diff options
Diffstat (limited to 'indra')
179 files changed, 3165 insertions, 1750 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 40a9752268..27c0c0b640 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -389,27 +389,6 @@ void LLCharacter::clearVisualParamWeights() } //----------------------------------------------------------------------------- -// BOOL visualParamWeightsAreDefault() -//----------------------------------------------------------------------------- -BOOL LLCharacter::visualParamWeightsAreDefault() -{ - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) - { - if (param->getWeight() != param->getDefaultWeight()) - return false; - } - } - - return true; -} - - - -//----------------------------------------------------------------------------- // getVisualParam() //----------------------------------------------------------------------------- LLVisualParam* LLCharacter::getVisualParam(const char *param_name) diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 27e2a51c62..cac73c01b9 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -212,12 +212,9 @@ public: F32 getVisualParamWeight(const char* param_name); F32 getVisualParamWeight(S32 index); - // set all morph weights to 0 + // set all morph weights to defaults void clearVisualParamWeights(); - // see if all the weights are default - BOOL visualParamWeightsAreDefault(); - // visual parameter accessors LLVisualParam* getFirstVisualParam() { @@ -231,6 +228,21 @@ public: return (mCurIterator++)->second; } + S32 getVisualParamCountInGroup(const EVisualParamGroup group) const + { + S32 rtn = 0; + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); + /**/ ) + { + if ((iter++)->second->getGroup() == group) + { + ++rtn; + } + } + return rtn; + } + LLVisualParam* getVisualParam(S32 id) const { visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id); diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 297322fe58..703fe2f9cc 100644 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -284,7 +284,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake) void LLVisualParam::setNextParam( LLVisualParam *next ) { llassert(!mNext); - + llassert(getWeight() == getDefaultWeight()); // need to establish mNext before we start changing values on this, else initial value won't get mirrored (we can fix that, but better to forbid this pattern) mNext = next; } diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp index e22b753923..212963f270 100644 --- a/indra/llrender/llrendersphere.cpp +++ b/indra/llrender/llrendersphere.cpp @@ -68,45 +68,6 @@ void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks) } -// lat = 0 is Z-axis -// lon = 0, lat = 90 at X-axis -void lat2xyz(LLVector3 * result, F32 lat, F32 lon) -{ - // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result - F32 r; - result->mV[VX] = (F32) (cos(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD)); - result->mV[VY] = (F32) (sin(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD)); - r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f); - if (r == 1.0f) - { - result->mV[VZ] = 0.0f; - } - else - { - result->mV[VZ] = (F32) pow(1 - r*r, 0.5f); - if (lat > 90.01) - { - result->mV[VZ] *= -1.0; - } - } -} - -void lat2xyz_rad(LLVector3 * result, F32 lat, F32 lon) -{ - // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result - F32 r; - result->mV[VX] = (F32) (cos(lon) * sin(lat)); - result->mV[VY] = (F32) (sin(lon) * sin(lat)); - r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f); - if (r == 1.0f) - result->mV[VZ] = 0.0f; - else - { - result->mV[VZ] = (F32) pow(1 - r*r, 0.5f); - if (lat > F_PI_BY_TWO) result->mV[VZ] *= -1.0; - } -} - // A couple thoughts on sphere drawing: // 1) You need more slices than stacks, but little less than 2:1 // 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother @@ -181,3 +142,50 @@ void LLRenderSphere::render() { glCallList(mDList[0]); } + +inline LLVector3 polar_to_cart(F32 latitude, F32 longitude) +{ + return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude), + sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude), + cos(F_TWO_PI * latitude)); +} + + +void LLRenderSphere::renderGGL() +{ + S32 const LATITUDE_SLICES = 20; + S32 const LONGITUDE_SLICES = 30; + + if (mSpherePoints.empty()) + { + mSpherePoints.resize(LATITUDE_SLICES + 1); + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++) + { + mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1); + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++) + { + F32 lat = (F32)lat_i / LATITUDE_SLICES; + F32 lon = (F32)lon_i / LONGITUDE_SLICES; + + mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon); + } + } + } + + gGL.begin(LLRender::TRIANGLES); + + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++) + { + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++) + { + gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV); + } + } + gGL.end(); +} diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h index 617ee3e12e..ebc71b6146 100644 --- a/indra/llrender/llrendersphere.h +++ b/indra/llrender/llrendersphere.h @@ -52,6 +52,10 @@ public: void cleanupGL(); void render(F32 pixel_area); // of a box of size 1.0 at that position void render(); // render at highest LOD + void renderGGL(); // render using LLRender + +private: + std::vector< std::vector<LLVector3> > mSpherePoints; }; extern LLRenderSphere gSphere; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index a8f72183fd..34f3049f2e 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -636,8 +636,8 @@ void LLButton::draw() if (mFlashing) { - // if we have icon for flashing, use it as image for button - if(flash && mImageFlash->getName() != "FlashIconAbsent") + // if button should flash and we have icon for flashing, use it as image for button + if(flash && mImageFlash) { // setting flash to false to avoid its further influence on glow flash = false; diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index b251c3d65d..9bd566d3c9 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -314,8 +314,7 @@ private: /* There are two ways an image can flash- by making changes in color according to flash_color attribute or by changing icon from current to the one specified in image_flash. Second way is used only if - the name of flash icon is different from "FlashIconAbsent" which is there by default. First way is used - otherwise. */ + flash icon name is set in attributes(by default it isn't). First way is used otherwise. */ LLPointer<LLUIImage> mImageFlash; LLUIColor mHighlightColor; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 6babaf936b..fad98e553f 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -330,6 +330,7 @@ void LLFloater::addDragHandle() addChild(mDragHandle); } layoutDragHandle(); + applyTitle(); } void LLFloater::layoutDragHandle() @@ -348,7 +349,6 @@ void LLFloater::layoutDragHandle() } mDragHandle->setRect(rect); updateTitleButtons(); - applyTitle(); } void LLFloater::addResizeCtrls() @@ -2519,7 +2519,7 @@ LLFloater *LLFloaterView::getBackmost() const void LLFloaterView::syncFloaterTabOrder() { - // look for a visible modal dialog, starting from first (should be only one) + // look for a visible modal dialog, starting from first LLModalDialog* modal_dialog = NULL; for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 94eade06ad..d4d161f2c9 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2949,7 +2949,6 @@ BOOL LLScrollListCtrl::operateOnAll(EOperation op) //virtual void LLScrollListCtrl::setFocus(BOOL b) { - mSearchString.clear(); // for tabbing into pristine scroll lists (Finder) if (!getFirstSelected()) { @@ -2994,6 +2993,9 @@ void LLScrollListCtrl::onFocusLost() { gFocusMgr.setMouseCapture(NULL); } + + mSearchString.clear(); + LLUICtrl::onFocusLost(); } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8fc6f16702..38b35020b5 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -401,11 +401,11 @@ void LLTextBase::drawSelectionBackground() ++rect_it) { LLRect selection_rect = *rect_it; - selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom); - gl_rect_2d(selection_rect, selection_color); - } + selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom); + gl_rect_2d(selection_rect, selection_color); } } +} void LLTextBase::drawCursor() { @@ -962,17 +962,18 @@ void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent) { if (width != getRect().getWidth() || height != getRect().getHeight()) { - //EXT-4288 - //to keep consistance scrolling behaviour - //when scrolling from top and from bottom... - bool is_scrolled_to_end = (mScroller!=NULL) && scrolledToEnd(); + bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; LLUICtrl::reshape( width, height, called_from_parent ); - if (is_scrolled_to_end) + if (mScroller && scrolled_to_bottom && mTrackEnd) { - deselect(); - endOfDoc(); + // keep bottom of text buffer visible + // do this here as well as in reflow to handle case + // where shrinking from top, which causes buffer to temporarily + // not be scrolled to the bottom, since the scroll index + // specified the _top_ of the visible document region + mScroller->goToBottom(); } // do this first after reshape, because other things depend on @@ -1116,6 +1117,34 @@ void LLTextBase::reflow() updateSegments(); + if (mReflowIndex == S32_MAX) + { + return; + } + + bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; + + LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos); + bool follow_selection = getLocalRect().overlaps(cursor_rect); // cursor is (potentially) visible + + // store in top-left relative coordinates to avoid issues with horizontal scrollbar appearing and disappearing + cursor_rect.mTop = mVisibleTextRect.mTop - cursor_rect.mTop; + cursor_rect.mBottom = mVisibleTextRect.mTop - cursor_rect.mBottom; + + S32 first_line = getFirstVisibleLine(); + + // if scroll anchor not on first line, update it to first character of first line + if (!mLineInfoList.empty() + && (mScrollIndex < mLineInfoList[first_line].mDocIndexStart + || mScrollIndex >= mLineInfoList[first_line].mDocIndexEnd)) + { + mScrollIndex = mLineInfoList[first_line].mDocIndexStart; + } + LLRect first_char_rect = getLocalRectFromDocIndex(mScrollIndex); + // store in top-left relative coordinates to avoid issues with horizontal scrollbar appearing and disappearing + first_char_rect.mTop = mVisibleTextRect.mTop - first_char_rect.mTop; + first_char_rect.mBottom = mVisibleTextRect.mTop - first_char_rect.mBottom; + S32 reflow_count = 0; while(mReflowIndex < S32_MAX) { @@ -1129,6 +1158,7 @@ void LLTextBase::reflow() lldebugs << "Breaking out of reflow due to possible infinite loop in " << getName() << llendl; break; } + S32 start_index = mReflowIndex; mReflowIndex = S32_MAX; @@ -1136,25 +1166,6 @@ void LLTextBase::reflow() // to force inlined widgets with follows set to shrink mDocumentView->reshape(mVisibleTextRect.getWidth(), mDocumentView->getRect().getHeight()); - bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; - - LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos); - bool follow_selection = mVisibleTextRect.overlaps(old_cursor_rect); // cursor is visible - old_cursor_rect.translate(-mVisibleTextRect.mLeft, -mVisibleTextRect.mBottom); - - S32 first_line = getFirstVisibleLine(); - - // if scroll anchor not on first line, update it to first character of first line - if (!mLineInfoList.empty() - && (mScrollIndex < mLineInfoList[first_line].mDocIndexStart - || mScrollIndex >= mLineInfoList[first_line].mDocIndexEnd)) - { - mScrollIndex = mLineInfoList[first_line].mDocIndexStart; - } - LLRect first_char_rect = getLocalRectFromDocIndex(mScrollIndex); - // subtract off effect of horizontal scrollbar from local position of first char - first_char_rect.translate(-mVisibleTextRect.mLeft, -mVisibleTextRect.mBottom); - S32 cur_top = 0; segment_set_t::iterator seg_iter = mSegments.begin(); @@ -1275,6 +1286,7 @@ void LLTextBase::reflow() segmentp->updateLayout(*this); } + } // apply scroll constraints after reflowing text if (!hasMouseCapture() && mScroller) @@ -1288,20 +1300,29 @@ void LLTextBase::reflow() { // keep cursor in same vertical position on screen when selecting text LLRect new_cursor_rect_doc = getDocRectFromDocIndex(mCursorPos); + LLRect old_cursor_rect = cursor_rect; + old_cursor_rect.mTop = mVisibleTextRect.mTop - cursor_rect.mTop; + old_cursor_rect.mBottom = mVisibleTextRect.mTop - cursor_rect.mBottom; + mScroller->scrollToShowRect(new_cursor_rect_doc, old_cursor_rect); } else { // keep first line of text visible LLRect new_first_char_rect = getDocRectFromDocIndex(mScrollIndex); - mScroller->scrollToShowRect(new_first_char_rect, first_char_rect); + + // pass in desired rect in the coordinate frame of the document viewport + LLRect old_first_char_rect = first_char_rect; + old_first_char_rect.mTop = mVisibleTextRect.mTop - first_char_rect.mTop; + old_first_char_rect.mBottom = mVisibleTextRect.mTop - first_char_rect.mBottom; + + mScroller->scrollToShowRect(new_first_char_rect, old_first_char_rect); } } // reset desired x cursor position updateCursorXPos(); } -} LLRect LLTextBase::getTextBoundingRect() { @@ -1576,7 +1597,7 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name) } } -void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params) +void LLTextBase::appendTextImpl(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params) { LLStyle::Params style_params(input_params); style_params.fillFrom(getDefaultStyleParams()); @@ -1609,8 +1630,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c part = (S32)LLTextParser::MIDDLE; } std::string subtext=text.substr(0,start); - appendAndHighlightText(subtext, prepend_newline, part, style_params); - prepend_newline = false; + appendAndHighlightTextImpl(subtext, part, style_params); } // output an optional icon before the Url @@ -1627,13 +1647,12 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c // Text will be replaced during rendering with the icon, // but string cannot be empty or the segment won't be // added (or drawn). - appendAndHighlightText(" ", prepend_newline, part, icon_params); - prepend_newline = false; + appendImageSegment(part, icon); } } - // output the styled Url - appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params); + // output the styled Url + appendAndHighlightTextImpl(match.getLabel(), part, link_params); // set the tooltip for the Url label if (! match.getTooltip().empty()) @@ -1645,8 +1664,6 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c segment->setToolTip(match.getTooltip()); } } - - prepend_newline = false; // move on to the rest of the text after the Url if (end < (S32)text.length()) @@ -1660,13 +1677,41 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c break; } } - if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; - if (end < (S32)text.length()) appendAndHighlightText(text, prepend_newline, part, style_params); + if (part != (S32)LLTextParser::WHOLE) + part=(S32)LLTextParser::END; + if (end < (S32)text.length()) + appendAndHighlightTextImpl(text, part, style_params); } else { - appendAndHighlightText(new_text, prepend_newline, part, style_params); + appendAndHighlightTextImpl(new_text, part, style_params); + } +} + +void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params) +{ + if (new_text.empty()) + return; + + if(prepend_newline) + appendLineBreakSegment(input_params); + std::string::size_type start = 0; + std::string::size_type pos = new_text.find("\n",start); + + while(pos!=-1) + { + if(pos!=start) + { + std::string str = std::string(new_text,start,pos-start); + appendTextImpl(str,input_params); + } + appendLineBreakSegment(input_params); + start = pos+1; + pos = new_text.find("\n",start); } + + std::string str = std::string(new_text,start,new_text.length()-start); + appendTextImpl(str,input_params); } void LLTextBase::needsReflow(S32 index) @@ -1675,10 +1720,28 @@ void LLTextBase::needsReflow(S32 index) mReflowIndex = llmin(mReflowIndex, index); } -void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params) +void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params) { - if (new_text.empty()) return; + segment_vec_t segments; + LLStyleConstSP sp(new LLStyle(style_params)); + segments.push_back(new LLLineBreakTextSegment(sp, getLength())); + + insertStringNoUndo(getLength(), utf8str_to_wstring("\n"), &segments); +} + +void LLTextBase::appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params) +{ + segment_vec_t segments; + LLStyleConstSP sp(new LLStyle(style_params)); + segments.push_back(new LLImageTextSegment(sp, getLength(),*this)); + + insertStringNoUndo(getLength(), utf8str_to_wstring(" "), &segments); +} + + +void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) +{ // Save old state S32 selection_start = mSelectionStart; S32 selection_end = mSelectionEnd; @@ -1691,13 +1754,11 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen setCursorPos(old_length); - LLTextParser* highlight = LLTextParser::getInstance(); - - if (mParseHighlights && highlight) + if (mParseHighlights) { LLStyle::Params highlight_params(style_params); - LLSD pieces = highlight->parsePartialLineHighlights(new_text, highlight_params.color(), (LLTextParser::EHighlightPosition)highlight_part); + LLSD pieces = LLTextParser::instance().parsePartialLineHighlights(new_text, highlight_params.color(), (LLTextParser::EHighlightPosition)highlight_part); for (S32 i = 0; i < pieces.size(); i++) { LLSD color_llsd = pieces[i]["color"]; @@ -1706,14 +1767,8 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen highlight_params.color = lcolor; LLWString wide_text; - if (prepend_newline && (i == 0 || pieces.size() <= 1 )) - { - wide_text = utf8str_to_wstring(std::string("\n") + pieces[i]["text"].asString()); - } - else - { wide_text = utf8str_to_wstring(pieces[i]["text"].asString()); - } + S32 cur_length = getLength(); LLStyleConstSP sp(new LLStyle(highlight_params)); LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); @@ -1725,17 +1780,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen else { LLWString wide_text; - - // Add carriage return if not first line - if (getLength() != 0 - && prepend_newline) - { - wide_text = utf8str_to_wstring(std::string("\n") + new_text); - } - else - { wide_text = utf8str_to_wstring(new_text); - } segment_vec_t segments; S32 segment_start = old_length; @@ -1763,11 +1808,32 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen { setCursorPos(cursor_pos); } +} - //if( !allow_undo ) - //{ - // blockUndo(); - //} +void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params) +{ + if (new_text.empty()) return; + + if(prepend_newline) + appendLineBreakSegment(style_params); + + std::string::size_type start = 0; + std::string::size_type pos = new_text.find("\n",start); + + while(pos!=-1) + { + if(pos!=start) + { + std::string str = std::string(new_text,start,pos-start); + appendAndHighlightTextImpl(str,highlight_part, style_params); + } + appendLineBreakSegment(style_params); + start = pos+1; + pos = new_text.find("\n",start); + } + + std::string str = std::string(new_text,start,new_text.length()-start); + appendAndHighlightTextImpl(str,highlight_part, style_params); } @@ -1876,14 +1942,19 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 text_width, text_height; bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); + if(newline) + { + pos = segment_line_start + segmentp->getOffset(local_x - start_x, line_seg_offset, segment_line_length, round); + break; + } + // if we've reached a line of text *below* the mouse cursor, doc index is first character on that line if (hit_past_end_of_line && local_y - mVisibleTextRect.mBottom + visible_region.mBottom > line_iter->mRect.mTop) { pos = segment_line_start; break; } - if (local_x < start_x + text_width // cursor to left of right edge of text - || newline) // or this line ends with a newline, set doc pos to newline char + if (local_x < start_x + text_width) // cursor to left of right edge of text { // Figure out which character we're nearest to. S32 offset; @@ -1907,13 +1978,13 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, pos = segment_line_start + offset; break; } - else if (hit_past_end_of_line && segmentp->getEnd() >= line_iter->mDocIndexEnd - 1) + else if (hit_past_end_of_line && segmentp->getEnd() > line_iter->mDocIndexEnd - 1) { + // segment wraps to next line, so just set doc pos to the end of the line // segment wraps to next line, so just set doc pos to start of next line (represented by mDocIndexEnd) pos = llmin(getLength(), line_iter->mDocIndexEnd); break; } - start_x += text_width; } @@ -1982,11 +2053,18 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const { + LLRect content_window_rect = mScroller ? mScroller->getContentWindowRect() : getLocalRect(); + if (mBorderVisible) + { + content_window_rect.stretch(-1); + } + LLRect local_rect; + if (mLineInfoList.empty()) { // return default height rect in upper left - local_rect = mVisibleTextRect; + local_rect = content_window_rect; local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight()); return local_rect; } @@ -1997,8 +2075,8 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const // compensate for scrolled, inset view of doc LLRect scrolled_view_rect = getVisibleDocumentRect(); local_rect = doc_rect; - local_rect.translate(mVisibleTextRect.mLeft - scrolled_view_rect.mLeft, - mVisibleTextRect.mBottom - scrolled_view_rect.mBottom); + local_rect.translate(content_window_rect.mLeft - scrolled_view_rect.mLeft, + content_window_rect.mBottom - scrolled_view_rect.mBottom); return local_rect; } @@ -2370,25 +2448,6 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec { if( end - start > 0 ) { - if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart)) - { - // ...for images, only render the image, not the underlying text, - // which is only a placeholder space - LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha; - LLUIImagePtr image = mStyle->getImage(); - S32 style_image_height = image->getHeight(); - S32 style_image_width = image->getWidth(); - // Text is drawn from the top of the draw_rect downward - S32 text_center = draw_rect.mTop - (mFontHeight / 2); - // Align image to center of text - S32 image_bottom = text_center - (style_image_height / 2); - image->draw(draw_rect.mLeft, image_bottom, - style_image_width, style_image_height, color); - - const S32 IMAGE_HPAD = 3; - return draw_rect.mLeft + style_image_width + IMAGE_HPAD; - } - return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect); } return draw_rect.mLeft; @@ -2401,11 +2460,6 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele const LLWString &text = mEditor.getWText(); - if ( text[seg_end-1] == '\n' ) - { - --seg_end; - } - F32 right_x = rect.mLeft; if (!mStyle->isVisible()) { @@ -2564,33 +2618,14 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt { height = 0; width = 0; - bool force_newline = false; if (num_chars > 0) { height = mFontHeight; const LLWString &text = mEditor.getWText(); // if last character is a newline, then return true, forcing line break - llwchar last_char = text[mStart + first_char + num_chars - 1]; - if (last_char == '\n') - { - force_newline = true; - // don't count newline in font width - width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars - 1); - } - else - { width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars); } - } - - LLUIImagePtr image = mStyle->getImage(); - if( image.notNull()) - { - width += image->getWidth(); - height = llmax(height, image->getHeight()); - } - - return force_newline; + return false; } S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const @@ -2613,15 +2648,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin num_pixels = llmax(0, num_pixels - image->getWidth()); } - // search for newline and if found, truncate there - S32 last_char = mStart + segment_offset; - for (; last_char != mEnd; ++last_char) - { - if (text[last_char] == '\n') - { - break; - } - } + S32 last_char = mEnd; // set max characters to length of segment, or to first newline max_chars = llmin(max_chars, last_char - (mStart + segment_offset)); @@ -2649,8 +2676,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin S32 last_char_in_run = mStart + segment_offset + num_chars; // check length first to avoid indexing off end of string if (last_char_in_run < mEnd - && (last_char_in_run >= mEditor.getLength() - || text[last_char_in_run] == '\n')) + && (last_char_in_run >= mEditor.getLength() )) { num_chars++; } @@ -2745,3 +2771,87 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor) { editor->addDocumentChild(mView); } + +LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1) +{ + mFontHeight = llceil(style->getFont()->getLineHeight()); +} +LLLineBreakTextSegment::~LLLineBreakTextSegment() +{ +} +bool LLLineBreakTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const +{ + width = 0; + height = mFontHeight; + + return true; +} +S32 LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +{ + return 1; +} +F32 LLLineBreakTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +{ + return draw_rect.mLeft; +} + +LLImageTextSegment::LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor) + :LLTextSegment(pos,pos+1) + ,mStyle( style ) + ,mEditor(editor) +{ +} + +LLImageTextSegment::~LLImageTextSegment() +{ +} + +static const S32 IMAGE_HPAD = 3; + +bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const +{ + width = 0; + height = llceil(mStyle->getFont()->getLineHeight());; + + LLUIImagePtr image = mStyle->getImage(); + if( image.notNull()) + { + width += image->getWidth() + IMAGE_HPAD; + height = llmax(height, image->getHeight() + IMAGE_HPAD ); + } + return false; +} + +S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +{ + LLUIImagePtr image = mStyle->getImage(); + S32 image_width = image->getWidth(); + if(num_pixels>image_width + IMAGE_HPAD) + { + return 1; + } + + return 0; +} +F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +{ + if ( (start >= 0) && (end <= mEnd - mStart)) + { + LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha; + LLUIImagePtr image = mStyle->getImage(); + S32 style_image_height = image->getHeight(); + S32 style_image_width = image->getWidth(); + // Text is drawn from the top of the draw_rect downward + + S32 text_center = draw_rect.mTop - (draw_rect.getHeight() / 2); + // Align image to center of draw rect + S32 image_bottom = text_center - (style_image_height / 2); + image->draw(draw_rect.mLeft, image_bottom, + style_image_width, style_image_height, color); + + const S32 IMAGE_HPAD = 3; + return draw_rect.mLeft + style_image_width + IMAGE_HPAD; + } + return 0.0; +} + diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index ddf604c195..7041b9a109 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -320,6 +320,13 @@ protected: // avatar names are looked up. void replaceUrl(const std::string &url, const std::string &label, const std::string& icon); + void appendLineBreakSegment(const LLStyle::Params& style_params); + void appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params); + + void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); + void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params); + + protected: // text segmentation and flow segment_set_t mSegments; @@ -511,5 +518,32 @@ private: bool mForceNewLine; }; +class LLLineBreakTextSegment : public LLTextSegment +{ +public: + + LLLineBreakTextSegment(LLStyleConstSP style,S32 pos); + ~LLLineBreakTextSegment(); + bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; + S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); + +private: + S32 mFontHeight; +}; + +class LLImageTextSegment : public LLTextSegment +{ +public: + LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor); + ~LLImageTextSegment(); + bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; + S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); + +private: + class LLTextBase& mEditor; + LLStyleConstSP mStyle; +}; #endif diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 4fd62045e8..c9474d66b7 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1083,6 +1083,28 @@ void LLTextEditor::addChar(llwchar wc) setCursorPos(mCursorPos + addChar( mCursorPos, wc )); } +void LLTextEditor::addLineBreakChar() +{ + if( !getEnabled() ) + { + return; + } + if( hasSelection() ) + { + deleteSelection(TRUE); + } + else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) + { + removeChar(mCursorPos); + } + + LLStyleConstSP sp(new LLStyle(LLStyle::Params())); + LLTextSegmentPtr segment = new LLLineBreakTextSegment(sp, mCursorPos); + + S32 pos = execute(new TextCmdAddChar(mCursorPos, FALSE, '\n', segment)); + + setCursorPos(mCursorPos + pos); +} BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) @@ -1404,7 +1426,27 @@ void LLTextEditor::pasteHelper(bool is_primary) } // Insert the new text into the existing text. - setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr())); + + //paste text with linebreaks. + std::basic_string<llwchar>::size_type start = 0; + std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start); + + while(pos!=-1) + { + if(pos!=start) + { + std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,pos-start); + setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr())); + } + addLineBreakChar(); + + start = pos+1; + pos = clean_string.find('\n',start); + } + + std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start); + setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr())); + deselect(); onKeyStroke(); @@ -2169,7 +2211,10 @@ void LLTextEditor::autoIndent() } // Insert that number of spaces on the new line - addChar( '\n' ); + + //appendLineBreakSegment(LLStyle::Params());//addChar( '\n' ); + addLineBreakChar(); + for( i = 0; i < space_count; i++ ) { addChar( ' ' ); diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 9b3ab9414c..7b68974fd8 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -240,6 +240,7 @@ protected: // Undoable operations void addChar(llwchar c); // at mCursorPos S32 addChar(S32 pos, llwchar wc); + void addLineBreakChar(); S32 overwriteChar(S32 pos, llwchar wc); void removeChar(); S32 removeChar(S32 pos); diff --git a/indra/llui/lltextparser.cpp b/indra/llui/lltextparser.cpp index 76a39e3094..2493afcb5d 100644 --- a/indra/llui/lltextparser.cpp +++ b/indra/llui/lltextparser.cpp @@ -43,29 +43,14 @@ #include "v4color.h" #include "lldir.h" -// Routines used for parsing text for TextParsers and html - -LLTextParser* LLTextParser::sInstance = NULL; - // // Member Functions // -LLTextParser::~LLTextParser() -{ - sInstance=NULL; -} +LLTextParser::LLTextParser() +: mLoaded(false) +{} -// static -LLTextParser* LLTextParser::getInstance() -{ - if (!sInstance) - { - sInstance = new LLTextParser(); - sInstance->loadFromDisk(); - } - return sInstance; -} // Moved triggerAlerts() to llfloaterchat.cpp to break llui/llaudio library dependency. @@ -105,6 +90,8 @@ S32 LLTextParser::findPattern(const std::string &text, LLSD highlight) LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLColor4 &color, EHighlightPosition part, S32 index) { + loadKeywords(); + //evil recursive string atomizer. LLSD ret_llsd, start_llsd, middle_llsd, end_llsd; @@ -195,6 +182,8 @@ LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLC bool LLTextParser::parseFullLineHighlights(const std::string &text, LLColor4 *color) { + loadKeywords(); + for (S32 i=0;i<mHighlights.size();i++) { if ((S32)mHighlights[i]["highlight"]==ALL || (S32)mHighlights[i]["condition"]==MATCHES) @@ -221,14 +210,14 @@ std::string LLTextParser::getFileName() return path; } -LLSD LLTextParser::loadFromDisk() +void LLTextParser::loadKeywords() { - std::string filename=getFileName(); - if (filename.empty()) - { - llwarns << "LLTextParser::loadFromDisk() no valid user directory." << llendl; + if (mLoaded) + {// keywords already loaded + return; } - else + std::string filename=getFileName(); + if (!filename.empty()) { llifstream file; file.open(filename.c_str()); @@ -237,9 +226,8 @@ LLSD LLTextParser::loadFromDisk() LLSDSerialize::fromXML(mHighlights, file); } file.close(); + mLoaded = true; } - - return mHighlights; } bool LLTextParser::saveToDisk(LLSD highlights) diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h index 072ac0f300..3005822f43 100644 --- a/indra/llui/lltextparser.h +++ b/indra/llui/lltextparser.h @@ -35,12 +35,13 @@ #define LL_LLTEXTPARSER_H #include "llsd.h" +#include "llsingleton.h" class LLUUID; class LLVector3d; class LLColor4; -class LLTextParser +class LLTextParser : public LLSingleton<LLTextParser> { public: typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType; @@ -48,22 +49,20 @@ public: typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition; typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction; - static LLTextParser* getInstance(); - LLTextParser(){}; - ~LLTextParser(); + LLTextParser(); - S32 findPattern(const std::string &text, LLSD highlight); LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0); bool parseFullLineHighlights(const std::string &text, LLColor4 *color); +private: + S32 findPattern(const std::string &text, LLSD highlight); std::string getFileName(); - LLSD loadFromDisk(); + void loadKeywords(); bool saveToDisk(LLSD highlights); public: LLSD mHighlights; -private: - static LLTextParser* sInstance; + bool mLoaded; }; #endif diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 5be3c6a45b..04423a81a3 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -95,6 +95,8 @@ public: /// Return the name of a SL location described by this Url, if any virtual std::string getLocation(const std::string &url) const { return ""; } + virtual LLUUID getID(const std::string &string) const { return LLUUID::null; } + protected: std::string getIDStringFromUrl(const std::string &url) const; std::string escapeUrl(const std::string &url) const; diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index 51fca6d7c0..73d880522b 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -48,8 +48,9 @@ LLUrlMatch::LLUrlMatch() : void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, - const std::string &icon, const LLStyle::Params& style, - const std::string &menu, const std::string &location) + const std::string &icon, const LLUIColor& color, + const std::string &menu, const std::string &location, + bool disabled_link) { mStart = start; mEnd = end; @@ -61,4 +62,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mStyle.link_href = url; mMenuName = menu; mLocation = location; + mID = id; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index 3b15a156a8..458a27d01f 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -86,9 +86,10 @@ public: /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, - const LLStyle::Params& style, const std::string &menu, - const std::string &location); + const LLUIColor& color, const std::string &menu, + const std::string &location, const LLUUID& id); + const LLUUID& getID() const { return mID; } private: U32 mStart; U32 mEnd; @@ -98,6 +99,7 @@ private: std::string mIcon; std::string mMenuName; std::string mLocation; + LLUUID mID; LLStyle::Params mStyle; }; diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index f119233f8f..5de249d994 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -43,7 +43,7 @@ void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, LLUrlRegistry::LLUrlRegistry() { - mUrlEntry.reserve(16); + mUrlEntry.reserve(20); // Urls are matched in the order that they were registered registerUrl(new LLUrlEntryNoLink()); @@ -192,7 +192,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getIcon(url), match_entry->getStyle(), match_entry->getMenuName(), - match_entry->getLocation(url)); + match_entry->getLocation(url), + match_entry->getID(url)); return true; } @@ -225,7 +226,8 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getIcon(), match.getStyle(), match.getMenuName(), - match.getLocation()); + match.getLocation(), + match.getID()); return true; } return false; diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index d6ef5132c8..e8e1ea118b 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -176,7 +176,7 @@ namespace tut LLUrlMatch match; ensure("empty()", match.empty()); - match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", ""); + match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", LLUUID::null); ensure("! empty()", ! match.empty()); } @@ -189,7 +189,7 @@ namespace tut LLUrlMatch match; ensure_equals("getStart() == 0", match.getStart(), 0); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getStart() == 10", match.getStart(), 10); } @@ -202,7 +202,7 @@ namespace tut LLUrlMatch match; ensure_equals("getEnd() == 0", match.getEnd(), 0); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getEnd() == 20", match.getEnd(), 20); } @@ -215,10 +215,10 @@ namespace tut LLUrlMatch match; ensure_equals("getUrl() == ''", match.getUrl(), ""); - match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getUrl() == '' (2)", match.getUrl(), ""); } @@ -231,10 +231,10 @@ namespace tut LLUrlMatch match; ensure_equals("getLabel() == ''", match.getLabel(), ""); - match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getLabel() == '' (2)", match.getLabel(), ""); } @@ -247,10 +247,10 @@ namespace tut LLUrlMatch match; ensure_equals("getTooltip() == ''", match.getTooltip(), ""); - match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getTooltip() == '' (2)", match.getTooltip(), ""); } @@ -263,10 +263,10 @@ namespace tut LLUrlMatch match; ensure_equals("getIcon() == ''", match.getIcon(), ""); - match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", LLUUID::null); ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure_equals("getIcon() == '' (2)", match.getIcon(), ""); } @@ -279,10 +279,10 @@ namespace tut LLUrlMatch match; ensure("getMenuName() empty", match.getMenuName().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", ""); + match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", LLUUID::null); ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure("getMenuName() empty (2)", match.getMenuName().empty()); } @@ -295,10 +295,10 @@ namespace tut LLUrlMatch match; ensure("getLocation() empty", match.getLocation().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris"); + match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", LLUUID::null); ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", LLUUID::null); ensure("getLocation() empty (2)", match.getLocation().empty()); } } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 41bb78e28d..cb5623a743 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -467,6 +467,7 @@ set(viewer_SOURCE_FILES llviewchildren.cpp llviewerassetstorage.cpp llviewerassettype.cpp + llviewerattachmenu.cpp llvieweraudio.cpp llviewercamera.cpp llviewerchat.cpp @@ -987,6 +988,7 @@ set(viewer_HEADER_FILES llviewchildren.h llviewerassetstorage.h llviewerassettype.h + llviewerattachmenu.h llvieweraudio.h llviewercamera.h llviewerchat.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1a11826265..4178b91fcf 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -632,7 +632,18 @@ <key>BlockAvatarAppearanceMessages</key> <map> <key>Comment</key> - <string>Ignore's appearance messages (for simulating Ruth)</string> + <string>Ignores appearance messages (for simulating Ruth)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>BlockSomeAvatarAppearanceVisualParams</key> + <map> + <key>Comment</key> + <string>Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -8327,17 +8338,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>ShowSidebarButton</key> - <map> - <key>Comment</key> - <string>Shows/hides Sidebar button in the bottom tray.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>ShowSnapshotButton</key> <map> <key>Comment</key> @@ -8880,17 +8880,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>SidebarWithButtonsVisibility</key> - <map> - <key>Comment</key> - <string>Sets visibility of sidebar with its tabs' buttons</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>SkinCurrent</key> <map> <key>Comment</key> @@ -11428,5 +11417,16 @@ <string>mini_map</string> </array> </map> + <key>LandmarksSortedByDate</key> + <map> + <key>Comment</key> + <string>Reflects landmarks panel sorting order.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> </map> </llsd> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 5efd997ab7..9564236ad2 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -4782,7 +4782,7 @@ group="1" name="Saddlebags" wearable="shape" - edit_grouo="driven" + edit_group="driven" value_min="-.5" value_max="3"> <param_morph> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index b4add267fe..de4d787d65 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -26,6 +26,7 @@ list all RenderAnisotropic 1 0 RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 +RenderAvatarMaxVisible 1 35 RenderAvatarVP 1 1 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 4fb529ab39..adda7cec4d 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -26,6 +26,7 @@ list all RenderAnisotropic 1 0 RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 +RenderAvatarMaxVisible 1 35 RenderAvatarVP 1 1 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index fbc589d3e7..82886d7e2c 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -26,6 +26,7 @@ list all RenderAnisotropic 1 0 RenderAvatarCloth 0 0 RenderAvatarLODFactor 1 1.0 +RenderAvatarMaxVisible 1 35 RenderAvatarVP 1 0 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 0fa77ff7c2..d2e55f88a0 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3585,7 +3585,13 @@ void LLAgent::sendAgentSetAppearance() llinfos << "TAT: Sending cached texture data" << llendl; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { - LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index); + BOOL generate_valid_hash = TRUE; + if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index)) + { + generate_valid_hash = FALSE; + } + + LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash); if (hash.notNull()) { diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e5796f8e63..e0104eddf0 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1445,6 +1445,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it queryWearableCache(); updateServer(); + gAgentAvatarp->dumpAvatarTEs("setWearableOutfit"); + lldebugs << "setWearableOutfit() end" << llendl; } @@ -1617,13 +1619,13 @@ void LLAgentWearables::queryWearableCache() gAgentQueryManager.mWearablesCacheQueryID++; } -LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index) +LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index, + BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache { LLUUID hash_id; bool hash_computed = false; LLMD5 hash; - - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(index); + const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); for (U8 i=0; i < baked_dict->mWearables.size(); i++) { @@ -1636,6 +1638,10 @@ LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextur { LLUUID asset_id = wearable->getAssetID(); hash.update((const unsigned char*)asset_id.mData, UUID_BYTES); + if (!generate_valid_hash) + { + hash.update((const unsigned char*)asset_id.mData, UUID_BYTES); + } hash_computed = true; } } @@ -1974,6 +1980,32 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos } // static +void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id) +{ + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); + LLAssetType::EType asset_type = wearable->getAssetType(); + LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; + LLPointer<LLInventoryCallback> cb = wear ? new WearOnAvatarCallback : NULL; + LLUUID folder_id; + + if (parent_id.notNull()) + { + folder_id = parent_id; + } + else + { + LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type); + folder_id = gInventory.findCategoryUUIDForType(folder_type); + } + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, wearable->getTransactionID(), wearable->getName(), + wearable->getDescription(), asset_type, inv_type, wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); +} + +// static void LLAgentWearables::editWearable(const LLUUID& item_id) { LLViewerInventoryItem* item; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 5d5c5ae371..679ecefa6f 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -144,6 +144,7 @@ protected: //-------------------------------------------------------------------- public: + static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null); static void editWearable(const LLUUID& item_id); bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); @@ -164,7 +165,8 @@ protected: public: // Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant) static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data); - LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index); + LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index, + BOOL generate_valid_hash = TRUE); protected: void sendAgentWearablesUpdate(); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index f27e632180..e6f363028a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -276,12 +276,14 @@ void LLWearableHoldingPattern::checkMissingWearables() if (found_by_type[type] > 0) continue; if ( - // Need to recover if at least one wearable of that type - // was requested but none was found (prevent missing - // pants) - (requested_by_type[type] > 0) || - // or if type is a body part and no wearables were found. - ((type == LLWearableType::WT_SHAPE) || (type == LLWearableType::WT_SKIN) || (type == LLWearableType::WT_HAIR) || (type == LLWearableType::WT_EYES))) + // If at least one wearable of certain types (pants/shirt/skirt) + // was requested but none was found, create a default asset as a replacement. + // In all other cases, don't do anything. + // For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud + // due to logic in LLVOAvatarSelf::getIsCloud(). + // For non-critical types (tatoo, socks, etc.) the wearable will just be missing. + (requested_by_type[type] > 0) && + ((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT))) { mTypesToRecover.insert(type); mTypesToLink.insert(type); @@ -704,6 +706,40 @@ void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit) wearInventoryCategory(cat, false, false); } +// Open outfit renaming dialog. +void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id) +{ + LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_id); + if (!cat) + { + return; + } + + LLSD args; + args["NAME"] = cat->getName(); + + LLSD payload; + payload["cat_id"] = outfit_id; + + LLNotificationsUtil::add("RenameOutfit", args, payload, boost::bind(onOutfitRename, _1, _2)); +} + +// User typed new outfit name. +// static +void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; // canceled + + std::string outfit_name = response["new_name"].asString(); + LLStringUtil::trim(outfit_name); + if (!outfit_name.empty()) + { + LLUUID cat_id = notification["payload"]["cat_id"].asUUID(); + rename_category(&gInventory, cat_id, outfit_name); + } +} + void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id) { LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); @@ -714,7 +750,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLFindWearables collector; + LLFindWorn collector; gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector); @@ -842,6 +878,41 @@ BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id) return ((required_wearables & folder_wearables) == required_wearables); } +bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id) +{ + // Disallow removing the base outfit. + if (outfit_cat_id == getBaseOutfitUUID()) + { + return false; + } + + // Check if the outfit folder itself is removable. + if (!get_is_category_removable(&gInventory, outfit_cat_id)) + { + return false; + } + + // Check if the folder contains worn items. + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWorn filter_worn; + gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_worn); + if (!items.empty()) + { + return false; + } + + // Check for the folder's non-removable descendants. + LLFindNonRemovableObjects filter_non_removable; + LLInventoryModel::item_array_t::const_iterator it; + gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable); + if (!cats.empty() || !items.empty()) + { + return false; + } + + return true; +} void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category) { diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index dbde055c3a..f1beef5857 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -59,6 +59,7 @@ public: void wearOutfitByName(const std::string& name); void changeOutfit(bool proceed, const LLUUID& category, bool append); void replaceCurrentOutfit(const LLUUID& new_outfit); + void renameOutfit(const LLUUID& outfit_id); void takeOffOutfit(const LLUUID& cat_id); void addCategoryToCurrentOutfit(const LLUUID& cat_id); @@ -69,6 +70,9 @@ public: // Return whether this folder contains minimal contents suitable for making a full outfit. BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id); + // Determine whether a given outfit can be removed. + bool getCanRemoveOutfit(const LLUUID& outfit_cat_id); + // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer<LLInventoryCallback> cb); @@ -180,6 +184,8 @@ private: void purgeCategory(const LLUUID& category, bool keep_outfit_links); void purgeBaseOutfitLink(const LLUUID& category); + static void onOutfitRename(const LLSD& notification, const LLSD& response); + std::set<LLUUID> mRegisteredAttachments; bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index eade4d639b..531aca7a82 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1813,7 +1813,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, } else { - llwarns << "Cannot load " << full_settings_path << " - No settings found." << llendl; + llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl; } } else @@ -3399,7 +3399,7 @@ void LLAppViewer::loadNameCache() } void LLAppViewer::saveNameCache() -{ + { // display names cache std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); @@ -3407,7 +3407,7 @@ void LLAppViewer::saveNameCache() if(name_cache_stream.is_open()) { LLAvatarNameCache::exportFile(name_cache_stream); - } +} if (!gCacheName) return; @@ -3607,7 +3607,7 @@ void LLAppViewer::idle() idleNameCache(); idleNetwork(); - + // Check for away from keyboard, kick idle agents. idle_afk_check(); diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index ade9c96758..2358aeb39d 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -78,7 +78,7 @@ public: boost::function<void(const LLUUID& uuid)> mCallback; }; -class LLBakedUploadData; +struct LLBakedUploadData; class LLSendTexLayerResponder : public LLAssetUploadResponder { public: diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index d1ed4922f4..f6d104cf0a 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -86,8 +86,8 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin payload["id"] = id; payload["name"] = name; - LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); - + LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); + // add friend to recent people list LLRecentPeople::instance().add(id); } @@ -467,37 +467,93 @@ namespace action_give_inventory return acceptable; } - /** - * Performs "give inventory" operations for provided avatars. - * - * Sends one requests to give all selected inventory items for each passed avatar. - * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other. - * - * @param avatar_names - avatar names request to be sent. - * @param avatar_uuids - avatar names request to be sent. - */ - static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names) + static void build_residents_string(const std::vector<std::string>& avatar_names, std::string& residents_string) + { + llassert(avatar_names.size() > 0); + + const std::string& separator = LLTrans::getString("words_separator"); + for (std::vector<std::string>::const_iterator it = avatar_names.begin(); ; ) + { + residents_string.append(*it); + if (++it == avatar_names.end()) + { + break; + } + residents_string.append(separator); + } + } + + static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string) { + llassert(inventory_selected_uuids.size() > 0); + + const std::string& separator = LLTrans::getString("words_separator"); + for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; ) + { + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); + if (NULL != inv_cat) + { + items_string = inv_cat->getName(); + break; + } + LLViewerInventoryItem* inv_item = gInventory.getItem(*it); + if (NULL != inv_item) + { + items_string.append(inv_item->getName()); + } + if(++it == inventory_selected_uuids.end()) + { + break; + } + items_string.append(separator); + } + } + + struct LLShareInfo : public LLSingleton<LLShareInfo> + { + std::vector<std::string> mAvatarNames; + uuid_vec_t mAvatarUuids; + }; + + static void give_inventory_cb(const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (NULL == active_panel) return; + if (NULL == active_panel) + { + return; + } const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); - if (inventory_selected_uuids.empty()) return; + if (inventory_selected_uuids.empty()) + { + return; + } - S32 count = avatar_uuids.size(); + S32 count = LLShareInfo::instance().mAvatarNames.size(); + bool shared = false; // iterate through avatars for(S32 i = 0; i < count; ++i) { - LLAvatarName av_name = avatar_names[i]; - const LLUUID& avatar_uuid = avatar_uuids[i]; + const std::string& avatar_name = LLShareInfo::instance().mAvatarNames[i]; + const LLUUID& avatar_uuid = LLShareInfo::instance().mAvatarUuids[i]; // Start up IM before give the item - const LLUUID session_id = gIMMgr->addSession(av_name.getCompleteName(), IM_NOTHING_SPECIAL, avatar_uuid); + const LLUUID session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, avatar_uuid); uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + const std::string& separator = LLTrans::getString("words_separator"); + std::string noncopy_item_names; + LLSD noncopy_items = LLSD::emptyArray(); // iterate through selected inventory objects for (; it != it_end; ++it) { @@ -505,13 +561,83 @@ namespace action_give_inventory if (inv_cat) { LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id); + shared = true; break; } LLViewerInventoryItem* inv_item = gInventory.getItem(*it); + if (!inv_item->getPermissions().allowCopyBy(gAgentID)) + { + if (!noncopy_item_names.empty()) + { + noncopy_item_names.append(separator); + } + noncopy_item_names.append(inv_item->getName()); + noncopy_items.append(*it); + } + else + { LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); + shared = true; + } } + if (noncopy_items.beginArray() != noncopy_items.endArray()) + { + LLSD substitutions; + substitutions["ITEMS"] = noncopy_item_names; + LLSD payload; + payload["agent_id"] = avatar_uuid; + payload["items"] = noncopy_items; + LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload, + &LLGiveInventory::handleCopyProtectedItem); + break; + } + } + if (shared) + { + LLFloaterReg::hideInstance("avatar_picker"); + LLNotificationsUtil::add("ItemsShared"); } } + + /** + * Performs "give inventory" operations for provided avatars. + * + * Sends one requests to give all selected inventory items for each passed avatar. + * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other. + * + * @param avatar_names - avatar names request to be sent. + * @param avatar_uuids - avatar names request to be sent. + */ + static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids) + { + llassert(avatar_names.size() == avatar_uuids.size()); + + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) + { + return; + } + + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) + { + return; + } + + std::string residents; + build_residents_string(avatar_names, residents); + + std::string items; + build_items_string(inventory_selected_uuids, items); + + LLSD substitutions; + substitutions["RESIDENTS"] = residents; + substitutions["ITEMS"] = items; + LLShareInfo::instance().mAvatarNames = avatar_names; + LLShareInfo::instance().mAvatarUuids = avatar_uuids; + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, LLSD(), &give_inventory_cb); + } } //static @@ -522,7 +648,6 @@ void LLAvatarActions::shareWithAvatars() LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE); picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); - LLNotificationsUtil::add("ShareNotification"); } // static diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index ff1e8a9657..7a3eddf7a6 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -1170,7 +1170,6 @@ void LLBottomTray::initResizeStateContainers() mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, getChild<LLPanel>("movement_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, getChild<LLPanel>("cam_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SNAPSHOT, getChild<LLPanel>("snapshot_panel"))); - mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SIDEBAR, getChild<LLPanel>("sidebar_btn_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_BUILD, getChild<LLPanel>("build_btn_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SEARCH, getChild<LLPanel>("search_btn_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_WORLD_MAP, getChild<LLPanel>("world_map_btn_panel"))); @@ -1181,7 +1180,6 @@ void LLBottomTray::initResizeStateContainers() mButtonsProcessOrder.push_back(RS_BUTTON_MOVEMENT); mButtonsProcessOrder.push_back(RS_BUTTON_CAMERA); mButtonsProcessOrder.push_back(RS_BUTTON_SNAPSHOT); - mButtonsProcessOrder.push_back(RS_BUTTON_SIDEBAR); mButtonsProcessOrder.push_back(RS_BUTTON_BUILD); mButtonsProcessOrder.push_back(RS_BUTTON_SEARCH); mButtonsProcessOrder.push_back(RS_BUTTON_WORLD_MAP); @@ -1217,7 +1215,6 @@ void LLBottomTray::initButtonsVisibility() setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton")); setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton")); setVisibleAndFitWidths(RS_BUTTON_SNAPSHOT, gSavedSettings.getBOOL("ShowSnapshotButton")); - setVisibleAndFitWidths(RS_BUTTON_SIDEBAR, gSavedSettings.getBOOL("ShowSidebarButton")); setVisibleAndFitWidths(RS_BUTTON_BUILD, gSavedSettings.getBOOL("ShowBuildButton")); setVisibleAndFitWidths(RS_BUTTON_SEARCH, gSavedSettings.getBOOL("ShowSearchButton")); setVisibleAndFitWidths(RS_BUTTON_WORLD_MAP, gSavedSettings.getBOOL("ShowWorldMapButton")); @@ -1230,7 +1227,6 @@ void LLBottomTray::setButtonsControlsAndListeners() gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2)); gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2)); gSavedSettings.getControl("ShowSnapshotButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SNAPSHOT, _2)); - gSavedSettings.getControl("ShowSidebarButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SIDEBAR, _2)); gSavedSettings.getControl("ShowBuildButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_BUILD, _2)); gSavedSettings.getControl("ShowSearchButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SEARCH, _2)); gSavedSettings.getControl("ShowWorldMapButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_WORLD_MAP, _2)); diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index c0887df39a..05fed53936 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -124,7 +124,6 @@ private: , RS_BUTTON_SEARCH = 0x0400 , RS_BUTTON_WORLD_MAP = 0x0800 , RS_BUTTON_MINI_MAP = 0x1000 - , RS_BUTTON_SIDEBAR = 0x2000 /* Once new button that can be hidden on resize is added don't forget to update related places: @@ -139,7 +138,6 @@ private: */ , RS_BUTTONS_CAN_BE_HIDDEN = RS_BUTTON_SNAPSHOT | RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES | RS_BUTTON_BUILD | RS_BUTTON_SEARCH | RS_BUTTON_WORLD_MAP | RS_BUTTON_MINI_MAP - | RS_BUTTON_SIDEBAR }EResizeState; /** diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index c52e8daf43..b7bccf46be 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -265,7 +265,7 @@ public: LLTextBox* user_name = getChild<LLTextBox>("user_name"); user_name->setReadOnlyColor(style_params.readonly_color()); user_name->setColor(style_params.color()); - + if (chat.mFromName.empty() || mSourceType == CHAT_SOURCE_SYSTEM || mAvatarID.isNull()) @@ -280,7 +280,7 @@ public: // ...from a normal user, lookup the name and fill in later. // *NOTE: Do not do this for chat history logs, otherwise the viewer // will flood the People API with lookup requests on startup - + // Start with blank so sample data from XUI XML doesn't // flash on the screen user_name->setValue( LLSD() ); @@ -894,12 +894,3 @@ void LLChatHistory::draw() LLUICtrl::draw(); } - -void LLChatHistory::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - bool is_scrolled_to_end = mEditor->scrolledToEnd(); - LLUICtrl::reshape( width, height, called_from_parent ); - // update scroll - if (is_scrolled_to_end) - mEditor->setCursorAndScrollToEnd(); -} diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index 950b32861b..fa1f2e04a4 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -122,7 +122,6 @@ class LLChatHistory : public LLUICtrl */ void appendMessage(const LLChat& chat, const LLSD &args = LLSD(), const LLStyle::Params& input_append_params = LLStyle::Params()); /*virtual*/ void clear(); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); private: std::string mLastFromName; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index ee366f4e3c..79ce2f8f6b 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -45,8 +45,7 @@ #include "llwearableitemslist.h" #include "llpaneloutfitedit.h" #include "llsidetray.h" - -static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor"); +#include "lltrans.h" static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearables"); @@ -54,6 +53,39 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD()); static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR; +////////////////////////////////////////////////////////////////////////// + +class CofContextMenu : public LLListContextMenu +{ +protected: + static void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id) + { + LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); + + // Hide the "Create new <WEARABLE_TYPE>" if it's irrelevant. + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item || !item->isWearableType()) + { + menu_item->setVisible(FALSE); + return; + } + + // Set proper label for the "Create new <WEARABLE_TYPE>" menu item. + LLStringUtil::format_map_t args; + LLWearableType::EType w_type = item->getWearableType(); + args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type); + std::string new_label = LLTrans::getString("CreateNewWearable", args); + menu_item->setLabel(new_label); + } + + static void createNew(const LLUUID& item_id) + { + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item || !item->isWearableType()) return; + + LLAgentWearables::createWearable(item->getWearableType(), true); + } +}; ////////////////////////////////////////////////////////////////////////// @@ -74,7 +106,7 @@ protected: ////////////////////////////////////////////////////////////////////////// -class CofClothingContextMenu : public LLListContextMenu +class CofClothingContextMenu : public CofContextMenu { protected: @@ -89,10 +121,17 @@ protected: registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false)); registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true)); registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); + registrar.add("Clothing.Create", boost::bind(createNew, selected_id)); enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2)); - return createFromFile("menu_cof_clothing.xml"); + LLContextMenu* menu = createFromFile("menu_cof_clothing.xml"); + llassert(menu); + if (menu) + { + updateCreateWearableLabel(menu, selected_id); + } + return menu; } bool onEnable(const LLSD& data) @@ -108,6 +147,10 @@ protected: { return gAgentWearables.canMoveWearable(selected_id, true); } + else if ("take_off" == param) + { + return get_is_item_worn(selected_id); + } else if ("edit" == param) { return gAgentWearables.isWearableModifiable(selected_id); @@ -122,12 +165,11 @@ protected: LLViewerInventoryItem* item = gInventory.getItem(item_id); return LLAppearanceMgr::instance().moveWearable(item, closer_to_body); } - }; ////////////////////////////////////////////////////////////////////////// -class CofBodyPartContextMenu : public LLListContextMenu +class CofBodyPartContextMenu : public CofContextMenu { protected: @@ -142,10 +184,17 @@ protected: LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit")); registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id)); registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); + registrar.add("BodyPart.Create", boost::bind(createNew, selected_id)); enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2)); - return createFromFile("menu_cof_body_part.xml"); + LLContextMenu* menu = createFromFile("menu_cof_body_part.xml"); + llassert(menu); + if (menu) + { + updateCreateWearableLabel(menu, selected_id); + } + return menu; } bool onEnable(const LLSD& data) diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 8f8bda2be8..f99f2662e6 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -45,53 +45,6 @@ class LLPanelClothingListItem; class LLPanelBodyPartsListItem; class LLPanelDeletableWearableListItem; -/** - * Adaptor between LLAccordionCtrlTab and LLFlatListView to facilitate communication between them - * (notify, notifyParent) regarding size changes of a list and selection changes across accordion tabs. - * Besides that it acts as a container for the LLFlatListView and a button bar on top of it. - */ -class LLCOFAccordionListAdaptor : public LLPanel -{ -public: - LLCOFAccordionListAdaptor() : LLPanel() {}; - ~LLCOFAccordionListAdaptor() {}; - - S32 notifyParent(const LLSD& info) - { - LLView* parent = getParent(); - if (!parent) return -1; - - if (!(info.has("action") && "size_changes" == info["action"].asString())) - { - return parent->notifyParent(info); - } - - LLRect rc; - childGetRect("button_bar", rc); - - LLSD params; - params["action"] = "size_changes"; - params["width"] = info["width"]; - params["height"] = info["height"].asInteger() + rc.getHeight(); - - return parent->notifyParent(params); - } - - - S32 notify(const LLSD& info) - { - for (child_list_const_iter_t iter = beginChild(); iter != endChild(); iter++) - { - if (dynamic_cast<LLFlatListView*>(*iter)) - { - return (*iter)->notify(info); - } - } - return LLPanel::notify(info); - }; -}; - - class LLCOFWearables : public LLPanel { public: diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index dc6847f236..d079da3b36 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -68,7 +68,7 @@ LLColorSwatchCtrl::Params::Params() LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p) : LLUICtrl(p), mValid( TRUE ), - mColor(p.color), + mColor(p.color()), mCanApplyImmediately(p.can_apply_immediately), mAlphaGradientImage(p.alpha_background_image), mOnCancelCallback(p.cancel_callback()), diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index 4bb7d837cb..09bb49cfbe 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -60,7 +60,7 @@ public: struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { - Optional<LLColor4> color; + Optional<LLUIColor> color; Optional<bool> can_apply_immediately; Optional<LLUIImage*> alpha_background_image; Optional<commit_callback_t> cancel_callback; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 546b60f286..2d0859650a 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -634,7 +634,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (!single_avatar && !avatarp->isFullyLoaded() ) { - if (pass==1 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) + if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); @@ -646,8 +646,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) gGL.translatef((F32)(pos.mV[VX]), (F32)(pos.mV[VY]), (F32)(pos.mV[VZ])); - gGL.scalef(0.15f, 0.15f, 0.3f); - gSphere.render(); + gGL.scalef(0.15f, 0.15f, 0.3f); + + gSphere.renderGGL(); + gGL.popMatrix(); gGL.setColorMask(true, false); } diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index 28e159421c..306fa5ad6d 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -54,6 +54,15 @@ LLFilteredWearableListManager::~LLFilteredWearableListManager() void LLFilteredWearableListManager::changed(U32 mask) { + if (LLInventoryObserver::CALLING_CARD == mask + || LLInventoryObserver::GESTURE == mask + || LLInventoryObserver::SORT == mask + ) + { + // skip non-related changes + return; + } + if(!gInventory.isInventoryUsable()) { return; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index b533e394ff..972565743e 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -442,15 +442,15 @@ void LLFloaterAvatarPicker::find() } else { - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("AvatarPickerRequest"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->addUUID("QueryID", mQueryID); // not used right now - msg->nextBlock("Data"); - msg->addString("Name", text); - gAgent.sendReliableMessage(); + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("AvatarPickerRequest"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->addUUID("QueryID", mQueryID); // not used right now + msg->nextBlock("Data"); + msg->addString("Name", text); + gAgent.sendReliableMessage(); } getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems(); @@ -520,7 +520,7 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask, session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id); } return LLToolDragAndDrop::handleGiveDragAndDrop(dest_agent_id, session_id, drop, - cargo_type, cargo_data, accept); + cargo_type, cargo_data, accept, getName()); } } } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 2b24189813..9ba8306a24 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -572,7 +572,7 @@ void LLPanelLandGeneral::refresh() if (regionp) { insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY); - mLandType->setText(regionp->getSimProductName()); + mLandType->setText(LLTrans::getString(regionp->getSimProductName())); } // estate owner/manager cannot edit other parts of the parcel @@ -828,9 +828,9 @@ void LLPanelLandGeneral::refreshNames() const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); if(auth_buyer_id.notNull()) { - std::string name; - name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString(); - mSaleInfoForSale2->setTextArg("[BUYER]", name); + std::string name; + name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString(); + mSaleInfoForSale2->setTextArg("[BUYER]", name); } else { @@ -2501,7 +2501,7 @@ void LLPanelLandAccess::refresh() if (maturity_pos != std::string::npos) { maturity_string.replace(maturity_pos, MATURITY.length(), std::string("")); - } + } maturity_checkbox->setLabel(maturity_string); } diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 725fc17136..c259659083 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -106,6 +106,8 @@ BOOL LLFloaterMap::postBuild() mPopupMenu->setItemEnabled ("Stop Tracking", false); } + stretchMiniMap(getRect().getWidth(),getRect().getHeight()); + updateMinorDirections(); // Get the drag handle all the way in back @@ -229,10 +231,8 @@ void LLFloaterMap::onFocusLost() LLPanel::onFocusLost(); } -void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) +void LLFloaterMap::stretchMiniMap(S32 width,S32 height) { - LLFloater::reshape(width, height, called_from_parent); - //fix for ext-7112 //by default ctrl can't overlap caption area if(mMap) @@ -242,6 +242,13 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) mMap->reshape( width, height, 1); mMap->setRect(map_rect); } +} + +void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLFloater::reshape(width, height, called_from_parent); + + stretchMiniMap(width, height); updateMinorDirections(); } diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index 9ff2f03180..3c063adfb8 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -61,6 +61,8 @@ private: void handleStopTracking (const LLSD& userdata); void setDirectionPos( LLTextBox* text_box, F32 rotation ); void updateMinorDirections(); + + void stretchMiniMap(S32 width,S32 height); LLMenuGL* mPopupMenu; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 920d09bd7f..6087312a68 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -985,7 +985,7 @@ void LLFloaterPreference::cleanupBadSetting() { if (gSavedPerAccountSettings.getString("BusyModeResponse2") == "|TOKEN COPY BusyModeResponse|") { - llwarns << "cleaning old BusyModeResponse" << llendl; + llinfos << "cleaning old BusyModeResponse" << llendl; //LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885) gSavedPerAccountSettings.setString("BusyModeResponse2", LLTrans::getString("BusyModeResponseDefault")); } diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index d83d895dd0..aebf1b4c26 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -192,15 +192,16 @@ bool LLGiveInventory::isInventoryGroupGiveAcceptable(const LLInventoryItem* item } // static -void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, +bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID& im_session_id/* = LLUUID::null*/) { + bool res = true; llinfos << "LLGiveInventory::giveInventory()" << llendl; if (!isInventoryGiveAcceptable(item)) { - return; + return false; } if (item->getPermissions().allowCopyBy(gAgentID)) { @@ -210,12 +211,19 @@ void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, else { // ask if the agent is sure. + LLSD substitutions; + substitutions["ITEMS"] = item->getName(); LLSD payload; payload["agent_id"] = to_agent; - payload["item_id"] = item->getUUID(); - LLNotificationsUtil::add("CannotCopyWarning", LLSD(), payload, + LLSD items = LLSD::emptyArray(); + items.append(item->getUUID()); + payload["items"] = items; + LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload, &LLGiveInventory::handleCopyProtectedItem); + res = false; } + + return res; } void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, @@ -318,23 +326,27 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLSD itmes = notification["payload"]["items"]; LLInventoryItem* item = NULL; switch(option) { case 0: // "Yes" - item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - if (item) + for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++) { - LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(), - item); - // delete it for now - it will be deleted on the server - // quickly enough. - gInventory.deleteObject(notification["payload"]["item_id"].asUUID()); - gInventory.notifyObservers(); - } - else - { - LLNotificationsUtil::add("CannotGiveItem"); + item = gInventory.getItem((*it).asUUID()); + if (item) + { + LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(), + item); + // delete it for now - it will be deleted on the server + // quickly enough. + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + } + else + { + LLNotificationsUtil::add("CannotGiveItem"); + } } break; diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h index e589a0cc69..86f0f2fe86 100644 --- a/indra/newview/llgiveinventory.h +++ b/indra/newview/llgiveinventory.h @@ -61,7 +61,7 @@ public: /** * Gives passed inventory item to specified avatar in specified session. */ - static void doGiveInventoryItem(const LLUUID& to_agent, + static bool doGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID& im_session_id = LLUUID::null); @@ -72,6 +72,9 @@ public: const LLInventoryCategory* item, const LLUUID &session_id = LLUUID::null); + // give inventory item functionality + static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); + private: // this class is not intended to be instantiated. LLGiveInventory(); @@ -82,8 +85,6 @@ private: static void logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id = LLUUID::null); - // give inventory item functionality - static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); static void commitGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID &im_session_id = LLUUID::null); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 245a1e2064..bad4697d17 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -165,38 +165,7 @@ time_t LLInvFVBridge::getCreationDate() const // Can be destroyed (or moved to trash) BOOL LLInvFVBridge::isItemRemovable() const { - const LLInventoryModel* model = getInventoryModel(); - if(!model) - { - return FALSE; - } - - // Can't delete an item that's in the library. - if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) - { - return FALSE; - } - - // Disable delete from COF folder; have users explicitly choose "detach/take off", - // unless the item is not worn but in the COF (i.e. is bugged). - if (LLAppearanceMgr::instance().getIsProtectedCOFItem(mUUID)) - { - if (get_is_item_worn(mUUID)) - { - return FALSE; - } - } - - const LLInventoryObject *obj = model->getItem(mUUID); - if (obj && obj->getIsLinkType()) - { - return TRUE; - } - if (get_is_item_worn(mUUID)) - { - return FALSE; - } - return TRUE; + return get_is_item_removable(getInventoryModel(), mUUID); } // Can be moved to another folder @@ -834,24 +803,7 @@ void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp) { - // Can't move a folder into a child of itself. - if (model->isObjectDescendentOf(new_parent_id, cat->getUUID())) - { - return; - } - - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - model->accountForUpdate(update); - - LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); - new_cat->setParent(new_parent_id); - new_cat->updateParentOnServer(restamp); - model->updateCategory(new_cat); - model->notifyObservers(); + change_category_parent(model, cat, new_parent_id, restamp); } LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, @@ -1539,26 +1491,7 @@ public: // Can be destroyed (or moved to trash) BOOL LLFolderBridge::isItemRemovable() const { - LLInventoryModel* model = getInventoryModel(); - if(!model) - { - return FALSE; - } - - if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) - { - return FALSE; - } - - if (!isAgentAvatarValid()) return FALSE; - - LLInventoryCategory* category = model->getCategory(mUUID); - if(!category) - { - return FALSE; - } - - if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) + if (!get_is_category_removable(getInventoryModel(), mUUID)) { return FALSE; } @@ -1574,6 +1507,7 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } } + return TRUE; } @@ -2334,10 +2268,20 @@ LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type, BOOL is else return LLUI::getUIImage("Inv_FolderClosed_Link"); } - if (preferred_type == LLFolderType::FT_OUTFIT) + + switch (preferred_type) + { + case LLFolderType::FT_OUTFIT: return LLUI::getUIImage("Inv_LookFolderClosed"); - else + case LLFolderType::FT_LOST_AND_FOUND: + return LLUI::getUIImage("Inv_LostClosed"); + case LLFolderType::FT_TRASH: + return LLUI::getUIImage("Inv_TrashClosed"); + case LLFolderType::FT_NONE: return LLUI::getUIImage("Inv_FolderClosed"); + default: + return LLUI::getUIImage("Inv_SysClosed"); + } } LLUIImagePtr LLFolderBridge::getOpenIcon() const @@ -2351,29 +2295,27 @@ LLUIImagePtr LLFolderBridge::getOpenIcon() const else return LLUI::getUIImage("Inv_FolderOpen_Link"); } - if (getPreferredType() == LLFolderType::FT_OUTFIT) + + switch (getPreferredType()) + { + case LLFolderType::FT_OUTFIT: return LLUI::getUIImage("Inv_LookFolderOpen"); - else + case LLFolderType::FT_LOST_AND_FOUND: + return LLUI::getUIImage("Inv_LostOpen"); + case LLFolderType::FT_TRASH: + return LLUI::getUIImage("Inv_TrashOpen"); + case LLFolderType::FT_NONE: return LLUI::getUIImage("Inv_FolderOpen"); + default: + return LLUI::getUIImage("Inv_SysOpen"); + } + } BOOL LLFolderBridge::renameItem(const std::string& new_name) { - if(!isItemRenameable()) - return FALSE; - LLInventoryModel* model = getInventoryModel(); - if(!model) - return FALSE; - LLViewerInventoryCategory* cat = getCategory(); - if(cat && (cat->getName() != new_name)) - { - LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); - new_cat->rename(new_name); - new_cat->updateServer(FALSE); - model->updateCategory(new_cat); + rename_category(getInventoryModel(), mUUID, new_name); - model->notifyObservers(); - } // return FALSE because we either notified observers (& therefore // rebuilt) or we didn't update. return FALSE; @@ -2427,36 +2369,7 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re { // move it to the trash LLPreview::hide(mUUID); - LLInventoryModel* model = getInventoryModel(); - if(!model) return FALSE; - - const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - - // Look for any gestures and deactivate them - LLInventoryModel::cat_array_t descendent_categories; - LLInventoryModel::item_array_t descendent_items; - gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE ); - - for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); - iter != descendent_items.end(); - ++iter) - { - const LLViewerInventoryItem* item = (*iter); - const LLUUID& item_id = item->getUUID(); - if (item->getType() == LLAssetType::AT_GESTURE - && LLGestureMgr::instance().isGestureActive(item_id)) - { - LLGestureMgr::instance().deactivateGesture(item_id); - } - } - - // go ahead and do the normal remove if no 'last calling - // cards' are being removed. - LLViewerInventoryCategory* cat = getCategory(); - if(cat) - { - LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE); - } + remove_category(getInventoryModel(), mUUID); return TRUE; } return FALSE; @@ -2652,22 +2565,6 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv return ((item_array.count() > 0) ? TRUE : FALSE ); } -class LLFindWorn : public LLInventoryCollectFunctor -{ -public: - LLFindWorn() {} - virtual ~LLFindWorn() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item) - { - if (item && get_is_item_worn(item->getUUID())) - { - return TRUE; - } - return FALSE; - } -}; - BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const { LLInventoryModel::cat_array_t cat_array; @@ -2986,22 +2883,7 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::ETyp { if(!bridge) return; LLUUID parent_id = bridge->getUUID(); - createWearable(parent_id, type); -} - -// Separate function so can be called by global menu as well as right-click -// menu. -// static -void LLFolderBridge::createWearable(const LLUUID &parent_id, LLWearableType::EType type) -{ - LLWearable* wearable = LLWearableList::instance().createNewWearable(type); - LLAssetType::EType asset_type = wearable->getAssetType(); - LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - parent_id, wearable->getTransactionID(), wearable->getName(), - wearable->getDescription(), asset_type, inv_type, wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - LLPointer<LLInventoryCallback>(NULL)); + LLAgentWearables::createWearable(type, false, parent_id); } void LLFolderBridge::modifyOutfit(BOOL append) @@ -4885,13 +4767,7 @@ void LLWearableBridge::onEditOnAvatar(void* user_data) void LLWearableBridge::editOnAvatar() { - LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID); - if( wearable ) - { - LLPanel * panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance"); - - LLSidepanelAppearance::editWearable(wearable, panel); - } + LLAgentWearables::editWearable(mUUID); } // static diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index c5efefac7e..59c1f3d6fb 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -270,7 +270,6 @@ public: virtual BOOL copyToClipboard() const; static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type); - static void createWearable(const LLUUID &parent_folder_id, LLWearableType::EType type); LLViewerInventoryCategory* getCategory() const; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 0cc4b0e389..817da34c61 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -130,6 +130,90 @@ void change_item_parent(LLInventoryModel* model, } } +void change_category_parent(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp) +{ + if (!model || !cat) + { + return; + } + + // Can't move a folder into a child of itself. + if (model->isObjectDescendentOf(new_parent_id, cat->getUUID())) + { + return; + } + + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + model->accountForUpdate(update); + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->setParent(new_parent_id); + new_cat->updateParentOnServer(restamp); + model->updateCategory(new_cat); + model->notifyObservers(); +} + +void remove_category(LLInventoryModel* model, const LLUUID& cat_id) +{ + if (!model || !get_is_category_removable(model, cat_id)) + { + return; + } + + // Look for any gestures and deactivate them + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); + + for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); + iter != descendent_items.end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + const LLUUID& item_id = item->getUUID(); + if (item->getType() == LLAssetType::AT_GESTURE + && LLGestureMgr::instance().isGestureActive(item_id)) + { + LLGestureMgr::instance().deactivateGesture(item_id); + } + } + + // go ahead and do the normal remove if no 'last calling + // cards' are being removed. + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (cat) + { + const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); + change_category_parent(model, cat, trash_id, TRUE); + } +} + +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) +{ + LLViewerInventoryCategory* cat; + + if (!model || + !get_is_category_renameable(model, cat_id) || + (cat = model->getCategory(cat_id)) == NULL || + cat->getName() == new_name) + { + return; + } + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->rename(new_name); + new_cat->updateServer(FALSE); + model->updateCategory(new_cat); + + model->notifyObservers(); +} BOOL get_is_item_worn(const LLUUID& id) { @@ -160,6 +244,83 @@ BOOL get_is_item_worn(const LLUUID& id) return FALSE; } +BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) +{ + if (!model) + { + return FALSE; + } + + // Can't delete an item that's in the library. + if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + return FALSE; + } + + // Disable delete from COF folder; have users explicitly choose "detach/take off", + // unless the item is not worn but in the COF (i.e. is bugged). + if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id)) + { + if (get_is_item_worn(id)) + { + return FALSE; + } + } + + const LLInventoryObject *obj = model->getItem(id); + if (obj && obj->getIsLinkType()) + { + return TRUE; + } + if (get_is_item_worn(id)) + { + return FALSE; + } + return TRUE; +} + +BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id) +{ + // This function doesn't check the folder's children. + + if (!model) + { + return FALSE; + } + + if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + return FALSE; + } + + if (!isAgentAvatarValid()) return FALSE; + + LLInventoryCategory* category = model->getCategory(id); + if (!category) + { + return FALSE; + } + + if (LLFolderType::lookupIsProtectedType(category->getPreferredType())) + { + return FALSE; + } + + return TRUE; +} + +BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) +{ + LLViewerInventoryCategory* cat = model->getCategory(id); + + if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && + cat->getOwnerID() == gAgent.getID()) + { + return TRUE; + } + return FALSE; +} + void show_item_profile(const LLUUID& item_uuid) { LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid); @@ -376,6 +537,26 @@ void LLFindWearablesOfType::setType(LLWearableType::EType type) mWearableType = type; } +bool LLFindWorn::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && get_is_item_worn(item->getUUID()); +} + +bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + if (item) + { + return !get_is_item_removable(&gInventory, item->getUUID()); + } + if (cat) + { + return !get_is_category_removable(&gInventory, cat->getUUID()); + } + + llwarns << "Not a category and not an item?" << llendl; + return false; +} + ///---------------------------------------------------------------------------- /// LLAssetIDMatches ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index bb365573d7..33b52cfd5e 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -46,6 +46,12 @@ // Is this item or its baseitem is worn, attached, etc... BOOL get_is_item_worn(const LLUUID& id); +BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id); + +BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id); + +BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id); + void show_item_profile(const LLUUID& item_uuid); void show_item_original(const LLUUID& item_uuid); @@ -55,6 +61,15 @@ void change_item_parent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp); +void change_category_parent(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp); + +void remove_category(LLInventoryModel* model, const LLUUID& cat_id); + +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); + // Generates a string containing the path to the item specified by item_id. void append_path(const LLUUID& id, std::string& path); @@ -309,6 +324,22 @@ private: LLWearableType::EType mWearableType; }; +// Find worn items. +class LLFindWorn : public LLInventoryCollectFunctor +{ +public: + LLFindWorn() {} + virtual ~LLFindWorn() {} + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; + +// Collect non-removable folders and items. +class LLFindNonRemovableObjects : public LLInventoryCollectFunctor +{ +public: + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; + /** Inventory Collector Functions ** ** *******************************************************************************/ diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 0ff6ab2644..b4f0947b2c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -112,6 +112,8 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive { if (!mAllFoldersFetched) { + LL_DEBUGS("InventoryFetch") << "Start fetching category: " << cat_id << ", recursive: " << recursive << LL_ENDL; + mBackgroundFetchActive = TRUE; if (cat_id.isNull()) { diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 8557548887..d2b402fe14 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -68,7 +68,7 @@ // you're fetching an item and a notification gets triggered because // you renamed some other item). This counter is to specify how many // notification to wait for before giving up. -static const U32 MAX_NUM_NOTIFICATIONS_TO_PROCESS = 20; +static const U32 MAX_NUM_NOTIFICATIONS_TO_PROCESS = 127; LLInventoryObserver::LLInventoryObserver() { diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 4766c1c227..bb3f34dde2 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -49,6 +49,7 @@ #include "llsidepanelinventory.h" #include "llsidetray.h" #include "llscrollcontainer.h" +#include "llviewerattachmenu.h" #include "llviewerfoldertype.h" #include "llvoavatarself.h" @@ -877,48 +878,19 @@ bool LLInventoryPanel::beginIMSession() bool LLInventoryPanel::attachObject(const LLSD& userdata) { + // Copy selected item UUIDs to a vector. std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); - - std::string joint_name = userdata.asString(); - LLViewerJointAttachment* attachmentp = NULL; - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getName() == joint_name) - { - attachmentp = attachment; - break; - } - } - if (attachmentp == NULL) - { - return true; - } - + uuid_vec_t items; for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) { - const LLUUID &id = *set_iter; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id); - if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) - { - rez_attachment(item, attachmentp); - } - else if(item && item->isFinished()) - { - // must be in library. copy it to our inventory and put it on. - LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); - copy_inventory_item(gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } + items.push_back(*set_iter); } + + // Attach selected items. + LLViewerAttachMenu::attachObjects(items, userdata.asString()); + gFocusMgr.setKeyboardFocus(NULL); return true; diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 251c60b5bf..e5548007bd 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -713,6 +713,7 @@ void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button) void LLNavigationBar::handleLoginComplete() { + LLTeleportHistory::getInstance()->handleLoginComplete(); mCmbLocation->handleLoginComplete(); } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 8f189a1e9f..77db280487 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -43,12 +43,16 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "lllistcontextmenu.h" +#include "llnotificationsutil.h" +#include "llsidetray.h" #include "lltransutil.h" #include "llviewermenu.h" #include "llvoavatar.h" #include "llvoavatarself.h" #include "llwearableitemslist.h" +static bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y); + ////////////////////////////////////////////////////////////////////////// class OutfitContextMenu : public LLListContextMenu @@ -66,12 +70,63 @@ protected: boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); registrar.add("Outfit.TakeOff", boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); - // *TODO: implement this - // registrar.add("Outfit.Rename", boost::bind()); - // registrar.add("Outfit.Delete", boost::bind()); + registrar.add("Outfit.Edit", boost::bind(editOutfit)); + registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); + registrar.add("Outfit.Delete", boost::bind(deleteOutfit, selected_id)); + + enable_registrar.add("Outfit.OnEnable", boost::bind(&OutfitContextMenu::onEnable, this, _2)); return createFromFile("menu_outfit_tab.xml"); } + + bool onEnable(const LLSD& data) + { + std::string param = data.asString(); + LLUUID outfit_cat_id = mUUIDs.back(); + bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id; + + if ("wear_replace" == param) + { + return !is_worn; + } + else if ("wear_add" == param) + { + return !is_worn; + } + else if ("take_off" == param) + { + return is_worn; + } + else if ("edit" == param) + { + return is_worn; + } + else if ("rename" == param) + { + return get_is_category_renameable(&gInventory, outfit_cat_id); + } + else if ("delete" == param) + { + return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); + } + + return true; + } + + static void editOutfit() + { + LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit")); + } + + static void renameOutfit(const LLUUID& outfit_cat_id) + { + LLAppearanceMgr::instance().renameOutfit(outfit_cat_id); + } + + static void deleteOutfit(const LLUUID& outfit_cat_id) + { + remove_category(&gInventory, outfit_cat_id); + } }; ////////////////////////////////////////////////////////////////////////// @@ -82,11 +137,9 @@ LLOutfitsList::LLOutfitsList() : LLPanel() , mAccordion(NULL) , mListCommands(NULL) + , mIsInitialized(false) { mCategoriesObserver = new LLInventoryCategoriesObserver(); - gInventory.addObserver(mCategoriesObserver); - - gInventory.addObserver(this); mOutfitMenu = new OutfitContextMenu(); } @@ -100,11 +153,6 @@ LLOutfitsList::~LLOutfitsList() gInventory.removeObserver(mCategoriesObserver); delete mCategoriesObserver; } - - if (gInventory.containsObserver(this)) - { - gInventory.removeObserver(this); - } } BOOL LLOutfitsList::postBuild() @@ -115,32 +163,36 @@ BOOL LLOutfitsList::postBuild() } //virtual -void LLOutfitsList::changed(U32 mask) +void LLOutfitsList::onOpen(const LLSD& /*info*/) { - if (!gInventory.isInventoryUsable()) - return; + if (!mIsInitialized) + { + // *TODO: I'm not sure is this check necessary but it never match while developing. + if (!gInventory.isInventoryUsable()) + return; - const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); - LLViewerInventoryCategory* category = gInventory.getCategory(outfits); - if (!category) - return; + const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); - // Start observing changes in "My Outfits" category. - mCategoriesObserver->addCategory(outfits, + // *TODO: I'm not sure is this check necessary but it never match while developing. + LLViewerInventoryCategory* category = gInventory.getCategory(outfits); + if (!category) + return; + + gInventory.addObserver(mCategoriesObserver); + + // Start observing changes in "My Outfits" category. + mCategoriesObserver->addCategory(outfits, boost::bind(&LLOutfitsList::refreshList, this, outfits)); - // Fetch "My Outfits" contents and refresh the list to display - // initially fetched items. If not all items are fetched now - // the observer will refresh the list as soon as the new items - // arrive. - category->fetch(); - refreshList(outfits); - - // This observer is used to start the initial outfits fetch - // when inventory becomes usable. It is no longer needed because - // "My Outfits" category is now observed by - // LLInventoryCategoriesObserver. - gInventory.removeObserver(this); + // Fetch "My Outfits" contents and refresh the list to display + // initially fetched items. If not all items are fetched now + // the observer will refresh the list as soon as the new items + // arrive. + category->fetch(); + refreshList(outfits); + + mIsInitialized = true; + } } void LLOutfitsList::refreshList(const LLUUID& category_id) @@ -176,8 +228,6 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); - tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this, - _1, _2, _3, cat_id)); tab->setName(name); tab->setTitle(name); @@ -198,6 +248,12 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) // Map the new tab with outfit category UUID. mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); + tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this, + _1, _2, _3, cat_id)); + + tab->setDoubleClickCallback(boost::bind(&LLOutfitsList::onAccordionTabDoubleClick, this, + _1, _2, _3, cat_id)); + // Setting tab focus callback to monitor currently selected outfit. tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id)); @@ -301,6 +357,10 @@ void LLOutfitsList::performAction(std::string action) { LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE ); } + else if ("rename_outfit" == action) + { + LLAppearanceMgr::instance().renameOutfit(mSelectedOutfitUUID); + } } void LLOutfitsList::setFilterSubString(const std::string& string) @@ -426,6 +486,10 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl) // hide tab if its title doesn't pass filter // and it has no visible items tab->setVisible(list->size() != 0); + + // remove title highlighting because it might + // have been previously highlighted by less restrictive filter + tab->setTitle(tab->getTitle()); } else { @@ -478,6 +542,10 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) // hide tab if its title doesn't pass filter // and it has no visible items tab->setVisible(list->size() != 0); + + // remove title highlighting because it might + // have been previously highlighted by less restrictive filter + tab->setTitle(tab->getTitle()); } else { @@ -510,22 +578,30 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) { LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); - if(mOutfitMenu && tab && tab->getHeaderVisible() && cat_id.notNull()) + if(mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull()) { - S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight(); - if(y >= header_bottom) + // Focus tab header to trigger tab selection change. + LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); + if (header) { - // Focus tab header to trigger tab selection change. - LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); - if (header) - { - header->setFocus(TRUE); - } - - uuid_vec_t selected_uuids; - selected_uuids.push_back(cat_id); - mOutfitMenu->show(ctrl, selected_uuids, x, y); + header->setFocus(TRUE); } + + uuid_vec_t selected_uuids; + selected_uuids.push_back(cat_id); + mOutfitMenu->show(ctrl, selected_uuids, x, y); + } +} + +void LLOutfitsList::onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) +{ + LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); + if(is_tab_header_clicked(tab, y) && cat_id.notNull()) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (!cat) return; + + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE ); } } @@ -551,4 +627,13 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y); } + +bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y) +{ + if(!tab || !tab->getHeaderVisible()) return false; + + S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight(); + return y >= header_bottom; +} + // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 1da7360c2e..44f6ec908b 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -49,12 +49,10 @@ class LLListContextMenu; * A list of agents's outfits from "My Outfits" inventory category * which displays each outfit in an accordion tab with a flat list * of items inside it. - * Uses LLInventoryCategoriesObserver to monitor changes to "My Outfits" - * inventory category and refresh the outfits listed in it. - * This class is derived from LLInventoryObserver to know when inventory - * becomes usable and it is safe to request data from inventory model. + * + * Starts fetching nevessary inventory content on first openning. */ -class LLOutfitsList : public LLPanel, public LLInventoryObserver +class LLOutfitsList : public LLPanel { public: LLOutfitsList(); @@ -62,16 +60,16 @@ public: /*virtual*/ BOOL postBuild(); - /*virtual*/ void changed(U32 mask); + /*virtual*/ void onOpen(const LLSD& info); void refreshList(const LLUUID& category_id); - void onSelectionChange(LLUICtrl* ctrl); - void performAction(std::string action); void setFilterSubString(const std::string& string); + const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } + private: /** * Reads xml with accordion tab and Flat list from xml file. @@ -107,9 +105,13 @@ private: void applyFilter(const std::string& new_filter_substring); void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); - + void onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + void onSelectionChange(LLUICtrl* ctrl); + + static void onOutfitRename(const LLSD& notification, const LLSD& response); + LLInventoryCategoriesObserver* mCategoriesObserver; LLAccordionCtrl* mAccordion; @@ -128,6 +130,8 @@ private: outfits_map_t mOutfitsMap; LLListContextMenu* mOutfitMenu; + + bool mIsInitialized; }; #endif //LL_LLOUTFITSLIST_H diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 4bf4f9eac1..7fb46fc84f 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -221,8 +221,6 @@ BOOL LLLandmarksPanel::postBuild() // mast be called before any other initXXX methods to init Gear menu initListCommandsHandlers(); - U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER); - mSortByDate = sort_order & LLInventoryFilter::SO_DATE; initFavoritesInventoryPanel(); initLandmarksInventoryPanel(); initMyInventoryPanel(); @@ -607,7 +605,8 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - updateSortOrder(inventory_list, mSortByDate); + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + updateSortOrder(inventory_list, sorting_order); LLPlacesFolderView* root_folder = dynamic_cast<LLPlacesFolderView*>(inventory_list->getRootFolder()); if (root_folder) @@ -875,10 +874,12 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) } else if ("sort_by_date" == command_name) { - mSortByDate = !mSortByDate; - updateSortOrder(mLandmarksInventoryPanel, mSortByDate); - updateSortOrder(mMyInventoryPanel, mSortByDate); - updateSortOrder(mLibraryInventoryPanel, mSortByDate); + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + sorting_order=!sorting_order; + gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order); + updateSortOrder(mLandmarksInventoryPanel, sorting_order); + updateSortOrder(mMyInventoryPanel, sorting_order); + updateSortOrder(mLibraryInventoryPanel, sorting_order); } else { @@ -895,7 +896,8 @@ bool LLLandmarksPanel::isActionChecked(const LLSD& userdata) const if ( "sort_by_date" == command_name) { - return mSortByDate; + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + return sorting_order; } return false; diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 8f8d9c2708..0e70c72f11 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -167,7 +167,6 @@ private: LLInventoryObserver* mInventoryObserver; LLPanel* mListCommands; - bool mSortByDate; typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t; accordion_tabs_t mAccordionTabs; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index a4b3d22486..aa8dd4ef45 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -214,7 +214,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this); // change z sort of clickable text to be behind buttons - sendChildToBack(getChildView("channel_text")); + //sendChildToBack(getChildView("channel_text")); sendChildToBack(getChildView("forgot_password_text")); LLLineEditor* edit = getChild<LLLineEditor>("password_edit"); @@ -240,10 +240,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, std::string version = llformat("%s (%d)", LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); - LLTextBox* channel_text = getChild<LLTextBox>("channel_text"); - channel_text->setTextArg("[CHANNEL]", channel); // though not displayed - channel_text->setTextArg("[VERSION]", version); - channel_text->setClickedCallback(onClickVersion, this); + //LLTextBox* channel_text = getChild<LLTextBox>("channel_text"); + //channel_text->setTextArg("[CHANNEL]", channel); // though not displayed + //channel_text->setTextArg("[VERSION]", version); + //channel_text->setClickedCallback(onClickVersion, this); LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text"); forgot_password_text->setClickedCallback(onClickForgotPassword, NULL); @@ -612,7 +612,7 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, if (separator_index != username.npos) { last = username.substr(separator_index+1, username.npos); - LLStringUtil::trim(last); + LLStringUtil::trim(last); } else { diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 78de384cdc..4982e98f8e 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -79,6 +79,70 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK; static const std::string REVERT_BTN("revert_btn"); +class LLPanelOutfitEditGearMenu +{ +public: + static LLMenuGL* create() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("Wearable.Create", boost::bind(onCreate, _2)); + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( + "menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(menu); + if (menu) + { + populateCreateWearableSubmenus(menu); + menu->buildDrawLabels(); + } + + return menu; + } + +private: + static void onCreate(const LLSD& param) + { + LLWearableType::EType type = LLWearableType::typeNameToType(param.asString()); + if (type == LLWearableType::WT_NONE) + { + llwarns << "Invalid wearable type" << llendl; + return; + } + + LLAgentWearables::createWearable(type, true); + } + + // Populate the menu with items like "New Skin", "New Pants", etc. + static void populateCreateWearableSubmenus(LLMenuGL* menu) + { + LLView* menu_clothes = gMenuHolder->findChildView("COF.Gear.New_Clothes", FALSE); + LLView* menu_bp = gMenuHolder->findChildView("COF.Geear.New_Body_Parts", FALSE); + + if (!menu_clothes || !menu_bp) + { + llassert(menu_clothes && menu_bp); + return; + } + + for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i) + { + LLWearableType::EType type = (LLWearableType::EType) i; + const std::string& type_name = LLWearableType::getTypeName(type); + + LLMenuItemCallGL::Params p; + p.name = type_name; + p.label = LLWearableType::getTypeDefaultNewName(type); + p.on_click.function_name = "Wearable.Create"; + p.on_click.parameter = LLSD(type_name); + + LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? + menu_clothes : menu_bp; + LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent); + } + } +}; + class LLCOFObserver : public LLInventoryObserver { public: @@ -259,7 +323,6 @@ BOOL LLPanelOutfitEdit::postBuild() mFolderViewBtn = getChild<LLButton>("folder_view_btn"); mListViewBtn = getChild<LLButton>("list_view_btn"); - mAddToOutfitBtn = getChild<LLButton>("add_to_outfit_btn"); childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL); childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL); @@ -275,8 +338,6 @@ BOOL LLPanelOutfitEdit::postBuild() mCOFWearables->getCOFCallbacks().mMoveWearableCloser = boost::bind(&LLPanelOutfitEdit::moveWearable, this, true); mCOFWearables->getCOFCallbacks().mMoveWearableFurther = boost::bind(&LLPanelOutfitEdit::moveWearable, this, false); - mCOFWearables->childSetAction("add_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); - mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel"); mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items"); @@ -298,7 +359,8 @@ BOOL LLPanelOutfitEdit::postBuild() mSearchFilter = getChild<LLFilterEditor>("look_item_filter"); mSearchFilter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onSearchEdit, this, _2)); - + + childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this)); mEditWearableBtn = getChild<LLButton>("edit_wearable_btn"); @@ -313,7 +375,6 @@ BOOL LLPanelOutfitEdit::postBuild() mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel"); mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list"); - mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector); mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this)); return TRUE; @@ -324,6 +385,10 @@ void LLPanelOutfitEdit::onOpen(const LLSD& key) { if (!mInitialized) { + // *TODO: this method is called even panel is not visible to user because its parent layout panel is hidden. + // So, we can defer initializing a bit. + mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector); + mWearableListManager->populateList(); displayCurrentOutfit(); mInitialized = true; } @@ -341,15 +406,28 @@ void LLPanelOutfitEdit::moveWearable(bool closer_to_body) void LLPanelOutfitEdit::toggleAddWearablesPanel() { BOOL current_visibility = mAddWearablesPanel->getVisible(); - mAddWearablesPanel->setVisible(!current_visibility); + showAddWearablesPanel(!current_visibility); +} + +void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables) +{ + mAddWearablesPanel->setVisible(show_add_wearables); + + childSetValue("show_add_wearables_btn", show_add_wearables); - mFolderViewBtn->setVisible(!current_visibility); - mListViewBtn->setVisible(!current_visibility); - mAddToOutfitBtn->setVisible(!current_visibility); + childSetVisible("filter_wearables_combobox", show_add_wearables); + childSetVisible("filter_button", show_add_wearables); - // Change right dummy icon to fill the toggled buttons space. - childSetVisible("add_wearables_dummy_icon", !current_visibility); - childSetVisible("dummy_right_icon", current_visibility); + //search filter should be disabled + if (!show_add_wearables) + { + childSetValue("filter_button", false); + showWearablesFilter(); + } + + //switching button bars + childSetVisible("no_add_wearables_button_bar", !show_add_wearables); + childSetVisible("add_wearables_button_bar", show_add_wearables); } void LLPanelOutfitEdit::showWearablesFilter() @@ -708,34 +786,18 @@ void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) { if(!mGearMenu) { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("Gear.OnClick", boost::bind(&LLPanelOutfitEdit::onGearMenuItemClick, this, _2)); - - mGearMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( - "menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); - mGearMenu->buildDrawLabels(); - mGearMenu->updateParent(LLMenuGL::sMenuContainer); + mGearMenu = LLPanelOutfitEditGearMenu::create(); } S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight(); LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y); } -void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data) -{ - std::string param = data.asString(); - if("add" == param) - { - // TODO - } -} - void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type) { mWearableListTypeCollector->setType(type); mWearableListManager->setFilterCollector(mWearableListTypeCollector); - mAddWearablesPanel->setVisible(TRUE); + showAddWearablesPanel(true); showFilteredWearablesPanel(); } diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 1569c55732..802386c573 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -93,6 +93,7 @@ public: void moveWearable(bool closer_to_body); void toggleAddWearablesPanel(); + void showAddWearablesPanel(bool show__add_wearables); void showWearablesFilter(); void showFilteredWearablesPanel(); void showFilteredFolderWearablesPanel(); @@ -131,7 +132,6 @@ public: private: void onGearButtonClick(LLUICtrl* clicked_button); - void onGearMenuItemClick(const LLSD& data); void showFilteredWearableItemsList(LLWearableType::EType type); @@ -144,7 +144,6 @@ private: LLButton* mEditWearableBtn; LLButton* mFolderViewBtn; LLButton* mListViewBtn; - LLButton* mAddToOutfitBtn; LLPanel* mAddWearablesPanel; LLFindNonLinksByMask* mWearableListMaskCollector; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 21f69d3470..5f67f3d989 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -42,6 +42,7 @@ #include "llfloaterworldmap.h" #include "llfloaterinventory.h" #include "llfoldervieweventlistener.h" +#include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" @@ -70,11 +71,134 @@ static const std::string COF_TAB_NAME = "cof_tab"; static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); +class LLOutfitListGearMenu +{ +public: + LLOutfitListGearMenu(LLOutfitsList* olist) + : mOutfitList(olist), + mMenu(NULL) + { + llassert_always(mOutfitList); + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this)); + registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this)); + registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this)); + registrar.add("Gear.Delete", boost::bind(&LLOutfitListGearMenu::onDelete, this)); + registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2)); + + enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2)); + + mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( + "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(mMenu); + } + + LLMenuGL* getMenu() { return mMenu; } + +private: + const LLUUID& getSelectedOutfitID() + { + return mOutfitList->getSelectedOutfitUUID(); + } + + LLViewerInventoryCategory* getSelectedOutfit() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.isNull()) + { + return NULL; + } + + LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id); + return cat; + } + + void onWear() + { + LLViewerInventoryCategory* selected_outfit = getSelectedOutfit(); + if (selected_outfit) + { + LLAppearanceMgr::instance().wearInventoryCategory( + selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE); + } + } + + void onTakeOff() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); + } + } + + void onRename() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().renameOutfit(selected_outfit_id); + } + } + + void onDelete() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + remove_category(&gInventory, selected_outfit_id); + } + } + + void onCreate(const LLSD& data) + { + LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); + if (type == LLWearableType::WT_NONE) + { + llwarns << "Invalid wearable type" << llendl; + return; + } + + LLAgentWearables::createWearable(type, true); + } + + bool onEnable(LLSD::String param) + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id; + + if ("wear" == param) + { + return !is_worn; + } + else if ("take_off" == param) + { + return is_worn; + } + else if ("rename" == param) + { + return get_is_category_renameable(&gInventory, selected_outfit_id); + } + else if ("delete" == param) + { + return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id); + } + + return true; + } + + LLOutfitsList* mOutfitList; + LLMenuGL* mMenu; +}; LLPanelOutfitsInventory::LLPanelOutfitsInventory() : mMyOutfitsPanel(NULL), mCurrentOutfitPanel(NULL), mParent(NULL), + mGearMenu(NULL), mInitialized(false) { mSavedFolderState = new LLSaveFolderState(); @@ -84,6 +208,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() : LLPanelOutfitsInventory::~LLPanelOutfitsInventory() { + delete mGearMenu; delete mSavedFolderState; } @@ -374,7 +499,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() { mListCommands = getChild<LLPanel>("bottom_panel"); - mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this)); + mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this)); mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this)); @@ -385,8 +510,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() , _7 // EAcceptance* accept )); - mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_outfit_gear.xml", - gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearMenu = new LLOutfitListGearMenu(mMyOutfitsPanel); } void LLPanelOutfitsInventory::updateListCommands() @@ -401,18 +525,14 @@ void LLPanelOutfitsInventory::updateListCommands() mSaveComboBtn->setSaveBtnEnabled(make_outfit_enabled); } -void LLPanelOutfitsInventory::onGearButtonClick() -{ - showActionMenu(mMenuGearDefault,"options_gear_btn"); -} - -void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) +void LLPanelOutfitsInventory::showGearMenu() { + LLMenuGL* menu = mGearMenu ? mGearMenu->getMenu() : NULL; if (menu) { menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - LLView* spawning_view = getChild<LLView> (spawning_view_name); + LLView* spawning_view = getChild<LLView>("options_gear_btn"); S32 menu_x, menu_y; //show menu in co-ordinates of panel spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); @@ -632,6 +752,7 @@ void LLPanelOutfitsInventory::onTabChange() else { mMyOutfitsPanel->setFilterSubString(mFilterSubString); + mMyOutfitsPanel->onOpen(LLSD()); } updateVerbs(); diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 7bdd37c16c..aff7839bcc 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -47,6 +47,7 @@ class LLMenuGL; class LLSidepanelAppearance; class LLTabContainer; class LLSaveOutfitComboBtn; +class LLOutfitListGearMenu; class LLPanelOutfitsInventory : public LLPanel { @@ -116,9 +117,8 @@ private: protected: void initListCommandsHandlers(); void updateListCommands(); - void onGearButtonClick(); void onWearButtonClick(); - void showActionMenu(LLMenuGL* menu, std::string spawning_view_name); + void showGearMenu(); void onTrashButtonClick(); void onClipboardAction(const LLSD& userdata); BOOL isActionEnabled(const LLSD& command_name); @@ -129,7 +129,7 @@ protected: void onWearablesLoaded(); private: LLPanel* mListCommands; - LLMenuGL* mMenuGearDefault; + LLOutfitListGearMenu* mGearMenu; LLMenuGL* mMenuAdd; // List Commands // //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index e48b18751d..986f71ae7b 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -842,7 +842,8 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 1) + // if Cancel pressed + if (option == 1) { return; } diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index 9e636f38c0..6389fd292c 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -59,7 +59,7 @@ void initializeSecHandler() gSecAPIHandler = gHandlerMap[BASIC_SECHANDLER]; // initialize all SecAPIHandlers - LLProtectedDataException ex = LLProtectedDataException(""); + std::string exception_msg; std::map<std::string, LLPointer<LLSecAPIHandler> >::const_iterator itr; for(itr = gHandlerMap.begin(); itr != gHandlerMap.end(); ++itr) { @@ -70,12 +70,12 @@ void initializeSecHandler() } catch (LLProtectedDataException e) { - ex = e; + exception_msg = e.getMessage(); } } - if (ex.getMessage().length() > 0 ) // an exception was thrown. + if (!exception_msg.empty()) // an exception was thrown. { - throw ex; + throw LLProtectedDataException(exception_msg.c_str()); } } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 9159f42968..3c97f01887 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -66,21 +66,6 @@ static const std::string TAB_PANEL_CAPTION_TITLE_BOX = "sidetray_tab_title"; LLSideTray* LLSideTray::sInstance = 0; -/** - * Updates visibility of sidetray tabs buttons according to "SidebarWithButtonsVisibility" setting - * - * @param force_set_visible if true method ignores setting value and set buttons visible. - */ -static void update_tabs_buttons_visibility(bool force_set_visible = false) -{ - LLView* side_bar_tabs = gViewerWindow->getRootView()->getChildView("side_bar_tabs"); - if (side_bar_tabs) - { - BOOL visible = LLUI::sSettingGroups["config"]->getBOOL("SidebarWithButtonsVisibility"); - side_bar_tabs->setVisible(force_set_visible || visible); - } -} - LLSideTray* LLSideTray::getInstance() { if (!sInstance) @@ -273,8 +258,6 @@ LLSideTray::LLSideTray(Params& params) p.name = "buttons_panel"; p.mouse_opaque = false; mButtonsPanel = LLUICtrlFactory::create<LLPanel>(p); - - initControlSettings(); } @@ -563,8 +546,6 @@ void LLSideTray::collapseSideBar() //mActiveTab->setVisible(FALSE); reflectCollapseChange(); setFocus( FALSE ); - - update_tabs_buttons_visibility(); } void LLSideTray::expandSideBar() @@ -589,8 +570,6 @@ void LLSideTray::expandSideBar() LLButton* btn = btn_it->second; btn->setImageOverlay( mActiveTab->mImageSelected ); } - - update_tabs_buttons_visibility(true); } void LLSideTray::highlightFocused() @@ -658,8 +637,6 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para panel->onOpen(params); } - update_tabs_buttons_visibility(true); - return panel; } } @@ -751,35 +728,3 @@ void LLSideTray::updateSidetrayVisibility() } } -void LLSideTray::initControlSettings() -{ - // set listeners to process runtime setting changes - LLUI::sSettingGroups["config"]->getControl("SidebarWithButtonsVisibility")->getSignal()->connect(boost::bind(&LLSideTray::toggleSidetrayAndTabButtonsVisibility, this, _2)); - - // update visibility according to current value - toggleSidetrayAndTabButtonsVisibility(LLUI::sSettingGroups["config"]->getBOOL("SidebarWithButtonsVisibility")); -} - -// sidebar visibility is implemented via its expanding/collapsing -void LLSideTray::toggleSidetrayAndTabButtonsVisibility(const LLSD::Boolean& new_visibility) -{ - // If new_visibility==FALSE it gets invisible but still can be expanded in other ways (Ctrl+I to see My Inventory) - - // store collapsed state to restore it properly on next call - static bool was_collapsed = false; - - if (!new_visibility && !mCollapsed) - { - collapseSideBar(); - was_collapsed = true; - } - // should be visible: expand only if it was expanded when has been collapsed on previous call - else if (new_visibility && was_collapsed) - { - if (mCollapsed) expandSideBar(); - was_collapsed = false; - } - - update_tabs_buttons_visibility(new_visibility); -} - diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index ed6b376d5c..e8fdee9430 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -179,16 +179,6 @@ private: LLSideTray::getInstance()->setEnabled(FALSE); } - /** - * Initializes listener of SidebarWithButtonsVisibility setting and updates state according to it. - */ - void initControlSettings(); - - /** - * Updates Sidebar and its Tab Buttons visibility according to passed value. - */ - void toggleSidetrayAndTabButtonsVisibility(const LLSD::Boolean& new_visibility); - private: LLPanel* mButtonsPanel; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 977ae7ed45..89178fc30c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -736,6 +736,8 @@ bool idle_startup() // Make sure the process dialog doesn't hide things gViewerWindow->setShowProgress(FALSE); + initialize_edit_menu(); + // Show the login dialog login_show(); // connect dialog is already shown, so fill in the names diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index 15684337f4..cac3b58464 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -38,6 +38,7 @@ #include "llsdserialize.h" #include "llagent.h" +#include "llvoavatarself.h" #include "llslurl.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewerparcelmgr.h" @@ -108,6 +109,16 @@ void LLTeleportHistory::onTeleportFailed() } } +void LLTeleportHistory::handleLoginComplete() +{ + if( mGotInitialUpdate ) + { + return; + } + updateCurrentLocation(gAgent.getPositionGlobal()); +} + + void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) { if (mRequestedItem != -1) // teleport within the history in progress? @@ -117,6 +128,17 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) } else { + //EXT-7034 + //skip initial update if agent avatar is no valid yet + //this may happen when updateCurrentLocation called while login process + //sometimes isAgentAvatarValid return false and in this case new_pos + //(which actually is gAgent.getPositionGlobal() ) is invalid + //if this position will be saved then teleport back will teleport user to wrong position + if ( !mGotInitialUpdate && !isAgentAvatarValid() ) + { + return ; + } + // If we're getting the initial location update // while we already have a (loaded) non-empty history, // there's no need to purge forward items or add a new item. diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h index a82bec7c4f..e035451e71 100644 --- a/indra/newview/llteleporthistory.h +++ b/indra/newview/llteleporthistory.h @@ -136,6 +136,10 @@ public: * @see load() */ void dump() const; + /** + * Process login complete event. Basically put current location into history + */ + void handleLoginComplete(); private: diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index b13f9e3898..1d74a7be8c 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -57,17 +57,52 @@ using namespace LLVOAvatarDefines; +class LLTexLayerInfo +{ + friend class LLTexLayer; + friend class LLTexLayerTemplate; + friend class LLTexLayerInterface; +public: + LLTexLayerInfo(); + ~LLTexLayerInfo(); + + BOOL parseXml(LLXmlTreeNode* node); + BOOL createVisualParams(LLVOAvatar *avatar); + BOOL isUserSettable() { return mLocalTexture != -1; } + S32 getLocalTexture() const { return mLocalTexture; } + BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; } + std::string getName() const { return mName; } + +private: + std::string mName; + + BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer, + LLTexLayerInterface::ERenderPass mRenderPass; + + std::string mGlobalColor; + LLColor4 mFixedColor; + + S32 mLocalTexture; + std::string mStaticImageFileName; + BOOL mStaticImageIsMask; + BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask + BOOL mIsVisibilityMask; + + typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t; + morph_name_list_t mMorphNameList; + param_color_info_list_t mParamColorInfoList; + param_alpha_info_list_t mParamAlphaInfoList; +}; + //----------------------------------------------------------------------------- // LLBakedUploadData() //----------------------------------------------------------------------------- LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, - const LLUUID& id, - BOOL highest_lod) : + const LLUUID& id) : mAvatar(avatar), mTexLayerSet(layerset), mID(id), - mHighestLOD(highest_lod), mStartTime(LLFrameTimer::getTotalTime()) // Record starting time { } @@ -87,7 +122,7 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, mNeedsUpdate(TRUE), mNeedsUpload(FALSE), mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates - mDebugNumLowresUploads(0), + mNumLowresUploads(0), mTexLayerSet(owner) { LLTexLayerSetBuffer::sGLByteCount += getSize(); @@ -141,12 +176,12 @@ void LLTexLayerSetBuffer::requestUpload() // If we requested a new upload but haven't even uploaded // a low res version of our last upload request, then // keep the timer ticking instead of resetting it. - if (mNeedsUpload && (mDebugNumLowresUploads == 0)) + if (mNeedsUpload && (mNumLowresUploads == 0)) { mNeedsUploadTimer.reset(); } mNeedsUpload = TRUE; - mDebugNumLowresUploads = 0; + mNumLowresUploads = 0; mUploadPending = TRUE; mNeedsUploadTimer.unpause(); } @@ -289,8 +324,12 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout"); if (texture_timeout) { + // The timeout period increases exponentially between every lowres upload in order to prevent + // spamming the server with frequent uploads. + const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads); + // If we hit our timeout and have textures available at even lower resolution, then upload. - const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout; + const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold; const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable(); if (has_lower_lod && is_upload_textures_timeout) return TRUE; } @@ -387,14 +426,13 @@ void LLTexLayerSetBuffer::readBackAndUpload() if( valid ) { - const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal(); // baked_upload_data is owned by the responder and deleted after the request completes LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, this->mTexLayerSet, - asset_id, - highest_lod); + asset_id); mUploadID = asset_id; - + const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal(); + // upload the image std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture"); @@ -431,19 +469,19 @@ void LLTexLayerSetBuffer::readBackAndUpload() LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args); llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl; } - + if (highest_lod) { - // Got the final LOD for the baked texture. + // Sending the final LOD for the baked texture. // All done, pause the upload timer so we know how long it took. mNeedsUpload = FALSE; mNeedsUploadTimer.pause(); } else { - // Got a lower level LOD for the baked texture. + // Sending a lower level LOD for the baked texture. // Restart the upload timer. - mDebugNumLowresUploads++; + mNumLowresUploads++; mNeedsUploadTimer.unpause(); mNeedsUploadTimer.reset(); } @@ -973,11 +1011,11 @@ void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_ mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex); } -BOOL LLTexLayerSet::isMorphValid() +BOOL LLTexLayerSet::isMorphValid() const { - for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + for(layer_list_t::const_iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - LLTexLayerInterface* layer = *iter; + const LLTexLayerInterface* layer = *iter; if (layer && !layer->isMorphValid()) { return FALSE; @@ -1193,7 +1231,6 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set): mTexLayerSet( layer_set ), mMorphMasksValid( FALSE ), - mStaticImageInvalid( FALSE ), mInfo(NULL), mHasMorph(FALSE) { @@ -1307,17 +1344,17 @@ void LLTexLayerInterface::invalidateMorphMasks() mMorphMasksValid = FALSE; } -LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) +LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) const { LLViewerVisualParam *result = NULL; - for (param_color_list_t::iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter) + for (param_color_list_t::const_iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter) { if ((*color_iter)->getID() == index) { result = *color_iter; } } - for (param_alpha_list_t::iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter) + for (param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter) { if ((*alpha_iter)->getID() == index) { @@ -1571,7 +1608,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) return success; } -U8* LLTexLayer::getAlphaData() +const U8* LLTexLayer::getAlphaData() const { LLCRC alpha_mask_crc; const LLUUID& uuid = getUUID(); @@ -1587,7 +1624,7 @@ U8* LLTexLayer::getAlphaData() U32 cache_index = alpha_mask_crc.getCRC(); - alpha_cache_t::iterator iter2 = mAlphaCache.find(cache_index); + alpha_cache_t::const_iterator iter2 = mAlphaCache.find(cache_index); return (iter2 == mAlphaCache.end()) ? 0 : iter2->second; } @@ -1810,7 +1847,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { S32 size = width * height; - U8* alphaData = getAlphaData(); + const U8* alphaData = getAlphaData(); if (!alphaData && hasAlphaParams()) { LLColor4 net_color; @@ -1833,7 +1870,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 } } -/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() +/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() const { if (mLocalTextureObject) { @@ -1846,8 +1883,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 return FALSE; } -// private helper function -LLUUID LLTexLayer::getUUID() +LLUUID LLTexLayer::getUUID() const { LLUUID uuid; if( getInfo()->mLocalTexture != -1 ) @@ -1906,7 +1942,7 @@ LLTexLayerTemplate::~LLTexLayerTemplate() return LLTexLayerInterface::setInfo(info, wearable); } -U32 LLTexLayerTemplate::updateWearableCache() +U32 LLTexLayerTemplate::updateWearableCache() const { mWearableCache.clear(); @@ -1931,7 +1967,7 @@ U32 LLTexLayerTemplate::updateWearableCache() } return added; } -LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) +LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const { if (mWearableCache.size() <= i) { @@ -2040,7 +2076,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) } } -/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() +/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() const { U32 num_wearables = updateWearableCache(); for (U32 i = 0; i < num_wearables; i++) @@ -2064,19 +2100,17 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) //----------------------------------------------------------------------------- LLTexLayerInterface* LLTexLayerSet::findLayerByName(const std::string& name) { - for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - if (layer->getName() == name) { return layer; } } - for( layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ ) + for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - if (layer->getName() == name) { return layer; @@ -2121,7 +2155,7 @@ LLTexLayerStaticImageList::~LLTexLayerStaticImageList() deleteCachedImages(); } -void LLTexLayerStaticImageList::dumpByteCount() +void LLTexLayerStaticImageList::dumpByteCount() const { llinfos << "Avatar Static Textures " << "KB GL:" << (mGLBytes / 1024) << @@ -2241,11 +2275,13 @@ const std::string LLTexLayerSetBuffer::dumpTextureInfo() const if (!isAgentAvatarValid()) return ""; const BOOL is_high_res = !mNeedsUpload; - const U32 num_low_res = mDebugNumLowresUploads; + const U32 num_low_res = mNumLowresUploads; const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32(); + const BOOL is_uploaded = !mUploadPending; const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet); - std::string text = llformat("[ HiRes:%d LoRes:%d Timer:%d ] %s", - is_high_res, num_low_res, upload_time, + std::string text = llformat("[ HiRes:%d LoRes:%d Uploaded:%d ] [ Timer:%d ] %s", + is_high_res, num_low_res, is_uploaded, + upload_time, local_texture_info.c_str()); return text; } diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 313c5f24e1..2ee609fe60 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -1,6 +1,6 @@ /** * @file lltexlayer.h - * @brief A texture layer. Used for avatars. + * @brief Texture layer classes. Used for avatars. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -35,40 +35,31 @@ #include <deque> #include "lldynamictexture.h" -#include "llwearable.h" #include "llvoavatardefines.h" +#include "lltexlayerparams.h" class LLVOAvatar; class LLVOAvatarSelf; class LLImageTGA; class LLImageRaw; class LLXmlTreeNode; -class LLPolyMorphTarget; class LLTexLayerSet; class LLTexLayerSetInfo; class LLTexLayerInfo; class LLTexLayerSetBuffer; -class LLTexLayerParamColor; -class LLTexLayerParamColorInfo; -class LLTexLayerParamAlpha; -class LLTexLayerParamAlphaInfo; class LLWearable; class LLViewerVisualParam; -typedef std::vector<LLTexLayerParamColor *> param_color_list_t; -typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t; -typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t; -typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t; - - -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerInterface -// Interface class to generalize functionality shared by LLTexLayer and LLTexLayerTemplate. - +// +// Interface class to generalize functionality shared by LLTexLayer +// and LLTexLayerTemplate. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerInterface { public: - enum ERenderPass + enum ERenderPass { RP_COLOR, RP_BUMP, @@ -79,84 +70,78 @@ public: LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable); virtual ~LLTexLayerInterface() {} - const LLTexLayerInfo* getInfo() const { return mInfo; } - virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0; - void requestUpdate(); - LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; } - virtual void deleteCaches() = 0; - void invalidateMorphMasks(); - virtual void setHasMorph(BOOL newval) { mHasMorph = newval; } - BOOL hasMorph() { return mHasMorph; } - BOOL isMorphValid() { return mMorphMasksValid; } + virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0; + virtual BOOL isInvisibleAlphaMask() const = 0; + + const LLTexLayerInfo* getInfo() const { return mInfo; } + virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions const std::string& getName() const; - ERenderPass getRenderPass() const; - const std::string& getGlobalColor() const; + const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; } + LLTexLayerSet* const getTexLayerSet() { return mTexLayerSet; } - virtual BOOL blendAlphaTexture( S32 x, S32 y, S32 width, S32 height) = 0; - virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0; - BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } - BOOL isVisibilityMask() const; - virtual BOOL isInvisibleAlphaMask() = 0; + void invalidateMorphMasks(); + virtual void setHasMorph(BOOL newval) { mHasMorph = newval; } + BOOL hasMorph() const { return mHasMorph; } + BOOL isMorphValid() const { return mMorphMasksValid; } - LLTexLayerSet* getLayerSet() {return mTexLayerSet;} + void requestUpdate(); + virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0; + BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } - LLViewerVisualParam* getVisualParamPtr(S32 index); + ERenderPass getRenderPass() const; + BOOL isVisibilityMask() const; +protected: + const std::string& getGlobalColor() const; + LLViewerVisualParam* getVisualParamPtr(S32 index) const; protected: - LLTexLayerSet* const mTexLayerSet; + LLTexLayerSet* const mTexLayerSet; + const LLTexLayerInfo* mInfo; + BOOL mMorphMasksValid; + BOOL mHasMorph; // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order. param_color_list_t mParamColorList; + param_alpha_list_t mParamAlphaList; // mGlobalColor name stored in mInfo // mFixedColor value stored in mInfo - param_alpha_list_t mParamAlphaList; - - BOOL mMorphMasksValid; - BOOL mStaticImageInvalid; - - BOOL mHasMorph; - - const LLTexLayerInfo *mInfo; - }; -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerTemplate -// Template class -// Only exists for llvoavatarself - +// +// Only exists for llvoavatarself. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerTemplate : public LLTexLayerInterface { public: LLTexLayerTemplate(LLTexLayerSet* const layer_set); LLTexLayerTemplate(const LLTexLayerTemplate &layer); /*virtual*/ ~LLTexLayerTemplate(); - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); - /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions - /*virtual*/ BOOL blendAlphaTexture( S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer + /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions + /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); /*virtual*/ void setHasMorph(BOOL newval); /*virtual*/ void deleteCaches(); - /*virtual*/ BOOL isInvisibleAlphaMask(); - + /*virtual*/ BOOL isInvisibleAlphaMask() const; +protected: + U32 updateWearableCache() const; + LLTexLayer* getLayer(U32 i) const; private: - U32 updateWearableCache(); - LLTexLayer* getLayer(U32 i); typedef std::vector<LLWearable*> wearable_cache_t; - wearable_cache_t mWearableCache; - + mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache }; -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayer -// A single texture layer -// Only exists for llvoavatarself - +// +// A single texture layer. Only exists for llvoavatarself. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayer : public LLTexLayerInterface { public: @@ -165,79 +150,37 @@ public: LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable); /*virtual*/ ~LLTexLayer(); - /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions + /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); /*virtual*/ void deleteCaches(); - U8* getAlphaData(); + const U8* getAlphaData() const; BOOL findNetColor(LLColor4* color) const; - /*virtual*/ BOOL blendAlphaTexture( S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer + /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color); void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height); - /*virtual*/ BOOL isInvisibleAlphaMask(); - - void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } - LLLocalTextureObject* getLTO() { return mLocalTextureObject; } + /*virtual*/ BOOL isInvisibleAlphaMask() const; - static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); + void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } + LLLocalTextureObject* getLTO() { return mLocalTextureObject; } + static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); +protected: + LLUUID getUUID() const; private: - LLUUID getUUID(); - typedef std::map<U32, U8*> alpha_cache_t; alpha_cache_t mAlphaCache; - LLLocalTextureObject *mLocalTextureObject; -}; - -// Make private -class LLTexLayerInfo -{ - friend class LLTexLayer; - friend class LLTexLayerTemplate; - friend class LLTexLayerInterface; -public: - LLTexLayerInfo(); - ~LLTexLayerInfo(); - - BOOL parseXml(LLXmlTreeNode* node); - BOOL createVisualParams(LLVOAvatar *avatar); - BOOL isUserSettable() { return mLocalTexture != -1; } - S32 getLocalTexture() const { return mLocalTexture; } - BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; } - std::string getName() const { return mName; } - -private: - std::string mName; - - BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer, - LLTexLayer::ERenderPass mRenderPass; - - std::string mGlobalColor; - LLColor4 mFixedColor; - - S32 mLocalTexture; - std::string mStaticImageFileName; - BOOL mStaticImageIsMask; - BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask - BOOL mIsVisibilityMask; - - typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t; - morph_name_list_t mMorphNameList; - param_color_info_list_t mParamColorInfoList; - param_alpha_info_list_t mParamAlphaInfoList; + LLLocalTextureObject* mLocalTextureObject; }; -// -// LLTexLayer -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerSet -// An ordered set of texture layers that get composited into a single texture. -// Only exists for llvoavatarself - +// +// An ordered set of texture layers that gets composited into a single texture. +// Only exists for llvoavatarself. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerSet { friend class LLTexLayerSetBuffer; @@ -245,186 +188,163 @@ public: LLTexLayerSet(LLVOAvatarSelf* const avatar); ~LLTexLayerSet(); - const LLTexLayerSetInfo* getInfo() const { return mInfo; } - BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions - - BOOL render(S32 x, S32 y, S32 width, S32 height); - void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); - - BOOL isBodyRegion(const std::string& region) const; - LLTexLayerSetBuffer* getComposite(); - const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. - void requestUpdate(); - void requestUpload(); - void cancelUpload(); - void updateComposite(); - BOOL isLocalTextureDataAvailable() const; - BOOL isLocalTextureDataFinal() const; - void createComposite(); - void destroyComposite(); - void setUpdatesEnabled(BOOL b); - BOOL getUpdatesEnabled() const { return mUpdatesEnabled; } - void deleteCaches(); - void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height); - void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); - BOOL isMorphValid(); - void invalidateMorphMasks(); - LLTexLayerInterface* findLayerByName(const std::string& name); - void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable); + const LLTexLayerSetInfo* getInfo() const { return mInfo; } + BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions + + BOOL render(S32 x, S32 y, S32 width, S32 height); + void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); + + BOOL isBodyRegion(const std::string& region) const; + LLTexLayerSetBuffer* getComposite(); + const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. + void requestUpdate(); + void requestUpload(); + void cancelUpload(); + void updateComposite(); + BOOL isLocalTextureDataAvailable() const; + BOOL isLocalTextureDataFinal() const; + void createComposite(); + void destroyComposite(); + void setUpdatesEnabled(BOOL b); + BOOL getUpdatesEnabled() const { return mUpdatesEnabled; } + void deleteCaches(); + void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height); + void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); + BOOL isMorphValid() const; + void invalidateMorphMasks(); + LLTexLayerInterface* findLayerByName(const std::string& name); + void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable); - LLVOAvatarSelf* getAvatar() const { return mAvatar; } - const std::string getBodyRegionName() const; - BOOL hasComposite() const { return (mComposite.notNull()); } + LLVOAvatarSelf* getAvatar() const { return mAvatar; } + const std::string getBodyRegionName() const; + BOOL hasComposite() const { return (mComposite.notNull()); } LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } - void setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } - BOOL isVisible() const { return mIsVisible; } + void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } + BOOL isVisible() const { return mIsVisible; } -public: - static BOOL sHasCaches; - - typedef std::vector<LLTexLayerInterface *> layer_list_t; + static BOOL sHasCaches; private: - layer_list_t mLayerList; - layer_list_t mMaskLayerList; + typedef std::vector<LLTexLayerInterface *> layer_list_t; + layer_list_t mLayerList; + layer_list_t mMaskLayerList; LLPointer<LLTexLayerSetBuffer> mComposite; - LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer. - BOOL mUpdatesEnabled; - BOOL mIsVisible; + LLVOAvatarSelf* const mAvatar; // note: backlink only; don't make this an LLPointer. + BOOL mUpdatesEnabled; + BOOL mIsVisible; LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; - - const LLTexLayerSetInfo *mInfo; + const LLTexLayerSetInfo* mInfo; }; -// Contains shared layer set data +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerSetInfo +// +// Contains shared layer set data. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerSetInfo { friend class LLTexLayerSet; public: LLTexLayerSetInfo(); ~LLTexLayerSetInfo(); - BOOL parseXml(LLXmlTreeNode* node); void createVisualParams(LLVOAvatar *avatar); - private: std::string mBodyRegion; S32 mWidth; S32 mHeight; std::string mStaticAlphaFileName; BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName) - typedef std::vector<LLTexLayerInfo*> layer_info_list_t; layer_info_list_t mLayerInfoList; }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerSetBuffer +// // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerSetBuffer : public LLViewerDynamicTexture { public: LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); virtual ~LLTexLayerSetBuffer(); - - /*virtual*/ S8 getType() const ; + /*virtual*/ S8 getType() const; virtual void preRender(BOOL clear_depth); virtual void postRender(BOOL success); virtual BOOL render(); BOOL updateImmediate(); bool isInitialized(void) const; - BOOL needsRender(); + /*virtual*/ BOOL needsRender(); void requestUpdate(); void requestUpload(); void cancelUpload(); - BOOL uploadPending() { return mUploadPending; } - BOOL render( S32 x, S32 y, S32 width, S32 height ); + BOOL uploadPending() const { return mUploadPending; } + BOOL render(S32 x, S32 y, S32 width, S32 height); void readBackAndUpload(); - static void onTextureUploadComplete(const LLUUID& uuid, void* userdata, S32 result, LLExtStat ext_status); static void dumpTotalByteCount(); - const std::string dumpTextureInfo() const; - - virtual void restoreGLTexture(); - virtual void destroyGLTexture(); - + virtual void restoreGLTexture(); + virtual void destroyGLTexture(); protected: void pushProjection() const; void popProjection() const; BOOL isReadyToUpload() const; - private: LLTexLayerSet* const mTexLayerSet; - - BOOL mNeedsUpdate; // Whether we need to update our baked textures - BOOL mNeedsUpload; // Whether we need to send our baked textures to the server - U32 mDebugNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server - BOOL mUploadPending; // Whether we have received back the new baked textures - LLUUID mUploadID; // Identifies the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) - + BOOL mNeedsUpdate; // whether we need to update our baked textures + BOOL mNeedsUpload; // whether we need to send our baked textures to the server + U32 mNumLowresUploads; // mumber of times we've sent a lowres version of our baked textures to the server + BOOL mUploadPending; // whether we have received back the new baked textures + LLUUID mUploadID; // the current upload process (null if none). Used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit. static S32 sGLByteCount; - LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested - }; -// -// LLTexLayerSet -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerStaticImageList // - +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList> { public: LLTexLayerStaticImageList(); ~LLTexLayerStaticImageList(); - LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask); - LLImageTGA* getImageTGA(const std::string& file_name); - - void deleteCachedImages(); - void dumpByteCount(); - -private: - BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw); - + LLImageTGA* getImageTGA(const std::string& file_name); + void deleteCachedImages(); + void dumpByteCount() const; +protected: + BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw); private: - LLStringTable mImageNames; - - typedef std::map< const char*, LLPointer<LLViewerTexture> > texture_map_t; - texture_map_t mStaticImageList; - typedef std::map< const char*, LLPointer<LLImageTGA> > image_tga_map_t; - image_tga_map_t mStaticImageListTGA; - - S32 mGLBytes; - S32 mTGABytes; + LLStringTable mImageNames; + typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t; + texture_map_t mStaticImageList; + typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t; + image_tga_map_t mStaticImageListTGA; + S32 mGLBytes; + S32 mTGABytes; }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLBakedUploadData +// // Used by LLTexLayerSetBuffer for a callback. -// Note to anyone merging branches - this supercedes the previous fix -// for DEV-31590 "Heap corruption and crash after outfit changes", -// here and in lltexlayer.cpp. Equally correct and a bit simpler. -class LLBakedUploadData +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +struct LLBakedUploadData { -public: LLBakedUploadData(const LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, - const LLUUID& id, - BOOL highest_lod); + const LLUUID& id); ~LLBakedUploadData() {} - const LLUUID mID; - const LLVOAvatarSelf* mAvatar; // just backlink, don't LLPointer + const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer LLTexLayerSet* mTexLayerSet; - const U64 mStartTime; // Used to measure time baked texture upload requires - BOOL mHighestLOD; - + const U64 mStartTime; // for measuring baked texture upload time }; - #endif // LL_LLTEXLAYER_H diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 93d01352d4..7747ee1ebf 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -42,6 +42,10 @@ class LLViewerTexture; class LLVOAvatar; class LLWearable; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerParam +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerParam : public LLViewerVisualParam { public: @@ -55,9 +59,10 @@ protected: LLVOAvatar* mAvatar; }; -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerParamAlpha // +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerParamAlpha : public LLTexLayerParam { public: @@ -124,9 +129,10 @@ private: // LLTexLayerParamAlpha //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerParamColor // +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerParamColor : public LLTexLayerParam { public: @@ -184,8 +190,9 @@ private: S32 mNumColors; }; -// -// LLTexLayerParamColor -//----------------------------------------------------------------------------- +typedef std::vector<LLTexLayerParamColor *> param_color_list_t; +typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t; +typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t; +typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t; #endif diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 7a8b6557bb..377449cc8b 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -65,6 +65,8 @@ LLTextureView *gTextureView = NULL; LLTextureSizeView *gTextureSizeView = NULL; LLTextureSizeView *gTextureCategoryView = NULL; +#define HIGH_PRIORITY 100000000.f + //static std::set<LLViewerFetchedTexture*> LLTextureView::sDebugImages; @@ -415,13 +417,14 @@ void LLAvatarTexBar::draw() if (!avatarp) return; const S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - const S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f); + const S32 v_offset = 0; + //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 1.f); LLColor4 color; - U32 line_num = 6; + U32 line_num = 1; for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) @@ -433,7 +436,7 @@ void LLAvatarTexBar::draw() if (!layerset_buffer) continue; std::string text = layerset_buffer->dumpTextureInfo(); LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*line_num, - text_color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT); + text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT); line_num++; } const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout"); @@ -443,7 +446,7 @@ void LLAvatarTexBar::draw() const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled"; std::string header_text = llformat("[ Timeout('AvatarBakedTextureTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str()); LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, 0, v_offset + line_height*line_num, - text_color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT); + text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT); } BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask) @@ -454,7 +457,8 @@ BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask) LLRect LLAvatarTexBar::getRequiredRect() { LLRect rect; - rect.mTop = 8; + rect.mTop = 85; + if (!gSavedSettings.getBOOL("DebugAvatarRezTime")) rect.mTop = 0; return rect; } @@ -497,7 +501,7 @@ void LLGLTexMemBar::draw() F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ; F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ; S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 5.0f); + S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -649,7 +653,8 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask) LLRect LLGLTexMemBar::getRequiredRect() { LLRect rect; - rect.mTop = 8; + //rect.mTop = 50; + rect.mTop = 0; return rect; } @@ -808,7 +813,7 @@ void LLTextureView::draw() { S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ; llinfos << imagep->getID() - << "\t" << tex_mem + << "\t" << tex_mem << "\t" << imagep->getBoostLevel() << "\t" << imagep->getDecodePriority() << "\t" << imagep->getWidth() @@ -823,19 +828,6 @@ void LLTextureView::draw() ++debug_count; // for breakpoints } -#if 0 - if (imagep->getDontDiscard()) - { - continue; - } - - if (imagep->isMissingAsset()) - { - continue; - } -#endif - -#define HIGH_PRIORITY 100000000.f F32 pri; if (mOrderFetch) { @@ -854,59 +846,55 @@ void LLTextureView::draw() if (!mOrderFetch) { -#if 1 - if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance()) - { - struct f : public LLSelectedTEFunctor + if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance()) { - LLViewerFetchedTexture* mImage; - f(LLViewerFetchedTexture* image) : mImage(image) {} - virtual bool apply(LLViewerObject* object, S32 te) + struct f : public LLSelectedTEFunctor + { + LLViewerFetchedTexture* mImage; + f(LLViewerFetchedTexture* image) : mImage(image) {} + virtual bool apply(LLViewerObject* object, S32 te) + { + return (mImage == object->getTEImage(te)); + } + } func(imagep); + const bool firstonly = true; + bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly); + if (match) { - return (mImage == object->getTEImage(te)); + pri += 3*HIGH_PRIORITY; } - } func(imagep); - const bool firstonly = true; - bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly); - if (match) - { - pri += 3*HIGH_PRIORITY; } - } -#endif -#if 1 - if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard)) - { - LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode(); - if (hover_node) + + if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard)) { - LLViewerObject *objectp = hover_node->getObject(); - if (objectp) + LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode(); + if (hover_node) { - S32 tex_count = objectp->getNumTEs(); - for (S32 i = 0; i < tex_count; i++) + LLViewerObject *objectp = hover_node->getObject(); + if (objectp) { - if (imagep == objectp->getTEImage(i)) + S32 tex_count = objectp->getNumTEs(); + for (S32 i = 0; i < tex_count; i++) { - pri += 2*HIGH_PRIORITY; - break; + if (imagep == objectp->getTEImage(i)) + { + pri += 2*HIGH_PRIORITY; + break; + } } } } } - } -#endif -#if 1 - if (pri > 0.f && pri < HIGH_PRIORITY) - { - if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f || - imagep->mFetchDeltaTime < 0.25f) + + if (pri > 0.f && pri < HIGH_PRIORITY) { - pri += 1*HIGH_PRIORITY; + if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f || + imagep->mFetchDeltaTime < 0.25f) + { + pri += 1*HIGH_PRIORITY; + } } } -#endif - } if (pri > 0.0f) { @@ -947,18 +935,21 @@ void LLTextureView::draw() sortChildren(LLTextureBar::sort()); LLGLTexMemBar::Params tmbp; + LLRect tmbr; tmbp.name("gl texmem bar"); + tmbp.rect(tmbr); tmbp.texture_view(this); mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp); - addChild(mGLTexMemBar); + addChildInBack(mGLTexMemBar); LLAvatarTexBar::Params atbp; + LLRect atbr; atbp.name("gl avatartex bar"); atbp.texture_view(this); + atbp.rect(atbr); mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp); addChild(mAvatarTexBar); - reshape(getRect().getWidth(), getRect().getHeight(), TRUE); /* diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 568cd4cb19..9abfab300c 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -271,7 +271,10 @@ void LLToast::setVisible(BOOL show) { mTimer->start(); } - LLModalDialog::setFrontmost(FALSE); + if (!getVisible()) + { + LLModalDialog::setFrontmost(FALSE); + } } else { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 8a8bdd2dba..bc77ac5fd1 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -48,7 +48,7 @@ #include "llgiveinventory.h" #include "llhudmanager.h" #include "llhudeffecttrail.h" -//#include "llimview.h" +#include "llimview.h" #include "llinventorybridge.h" #include "llinventorydefines.h" #include "llinventoryfunctions.h" @@ -1422,12 +1422,42 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL } +static void give_inventory_cb(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } + + LLSD payload = notification["payload"]; + const LLUUID& session_id = payload["session_id"]; + const LLUUID& agent_id = payload["agent_id"]; + LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]); + if (NULL == inv_item) + { + llassert(NULL != inv_item); + return; + } + + if (LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id)) + { + if ("avatarpicker" == payload["d&d_dest"].asString()) + { + LLFloaterReg::hideInstance("avatar_picker"); + } + LLNotificationsUtil::add("ItemsShared"); + } +} + // function used as drag-and-drop handler for simple agent give inventory requests //static bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_id, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, - EAcceptance* accept) + EAcceptance* accept, + const LLSD& dest) { // check the type switch(cargo_type) @@ -1452,7 +1482,21 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ *accept = ACCEPT_YES_COPY_SINGLE; if (drop) { - LLGiveInventory::doGiveInventoryItem(dest_agent, inv_item, session_id); + LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id); + if (NULL == session) + { + llassert(NULL != session); + return false; + } + LLSD substitutions; + substitutions["RESIDENTS"] = session->mName; + substitutions["ITEMS"] = inv_item->getName(); + LLSD payload; + payload["agent_id"] = dest_agent; + payload["item_id"] = inv_item->getUUID(); + payload["session_id"] = session_id; + payload["d&d_dest"] = dest.asString(); + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); } } else diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 18334b5ee1..36e69c1db3 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -246,7 +246,8 @@ public: static bool handleGiveDragAndDrop(LLUUID agent, LLUUID session, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, - EAcceptance* accept); + EAcceptance* accept, + const LLSD& dest = LLSD()); // Classes used for determining 3d drag and drop types. private: diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp new file mode 100644 index 0000000000..f7f5ec72fd --- /dev/null +++ b/indra/newview/llviewerattachmenu.cpp @@ -0,0 +1,139 @@ +/** + * @file llviewerattachmenu.cpp + * @brief "Attach to" / "Attach to HUD" submenus. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewerattachmenu.h" + +// project includes +#include "llagent.h" +#include "llinventorybridge.h" // for rez_attachment() +#include "llinventorymodel.h" +#include "llviewerinventory.h" +#include "llviewermenu.h" // for gMenuHolder +#include "llvoavatarself.h" + +// linden libraries +#include "llmenugl.h" +#include "lltrans.h" + +// static +void LLViewerAttachMenu::populateMenus(const std::string& attach_to_menu_name, const std::string& attach_to_hud_menu_name) +{ + // *TODO: share this code with other similar menus + // (inventory panel context menu, in-world object menu). + + if (attach_to_menu_name.empty() || attach_to_hud_menu_name.empty() || !isAgentAvatarValid()) return; + + LLContextMenu* attach_menu = gMenuHolder->getChild<LLContextMenu>(attach_to_menu_name); + LLContextMenu* attach_hud_menu = gMenuHolder->getChild<LLContextMenu>(attach_to_hud_menu_name); + + if (!attach_menu || attach_menu->getChildCount() != 0 || + !attach_hud_menu || attach_hud_menu->getChildCount() != 0) + { + return; + } + + // Populate "Attach to..." / "Attach to HUD..." submenus. + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + LLMenuItemCallGL::Params p; + std::string submenu_name = attachment->getName(); + std::string translated_submenu_name; + + if (LLTrans::findString(translated_submenu_name, submenu_name)) + { + p.name = (" ") + translated_submenu_name + " "; + } + else + { + p.name = submenu_name; + } + + LLSD cbparams; + cbparams["index"] = curiter->first; + cbparams["label"] = attachment->getName(); + p.on_click.function_name = "Object.Attach"; + p.on_click.parameter = LLSD(attachment->getName()); + p.on_enable.function_name = "Attachment.Label"; + p.on_enable.parameter = cbparams; + + LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(p); + LLView* parent_menu = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu; + parent_menu->addChild(item); + } +} + +// static +void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::string& joint_name) +{ + LLViewerJointAttachment* attachmentp = NULL; + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getName() == joint_name) + { + attachmentp = attachment; + break; + } + } + if (attachmentp == NULL) + { + return; + } + + for (uuid_vec_t::const_iterator it = items.begin(); it != items.end(); ++it) + { + const LLUUID &id = *it; + LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id); + if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + rez_attachment(item, attachmentp); + } + else if(item && item->isFinished()) + { + // must be in library. copy it to our inventory and put it on. + LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + } +} diff --git a/indra/newview/llviewerattachmenu.h b/indra/newview/llviewerattachmenu.h new file mode 100644 index 0000000000..d1db9914f3 --- /dev/null +++ b/indra/newview/llviewerattachmenu.h @@ -0,0 +1,43 @@ +/** + * @file llviewerattachmenu.h + * @brief "Attach to" / "Attach to HUD" submenus. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLVIEWERATTACHMENU_H +#define LL_LLVIEWERATTACHMENU_H + +class LLViewerAttachMenu +{ +public: + static void populateMenus(const std::string& attach_to_menu_name, const std::string& attach_to_hud_menu_name); + static void attachObjects(const uuid_vec_t& items, const std::string& joint_name); +}; + +#endif // LL_LLVIEWERATTACHMENU_H diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 706ec88d3b..7ba54b5069 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -39,6 +39,7 @@ #include "llagent.h" #include "llagentcamera.h" +#include "llagentwearables.h" #include "llviewerfoldertype.h" #include "llfolderview.h" #include "llviewercontrol.h" @@ -119,10 +120,10 @@ public: mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow"); //female - mInventoryItemsDict["FeMale - Excuse me"] = LLTrans::getString("FeMale - Excuse me"); - mInventoryItemsDict["FeMale - Get lost"] = LLTrans::getString("FeMale - Get lost"); - mInventoryItemsDict["FeMale - Blow kiss"] = LLTrans::getString("FeMale - Blow kiss"); - mInventoryItemsDict["FeMale - Boo"] = LLTrans::getString("FeMale - Boo"); + mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me"); + mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); + mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss"); + mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo"); mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored"); mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey"); mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh"); @@ -606,6 +607,7 @@ bool LLViewerInventoryCategory::fetch() if((VERSION_UNKNOWN == mVersion) && mDescendentsRequested.hasExpired()) //Expired check prevents multiple downloads. { + LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL; const F32 FETCH_TIMER_EXPIRY = 10.0f; mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); @@ -880,6 +882,14 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item) void ModifiedCOFCallback::fire(const LLUUID& inv_item) { LLAppearanceMgr::instance().updateAppearanceFromCOF(); + + if (LLSideTray::getInstance()->isPanelActive("sidepanel_appearance")) + { + // *HACK: Edit the wearable that has just been worn + // only if the Appearance SP is currently opened. + LLAgentWearables::editWearable(inv_item); + } + // TODO: camera mode may not be changed if a debug setting is tweaked if( gAgentCamera.cameraCustomizeAvatar() ) { @@ -1240,10 +1250,8 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons LLWearableType::EType wearable_type = LLWearableType::typeNameToType(type_name); if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT) { - LLAssetType::EType asset_type = LLWearableType::getAssetType(wearable_type); - LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type); - const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(folder_type); - LLFolderBridge::createWearable(parent_id, wearable_type); + const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null; + LLAgentWearables::createWearable(wearable_type, false, parent_id); } else { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ced5093106..23e12d4896 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2404,18 +2404,14 @@ void handle_object_touch() msg->sendMessage(object->getRegion()->getHost()); } -bool enable_object_touch() -{ - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - return obj && obj->flagHandleTouch(); -} - // One object must have touch sensor class LLObjectEnableTouch : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = enable_object_touch(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + + bool new_value = obj && obj->flagHandleTouch(); // Update label based on the node touch name if available. std::string touch_text; @@ -7659,6 +7655,30 @@ void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y) LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y); } +void initialize_edit_menu() +{ + view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo"); + view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo"); + view_listener_t::addMenu(new LLEditCut(), "Edit.Cut"); + view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy"); + view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste"); + view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete"); + view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll"); + view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect"); + view_listener_t::addMenu(new LLEditDuplicate(), "Edit.Duplicate"); + view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff"); + view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo"); + view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo"); + view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut"); + view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy"); + view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste"); + view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete"); + view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll"); + view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect"); + view_listener_t::addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate"); + +} + void initialize_menus() { // A parameterized event handler used as ctrl-8/9/0 zoom controls below. @@ -7685,7 +7705,6 @@ void initialize_menus() // Generic enable and visible // Don't prepend MenuName.Foo because these can be used in any menu. enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service)); - enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service)); view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); @@ -7696,27 +7715,6 @@ void initialize_menus() // File menu init_menu_file(); - // Edit menu - view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo"); - view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo"); - view_listener_t::addMenu(new LLEditCut(), "Edit.Cut"); - view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy"); - view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste"); - view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete"); - view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll"); - view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect"); - view_listener_t::addMenu(new LLEditDuplicate(), "Edit.Duplicate"); - view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff"); - - view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo"); - view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo"); - view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut"); - view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy"); - view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste"); - view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete"); - view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll"); - view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect"); - view_listener_t::addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate"); view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff"); view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar"); view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape"); @@ -8003,7 +8001,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend"); enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2)); - enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2)); // Object pie menu view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); @@ -8025,7 +8022,6 @@ void initialize_menus() commit.add("Object.Open", boost::bind(&handle_object_open)); commit.add("Object.Take", boost::bind(&handle_take)); enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); - enable.add("Object.EnableTouch", boost::bind(&enable_object_touch)); view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); view_listener_t::addMenu(new LLObjectEnableSitOrStand(), "Object.EnableSitOrStand"); enable.add("Object.EnableDelete", boost::bind(&enable_object_delete)); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index d72ea00077..ad88fcea9a 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -44,6 +44,7 @@ class LLParcelSelection; class LLObjectSelection; class LLSelectNode; +void initialize_edit_menu(); void init_menus(); void cleanup_menus(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 0f9ef7c281..dc458418d0 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -73,6 +73,7 @@ #include "llmoveview.h" #include "llnotificationsutil.h" #include "llquantize.h" +#include "llrand.h" #include "llregionhandle.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -2784,43 +2785,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - BOOL new_name = FALSE; - if (visible_chat != mVisibleChat) - { - mVisibleChat = visible_chat; - new_name = TRUE; - } - - if (sRenderGroupTitles != mRenderGroupTitles) - { - mRenderGroupTitles = sRenderGroupTitles; - new_name = TRUE; - } - - // First Calculate Alpha - // If alpha > 0, create mNameText if necessary, otherwise delete it - F32 alpha = 0.f; - if (mAppAngle > 5.f) - { - const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; - if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) + BOOL new_name = FALSE; + if (visible_chat != mVisibleChat) { - alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; + mVisibleChat = visible_chat; + new_name = TRUE; } - else + + if (sRenderGroupTitles != mRenderGroupTitles) { - // ...not fading, full alpha - alpha = 1.f; + mRenderGroupTitles = sRenderGroupTitles; + new_name = TRUE; } - } - else if (mAppAngle > 2.f) - { - // far away is faded out also - alpha = (mAppAngle-2.f)/3.f; - } + + // First Calculate Alpha + // If alpha > 0, create mNameText if necessary, otherwise delete it + F32 alpha = 0.f; + if (mAppAngle > 5.f) + { + const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; + if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) + { + alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; + } + else + { + // ...not fading, full alpha + alpha = 1.f; + } + } + else if (mAppAngle > 2.f) + { + // far away is faded out also + alpha = (mAppAngle-2.f)/3.f; + } if (alpha <= 0.f) - { + { if (mNameText) { mNameText->markDead(); @@ -2830,19 +2831,19 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - if (!mNameText) - { + if (!mNameText) + { mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject( LLHUDObject::LL_HUD_NAME_TAG) ); //mNameText->setMass(10.f); - mNameText->setSourceObject(this); + mNameText->setSourceObject(this); mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); - mNameText->setVisibleOffScreen(TRUE); - mNameText->setMaxLines(11); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - sNumVisibleChatBubbles++; - new_name = TRUE; - } + mNameText->setVisibleOffScreen(TRUE); + mNameText->setMaxLines(11); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + sNumVisibleChatBubbles++; + new_name = TRUE; + } LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); mNameText->setPositionAgent(name_position); @@ -2853,10 +2854,10 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) -{ - LLNameValue *title = getNVPair("Title"); - LLNameValue* firstname = getNVPair("FirstName"); - LLNameValue* lastname = getNVPair("LastName"); + { + LLNameValue *title = getNVPair("Title"); + LLNameValue* firstname = getNVPair("FirstName"); + LLNameValue* lastname = getNVPair("LastName"); // Avatars must have a first and last name if (!firstname || !lastname) return; @@ -2870,34 +2871,34 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) is_muted = false; } else - { + { is_muted = LLMuteList::getInstance()->isMuted(getID()); } bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); bool is_cloud = getIsCloud(); - - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - if (is_appearance != mNameAppearance) - { - if (is_appearance) - { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; - } - else + + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; + if (is_appearance != mNameAppearance) + { + if (is_appearance) + { + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); + args["NAME"] = getFullname(); + LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); + llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; + } + else + { + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); + args["NAME"] = getFullname(); + LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); + llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; + } + } } - } - } // Rebuild name tag if state change detected if (mNameString.empty() @@ -2907,39 +2908,39 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) || is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute - || is_appearance != mNameAppearance + || is_appearance != mNameAppearance || is_friend != mNameFriend || is_cloud != mNameCloud) - { + { LLColor4 name_tag_color = getNameTagColor(is_friend); clearNameTag(); if (is_away || is_muted || is_busy || is_appearance) - { + { std::string line; - if (is_away) - { - line += LLTrans::getString("AvatarAway"); + if (is_away) + { + line += LLTrans::getString("AvatarAway"); line += ", "; - } - if (is_busy) - { + } + if (is_busy) + { line += LLTrans::getString("AvatarBusy"); line += ", "; } if (is_muted) - { + { line += LLTrans::getString("AvatarMuted"); - line += ", "; - } + line += ", "; + } if (is_appearance) { line += LLTrans::getString("AvatarEditingAppearance"); line += ", "; - } + } if (is_cloud) - { + { line += LLTrans::getString("LoadingData"); line += ", "; } @@ -2953,14 +2954,14 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) if (sRenderGroupTitles && title && title->getString() && title->getString()[0] != '\0') - { + { LLColor4 group_color = LLUIColorTable::getInstance()->getColor("NameTagGroup"); std::string title_str = title->getString(); LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); addNameTagLine(title_str, group_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerifSmall()); - } + } static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames"); static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); @@ -2974,52 +2975,52 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // and force a rebuild LLAvatarNameCache::get(getID(), boost::bind(&LLVOAvatar::clearNameTag, this)); - } + } // Might be blank if name not available yet, that's OK if (show_display_names) { addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerif()); - } + } // Suppress SLID display if display name matches exactly (ugh) if (show_usernames && !av_name.mIsDisplayNameDefault) - { + { // *HACK: Desaturate the color LLColor4 username_color = name_tag_color * 0.83f; addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerifSmall()); } - } + } else - { + { const LLFontGL* font = LLFontGL::getFontSansSerif(); std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); - } + } - mNameAway = is_away; - mNameBusy = is_busy; - mNameMute = is_muted; - mNameAppearance = is_appearance; + mNameAway = is_away; + mNameBusy = is_busy; + mNameMute = is_muted; + mNameAppearance = is_appearance; mNameFriend = is_friend; - mNameCloud = is_cloud; - mTitle = title ? title->getString() : ""; - LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); - new_name = TRUE; - } + mNameCloud = is_cloud; + mTitle = title ? title->getString() : ""; + LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); + new_name = TRUE; + } if (mVisibleChat) - { - mNameText->setFont(LLFontGL::getFontSansSerif()); + { + mNameText->setFont(LLFontGL::getFontSansSerif()); mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - char line[MAX_STRING]; /* Flawfinder: ignore */ - line[0] = '\0'; - std::deque<LLChat>::iterator chat_iter = mChats.begin(); - mNameText->clearString(); + char line[MAX_STRING]; /* Flawfinder: ignore */ + line[0] = '\0'; + std::deque<LLChat>::iterator chat_iter = mChats.begin(); + mNameText->clearString(); LLColor4 new_chat = LLUIColorTable::instance().getColor( "NameTagChat" ); LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); @@ -3085,8 +3086,8 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) { // ...not using chat bubbles, just names mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - mNameText->setVisibleOffScreen(FALSE); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + mNameText->setVisibleOffScreen(FALSE); } } @@ -3109,8 +3110,8 @@ void LLVOAvatar::clearNameTag() { mNameString.clear(); if (mNameText) - { - mNameText->setLabel(""); + { + mNameText->setLabel(""); mNameText->setString( "" ); } } @@ -3138,8 +3139,8 @@ void LLVOAvatar::invalidateNameTags() if (avatar->isDead()) continue; avatar->clearNameTag(); - } -} + } + } // Compute name tag position during idle update LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) @@ -3163,7 +3164,7 @@ LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) (projected_vec(local_camera_at * root_rot, camera_to_av)); name_position += pixel_up_vec * 15.f; return name_position; - } + } void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) { @@ -3198,7 +3199,7 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) else { color_name = "NameTagMismatch"; - } + } } else { @@ -6638,16 +6639,13 @@ LLColor4 LLVOAvatar::getDummyColor() void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const { - /* const char* te_name[] = { - "TEX_HEAD_BODYPAINT ", - "TEX_UPPER_SHIRT ", */ llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl; for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); ++iter) { const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; - // TODO: handle multiple textures for self + // TODO: MULTI-WEARABLE: handle multiple textures for self const LLViewerTexture* te_image = getImage(iter->first,0); if( !te_image ) { @@ -6827,6 +6825,41 @@ void LLVOAvatar::onFirstTEMessageReceived() } //----------------------------------------------------------------------------- +// bool visualParamWeightsAreDefault() +//----------------------------------------------------------------------------- +bool LLVOAvatar::visualParamWeightsAreDefault() +{ + bool rtn = true; + + bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT); + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + { + LLViewerVisualParam* vparam = dynamic_cast<LLViewerVisualParam*>(param); + llassert(vparam); + bool is_skirt_param = vparam && + LLWearableType::WT_SKIRT == vparam->getWearableType(); + if (param->getWeight() != param->getDefaultWeight() && + // we have to not care whether skirt weights are default, if we're not actually wearing a skirt + (is_wearing_skirt || !is_skirt_param)) + { + //llinfos << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << llendl; + rtn = false; + break; + } + } + } + + //llinfos << "params are default ? " << int(rtn) << llendl; + + return rtn; +} + + +//----------------------------------------------------------------------------- // processAvatarAppearance() //----------------------------------------------------------------------------- void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) @@ -6895,15 +6928,16 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) releaseComponentTextures(); } - // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); - if( num_blocks > 1 ) + bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing + if( num_blocks > 1 && !drop_visual_params_debug) { BOOL params_changed = FALSE; BOOL interp_params = FALSE; LLVisualParam* param = getFirstVisualParam(); + llassert(param); // if this ever fires, we should do the same as when num_blocks<=1 if (!param) { llwarns << "No visual params!" << llendl; @@ -6919,8 +6953,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if( !param ) { - llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; - return; + // more visual params supplied than expected - just process what we know about + break; } U8 value; @@ -6945,14 +6979,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } } - while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) + const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); + if (num_blocks != expected_tweakable_count) { - param = getNextVisualParam(); - } - if( param ) - { - llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; - return; + llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl; } if (params_changed) @@ -6969,16 +6999,37 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) updateSexDependentLayerSets( FALSE ); } } + + llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); } else { - llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + // AvatarAppearance message arrived without visual params + if (drop_visual_params_debug) + { + llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl; + } + else + { + llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + } + + // this isn't really a problem if we already have a non-default shape + if (visualParamWeightsAreDefault()) + { + // re-request appearance, hoping that it comes back with a shape next time + llinfos << "Re-requesting AvatarAppearance for object: " << getID() << llendl; + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); + } + else + { + llinfos << "That's okay, we already have a non-default shape for object: " << getID() << llendl; + // we don't really care. + } } setCompositeUpdatesEnabled( TRUE ); - llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); - // If all of the avatars are completely baked, release the global image caches to conserve memory. LLVOAvatar::cullAvatarsByPixelArea(); @@ -8000,6 +8051,8 @@ void LLVOAvatar::idleUpdateRenderCost() static const U32 ARC_BODY_PART_COST = 20; static const U32 ARC_LIMIT = 2048; + static std::set<LLUUID> all_textures; + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) { return; @@ -8045,7 +8098,45 @@ void LLVOAvatar::idleUpdateRenderCost() } } } + // Diagnostic output to identify all avatar-related textures. + // Does not affect rendering cost calculation. + // Could be wrapped in a debug option if output becomes problematic. + if (isSelf()) + { + // print any attachment textures we didn't already know about. + for (std::set<LLUUID>::iterator it = textures.begin(); it != textures.end(); ++it) + { + LLUUID image_id = *it; + if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + continue; + if (all_textures.find(image_id) == all_textures.end()) + { + // attachment texture not previously seen. + llinfos << "attachment_texture: " << image_id.asString() << llendl; + all_textures.insert(image_id); + } + } + // print any avatar textures we didn't already know about + for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); + iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + ++iter) + { + const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + // TODO: MULTI-WEARABLE: handle multiple textures for self + const LLViewerTexture* te_image = getImage(iter->first,0); + if (!te_image) + continue; + LLUUID image_id = te_image->getID(); + if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + continue; + if (all_textures.find(image_id) == all_textures.end()) + { + llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; + all_textures.insert(image_id); + } + } + } cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; setDebugText(llformat("%d", cost)); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 25a9d5c5f1..384ab88816 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -258,6 +258,7 @@ public: //-------------------------------------------------------------------- public: BOOL isFullyLoaded() const; + bool visualParamWeightsAreDefault(); protected: virtual BOOL getIsCloud(); BOOL updateIsFullyLoaded(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index ce8f64404e..462c442954 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1328,6 +1328,15 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const return TRUE; } +BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const +{ + const LLTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet; + if (!layerset) return FALSE; + const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); + if (!layerset_buffer) return FALSE; + return !layerset_buffer->uploadPending(); +} + BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const { LLUUID id; diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index e461dc07da..55b4fd87c8 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -177,6 +177,7 @@ public: bool areTexturesCurrent() const; BOOL isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const; BOOL isLocalTextureDataFinal(const LLTexLayerSet* layerset) const; + BOOL isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const; // If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index /*virtual*/ BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const; /*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 161cd40cfc..c35b45d446 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -41,6 +41,7 @@ #include "llinventorymodel.h" #include "llmenugl.h" // for LLContextMenu #include "lltransutil.h" +#include "llviewerattachmenu.h" class LLFindOutfitItems : public LLInventoryCollectFunctor { @@ -94,6 +95,47 @@ LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item) ////////////////////////////////////////////////////////////////////////// // static +LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryItem* item) +{ + LLPanelWearableOutfitItem* list_item = NULL; + if (item) + { + list_item = new LLPanelWearableOutfitItem(item); + list_item->init(); + } + return list_item; +} + +BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLUUID id = item->getUUID(); + + if (get_is_item_worn(id)) + { + LLAppearanceMgr::getInstance()->removeItemFromAvatar(id); + } + else + { + LLAppearanceMgr::getInstance()->wearItemOnAvatar(id, true, false); + } + } + + return LLUICtrl::handleDoubleClick(x, y, mask); +} + +LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item) +: LLPanelInventoryListItemBase(item) +{ +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +// static LLPanelClothingListItem* LLPanelClothingListItem::create(LLViewerInventoryItem* item) { LLPanelClothingListItem* list_item = NULL; @@ -402,6 +444,27 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) LLWearableItemsList::~LLWearableItemsList() {} +// virtual +void LLWearableItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/) +{ + if (!item) + { + llwarns << "No inventory item. Couldn't create flat list item." << llendl; + llassert(item != NULL); + } + + LLPanelWearableOutfitItem *list_item = LLPanelWearableOutfitItem::create(item); + if (!list_item) + return; + + bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange); + if (!is_item_added) + { + llwarns << "Couldn't add flat list item." << llendl; + llassert(is_item_added); + } +} + void LLWearableItemsList::updateList(const LLUUID& category_id) { LLInventoryModel::cat_array_t cat_array; @@ -449,7 +512,9 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() // Register handlers common for all wearable types. registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids)); registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids)); + registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id)); registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); + registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids)); // Register handlers for clothing. registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids)); @@ -459,12 +524,16 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() // Register handlers for attachments. registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids)); registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id)); + registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2)); // Create the menu. LLContextMenu* menu = createFromFile("menu_wearable_list_item.xml"); // Determine which items should be visible/enabled. updateItemsVisibility(menu); + + // Update labels for the items requiring that. + updateItemsLabels(menu); return menu; } @@ -478,10 +547,10 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu const uuid_vec_t& ids = mUUIDs; // selected items IDs U32 mask = 0; // mask of selected items' types - U32 nitems = ids.size(); // number of selected items - U32 nworn = 0; // number of worn items among the selected ones - U32 nwornlinks = 0; // number of worn links among the selected items - U32 neditable = 0; // number of editable items among the selected ones + U32 n_items = ids.size(); // number of selected items + U32 n_worn = 0; // number of worn items among the selected ones + U32 n_links = 0; // number of links among the selected items + U32 n_editable = 0; // number of editable items among the selected ones for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -503,38 +572,82 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu if (is_worn) { - ++nworn; - - if (is_link) - { - ++nwornlinks; - } + ++n_worn; } if (is_editable) { - ++neditable; + ++n_editable; + } + if (is_link) + { + ++n_links; } } // for // *TODO: eliminate multiple traversals over the menu items - // *TODO: try disabling items rather than hiding them - // *FIX: we may hide *all* items and thus get an ugly empty menu - setMenuItemVisible(menu, "wear", nworn == 0); - setMenuItemVisible(menu, "edit", mask & (MASK_CLOTHING|MASK_BODYPART) && nitems == 1 && neditable == 1); - setMenuItemVisible(menu, "show_original", nitems == 1 && nwornlinks == nitems); - setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && nworn == nitems); // selected only worn clothes - setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && nworn == nitems); - setMenuItemVisible(menu, "object_profile", mask == MASK_ATTACHMENT && nitems == 1); + setMenuItemVisible(menu, "wear", n_worn == 0); + setMenuItemVisible(menu, "edit", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); + setMenuItemEnabled(menu, "edit", n_editable == 1 && n_worn == 1); + setMenuItemVisible(menu, "create_new", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); + setMenuItemEnabled(menu, "show_original", n_items == 1 && n_links == n_items); + setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && n_worn == n_items); + setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && n_worn == n_items); + setMenuItemVisible(menu, "take_off_or_detach", mask == (MASK_ATTACHMENT|MASK_CLOTHING)); + setMenuItemEnabled(menu, "take_off_or_detach", n_worn == n_items); + setMenuItemVisible(menu, "object_profile", mask & (MASK_ATTACHMENT|MASK_CLOTHING)); + setMenuItemEnabled(menu, "object_profile", n_items == 1); + + // Populate or hide the "Attach to..." / "Attach to HUD..." submenus. + if (mask == MASK_ATTACHMENT && n_worn == 0) + { + LLViewerAttachMenu::populateMenus("wearable_attach_to", "wearable_attach_to_hud"); + } + else + { + setMenuItemVisible(menu, "wearable_attach_to", false); + setMenuItemVisible(menu, "wearable_attach_to_hud", false); + } + + if (mask & MASK_UNKNOWN) + { + llwarns << "Non-wearable items passed." << llendl; + } +} + +void LLWearableItemsList::ContextMenu::updateItemsLabels(LLContextMenu* menu) +{ + llassert(menu); + if (!menu) return; + + // Set proper label for the "Create new <WEARABLE_TYPE>" menu item. + LLViewerInventoryItem* item = gInventory.getLinkedItem(mUUIDs.back()); + if (!item || !item->isWearableType()) return; + + LLStringUtil::format_map_t args; + LLWearableType::EType w_type = item->getWearableType(); + args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type); + std::string new_label = LLTrans::getString("CreateNewWearable", args); + + LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); + menu_item->setLabel(new_label); } // We need this method to convert non-zero BOOL values to exactly 1 (TRUE). // Otherwise code relying on a BOOL value being TRUE may fail // (I experienced a weird assert in LLView::drawChildren() because of that. +// static void LLWearableItemsList::ContextMenu::setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val) { menu->setItemVisible(name, val); } +// static +void LLWearableItemsList::ContextMenu::setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val) +{ + menu->setItemEnabled(name, val); +} + +// static void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType at) { if (at == LLAssetType::AT_CLOTHING) @@ -551,8 +664,17 @@ void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType } else { - llwarns << "Unsupported asset type: " << at << llendl; + mask |= MASK_UNKNOWN; } } +// static +void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id) +{ + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item || !item->isWearableType()) return; + + LLAgentWearables::createWearable(item->getWearableType(), true); +} + // EOF diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index de024ed220..0ed480a92a 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -70,6 +70,29 @@ protected: LLPanelWearableListItem(LLViewerInventoryItem* item); }; +/** + * @class LLPanelWearableOutfitItem + * + * Outfit item for "My Outfits" list. + * Extends LLPanelInventoryListItemBase with handling + * double click to wear the item. + */ +class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase +{ + LOG_CLASS(LLPanelWearableOutfitItem); +public: + static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item); + + /** + * Puts item on if it is not worn by agent + * otherwise takes it off on double click. + */ + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + +protected: + + LLPanelWearableOutfitItem(LLViewerInventoryItem* item); +}; class LLPanelDeletableWearableListItem : public LLPanelWearableListItem { @@ -292,12 +315,16 @@ public: MASK_CLOTHING = 0x01, MASK_BODYPART = 0x02, MASK_ATTACHMENT = 0x04, + MASK_UNKNOWN = 0x08, }; /* virtual */ LLContextMenu* createMenu(); void updateItemsVisibility(LLContextMenu* menu); - void setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val); - void updateMask(U32& mask, LLAssetType::EType at); + void updateItemsLabels(LLContextMenu* menu); + static void setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val); + static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val); + static void updateMask(U32& mask, LLAssetType::EType at); + static void createNewWearable(const LLUUID& item_id); }; struct Params : public LLInitParam::Block<Params, LLInventoryItemsList::Params> @@ -309,6 +336,8 @@ public: virtual ~LLWearableItemsList(); + /*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); + void updateList(const LLUUID& category_id); protected: diff --git a/indra/newview/skins/default/textures/icons/Inv_LostClosed.png b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png Binary files differnew file mode 100644 index 0000000000..a800217e0d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png Binary files differnew file mode 100644 index 0000000000..8c4a1a9ac0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png Binary files differnew file mode 100644 index 0000000000..dcf998449f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png Binary files differnew file mode 100644 index 0000000000..0efd403c95 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png Binary files differnew file mode 100644 index 0000000000..c5201e6f9a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png Binary files differnew file mode 100644 index 0000000000..4a886a3f37 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_off.png b/indra/newview/skins/default/textures/icons/back_arrow_off.png Binary files differnew file mode 100644 index 0000000000..422f67cf83 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/back_arrow_off.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_over.png b/indra/newview/skins/default/textures/icons/back_arrow_over.png Binary files differnew file mode 100644 index 0000000000..b4cc170f37 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/back_arrow_over.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_press.png b/indra/newview/skins/default/textures/icons/back_arrow_press.png Binary files differnew file mode 100644 index 0000000000..a9e2f326a7 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/back_arrow_press.png diff --git a/indra/newview/skins/default/textures/locked_image.j2c b/indra/newview/skins/default/textures/locked_image.j2c Binary files differnew file mode 100644 index 0000000000..9e8998d675 --- /dev/null +++ b/indra/newview/skins/default/textures/locked_image.j2c diff --git a/indra/newview/skins/default/textures/map_infohub.tga b/indra/newview/skins/default/textures/map_infohub.tga Binary files differnew file mode 100644 index 0000000000..545b8e532c --- /dev/null +++ b/indra/newview/skins/default/textures/map_infohub.tga diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index d6ea860e2e..b3314aa32f 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -68,6 +68,10 @@ with the same filename but different name <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" /> + <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" /> + <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" /> + <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" /> + <texture name="Blank" file_name="Blank.png" preload="false" /> @@ -144,8 +148,6 @@ with the same filename but different name <texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" /> <texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" /> - <texture name="Health" file_name="icons/Health.png" preload="false" /> - <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" /> <texture name="Hierarchy_View_Disabled" file_name="icons/Hierarchy_View_Disabled.png" preload="false" /> @@ -203,6 +205,8 @@ with the same filename but different name <texture name="Inv_Jacket" file_name="icons/Inv_Jacket.png" preload="false" /> <texture name="Inv_LookFolderOpen" file_name="icons/Inv_LookFolderOpen.png" preload="false" /> <texture name="Inv_LookFolderClosed" file_name="icons/Inv_LookFolderClosed.png" preload="false" /> + <texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" /> + <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" /> <texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" /> <texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" /> <texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" /> @@ -216,8 +220,12 @@ with the same filename but different name <texture name="Inv_Snapshot" file_name="icons/Inv_Snapshot.png" preload="false" /> <texture name="Inv_Socks" file_name="icons/Inv_Socks.png" preload="false" /> <texture name="Inv_Sound" file_name="icons/Inv_Sound.png" preload="false" /> + <texture name="Inv_SysClosed" file_name="icons/Inv_SysClosed.png" preload="false" /> + <texture name="Inv_SysOpen" file_name="icons/Inv_SysOpen.png" preload="false" /> <texture name="Inv_Tattoo" file_name="icons/Inv_Tattoo.png" preload="false" /> <texture name="Inv_Texture" file_name="icons/Inv_Texture.png" preload="false" /> + <texture name="Inv_TrashClosed" file_name="icons/Inv_TrashClosed.png" preload="false" /> + <texture name="Inv_TrashOpen" file_name="icons/Inv_TrashOpen.png" preload="false" /> <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" /> <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" /> @@ -232,7 +240,6 @@ with the same filename but different name <texture name="Inv_Gesture_Link" file_name="icons/Inv_Gesture_Link.png" preload="false" /> <texture name="Inv_Gloves_Link" file_name="icons/Inv_Gloves_Link.png" preload="false" /> <texture name="Inv_Hair_Link" file_name="icons/Inv_Hair_Link.png" preload="false" /> - <texture name="Inv_LinkItem_Link" file_name="icons/Inv_LinkItem_Link.png" preload="false" /> <texture name="Inv_LinkFolder_Link" file_name="icons/Inv_LinkFolder_Link.png" preload="false" /> <texture name="Inv_Jacket_Link" file_name="icons/Inv_Jacket_Link.png" preload="false" /> <texture name="Inv_LookFolderOpen_Link" file_name="icons/Inv_LookFolderOpen_Link.png" preload="false" /> @@ -626,7 +633,7 @@ with the same filename but different name <texture name="icon_avatar_online.tga" /> <texture name="icon_day_cycle.tga" /> <texture name="icon_diurnal.tga" /> - <texture name="icon_for_sale.tga" /> + <texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" /> <texture name="icon_top_pick.tga" /> <texture name="lag_status_critical.tga" /> diff --git a/indra/newview/skins/default/xui/da/floater_world_map.xml b/indra/newview/skins/default/xui/da/floater_world_map.xml index 898d291f1c..4dec9a9ba7 100644 --- a/indra/newview/skins/default/xui/da/floater_world_map.xml +++ b/indra/newview/skins/default/xui/da/floater_world_map.xml @@ -35,7 +35,7 @@ <text name="pg_label"> Generelt </text> - <check_box initial_value="sandt" name="event_mature_chk"/> + <check_box name="event_mature_chk"/> <text name="mature_label"> Moderat </text> diff --git a/indra/newview/skins/default/xui/da/panel_preferences_setup.xml b/indra/newview/skins/default/xui/da/panel_preferences_setup.xml index 8202c78947..38bc9c0a2a 100644 --- a/indra/newview/skins/default/xui/da/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/da/panel_preferences_setup.xml @@ -37,10 +37,10 @@ <radio_item label="Benyt min browser(IE, Firefox, Safari)" name="external" tool_tip="Brug systemets standard web browser til hjælp, web links, m.v. Ikke anbefalet hvis du kører i fuld-skærm." value="1"/> <radio_item label="Benyt den indbyggede browser" name="internal" tool_tip="Brug den indbyggede web browser til hjælp, web links m.v. Denne browser åbner et nyt vindue i [APP_NAME]." value=""/> </radio_group> - <check_box initial_value="sand" label="Aktivér plugins" name="browser_plugins_enabled"/> - <check_box initial_value="sand" label="Acceptér cookies" name="cookies_enabled"/> - <check_box initial_value="sand" label="Aktivér Javascript" name="browser_javascript_enabled"/> - <check_box initial_value="false" label="Aktivér web proxy" name="web_proxy_enabled"/> + <check_box label="Aktivér plugins" name="browser_plugins_enabled"/> + <check_box label="Acceptér cookies" name="cookies_enabled"/> + <check_box label="Aktivér Javascript" name="browser_javascript_enabled"/> + <check_box label="Aktivér web proxy" name="web_proxy_enabled"/> <text name="Proxy location"> Proxy placering: </text> diff --git a/indra/newview/skins/default/xui/da/panel_preferences_sound.xml b/indra/newview/skins/default/xui/da/panel_preferences_sound.xml index 856f978ebd..a1b47c3c1f 100644 --- a/indra/newview/skins/default/xui/da/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/da/panel_preferences_sound.xml @@ -11,8 +11,8 @@ <check_box label="Aktiveret" name="enable_media"/> <slider label="Stemme chat" name="Voice Volume"/> <check_box label="Aktiveret" name="enable_voice_check"/> - <check_box label="Tillad media at afspilles automatisk" name="media_auto_play_btn" tool_tip="Vælg dette for at media afspille automatisk hvis det ønsker det" value="sandt"/> - <check_box label="Afspil media vedhæftet andre avatarer" name="media_show_on_others_btn" tool_tip="Deaktiver dette for at skjule vedhæftet media for avatarer i nærheden" value="sandt"/> + <check_box label="Tillad media at afspilles automatisk" name="media_auto_play_btn" tool_tip="Vælg dette for at media afspille automatisk hvis det ønsker det" /> + <check_box label="Afspil media vedhæftet andre avatarer" name="media_show_on_others_btn" tool_tip="Deaktiver dette for at skjule vedhæftet media for avatarer i nærheden" /> <text name="voice_chat_settings"> Stemme chat opsætning </text> diff --git a/indra/newview/skins/default/xui/de/floater_preview_gesture.xml b/indra/newview/skins/default/xui/de/floater_preview_gesture.xml index 1426a33d1d..48b1f1170c 100644 --- a/indra/newview/skins/default/xui/de/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/de/floater_preview_gesture.xml @@ -7,7 +7,7 @@ Sound abspielen: </floater.string> <floater.string name="step_chat"> - Chat sprechen: + Im Chat anzeigen: </floater.string> <floater.string name="step_wait"> Warten: diff --git a/indra/newview/skins/default/xui/de/floater_world_map.xml b/indra/newview/skins/default/xui/de/floater_world_map.xml index a1f41f53ad..fb3a4ba9b5 100644 --- a/indra/newview/skins/default/xui/de/floater_world_map.xml +++ b/indra/newview/skins/default/xui/de/floater_world_map.xml @@ -39,7 +39,7 @@ <text name="pg_label"> Generell </text> - <check_box initial_value="wahr" label="Mature" name="event_mature_chk"/> + <check_box label="Mature" name="event_mature_chk"/> <text name="mature_label"> Moderat </text> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_sound.xml b/indra/newview/skins/default/xui/de/panel_preferences_sound.xml index 96a86ed85d..44b2bd1f60 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_sound.xml @@ -11,8 +11,8 @@ <check_box label="Aktiviert" name="enable_media"/> <slider label="Voice-Chat" name="Voice Volume"/> <check_box label="Aktiviert" name="enable_voice_check"/> - <check_box label="Automatische Wiedergabe zulassen" name="media_auto_play_btn" tool_tip="Hier aktivieren, um Medien automatisch wiederzugeben." value="wahr"/> - <check_box label="Medien, die an andere Avatare angehängt sind, wiedergeben." name="media_show_on_others_btn" tool_tip="Diese Option deaktivieren, um Medien für andere Avataren, die sich in der Nähe befinden, auszublenden." value="wahr"/> + <check_box label="Automatische Wiedergabe zulassen" name="media_auto_play_btn" tool_tip="Hier aktivieren, um Medien automatisch wiederzugeben."/> + <check_box label="Medien, die an andere Avatare angehängt sind, wiedergeben." name="media_show_on_others_btn" tool_tip="Diese Option deaktivieren, um Medien für andere Avataren, die sich in der Nähe befinden, auszublenden."/> <text name="voice_chat_settings"> Voice-Chat-Einstellungen </text> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 3bc78e8a12..914268a9d2 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -757,7 +757,7 @@ Leyla Linden </text> mouse_opaque="false" name="resellable_clause" word_wrap="true" - width="330"> + width="360"> Land in this region may not be resold. </text> <text diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 249b091800..a0e28f7a42 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -5,7 +5,7 @@ can_minimize="true" can_resize="true" follows="top|right" - height="218" + height="174" layout="topleft" min_height="174" min_width="174" diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index b2e4a7ad95..d8410a26dd 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -64,8 +64,7 @@ left="0" mouse_opaque="false" name="world_stack" - orientation="vertical" - tab_stop="false"> + orientation="vertical"> <panel auto_resize="true" follows="all" height="500" @@ -156,13 +155,6 @@ top="0" width="1024" height="768"/> - <notify_box_view top="0" - follows="all" - height="768" - mouse_opaque="false" - name="notify_container" - tab_group="-2" - width="1024"/> <panel top="0" follows="all" mouse_opaque="false" diff --git a/indra/newview/skins/default/xui/en/menu_bottomtray.xml b/indra/newview/skins/default/xui/en/menu_bottomtray.xml index ccd5388621..5beafef4e4 100644 --- a/indra/newview/skins/default/xui/en/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/menu_bottomtray.xml @@ -53,17 +53,6 @@ parameter="ShowSnapshotButton" /> </menu_item_check> <menu_item_check - label="Sidebar button" - layout="topleft" - name="ShowSidebarButton"> - <menu_item_check.on_click - function="ToggleControl" - parameter="ShowSidebarButton" /> - <menu_item_check.on_check - function="CheckControl" - parameter="ShowSidebarButton" /> - </menu_item_check> - <menu_item_check label="Build button" layout="topleft" name="ShowBuildButton"> diff --git a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml index b422d87938..c402100fb1 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml @@ -10,12 +10,4 @@ function="Attachment.Detach" parameter="detach"/> </menu_item_call> - <context_menu - label="Attach to" - layout="topleft" - name="attach_to" /> - <context_menu - label="Attach to HUD" - layout="topleft" - name="attach_to_hud" /> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml index 01008ef203..f0e8461360 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml @@ -19,4 +19,15 @@ function="BodyPart.OnEnable" parameter="edit" /> </menu_item_call> + <menu_item_call + label="Create New" + layout="topleft" + name="create_new" + translate="false"> + <on_click + function="BodyPart.Create"/> + <on_enable + function="BodyPart.OnEnable" + parameter="create" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml index f9cb29f0d7..12ee9b045b 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml @@ -8,6 +8,9 @@ name="take_off"> <on_click function="Clothing.TakeOff" /> + <on_enable + function="Clothing.OnEnable" + parameter="take_off" /> </menu_item_call> <menu_item_call label="Move Up a Layer" @@ -39,4 +42,15 @@ function="Clothing.OnEnable" parameter="edit" /> </menu_item_call> + <menu_item_call + label="Create New" + layout="topleft" + name="create_new" + translate="false"> + <on_click + function="Clothing.Create"/> + <on_enable + function="Clothing.OnEnable" + parameter="create" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml index 982d4f2015..c2a11a64ec 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml @@ -2,15 +2,12 @@ <menu layout="topleft" name="Gear COF"> - <menu_item_call - label="Add To Outfit" + <menu + label="New Clothes" layout="topleft" - name="add"> - <on_click - function="Gear.OnClick" - parameter="add"/> - <on_enable - function="Gear.OnEnable" - parameter="add" /> - </menu_item_call> + name="COF.Gear.New_Clothes" /> + <menu + label="New Body Parts" + layout="topleft" + name="COF.Geear.New_Body_Parts" /> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index dfc72b557c..b5eda8e999 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -7,31 +7,174 @@ layout="topleft" name="wear"> <on_click - function="Gear.OnClick" - parameter="wear"/> + function="Gear.Wear" /> <on_enable function="Gear.OnEnable" parameter="wear" /> </menu_item_call> <menu_item_call - label="Take Off - Remove Current Outfit" + label="Take Off - Remove from Current Outfit" layout="topleft" name="take_off"> <on_click - function="Gear.OnClick" - parameter="take_off"/> + function="Gear.TakeOff" /> <on_enable function="Gear.OnEnable" parameter="take_off" /> </menu_item_call> + + <menu_item_separator /> + <!-- copied (with minor modifications) from menu_inventory_add.xml --> + <!-- *TODO: generate dynamically? --> + <menu + height="175" + label="New Clothes" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="New Clothes" + top_pad="514" + width="125"> + <menu_item_call + label="New Shirt" + layout="topleft" + name="New Shirt"> + <menu_item_call.on_click + function="Gear.Create" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + label="New Pants" + layout="topleft" + name="New Pants"> + <menu_item_call.on_click + function="Gear.Create" + parameter="pants" /> + </menu_item_call> + <menu_item_call + label="New Shoes" + layout="topleft" + name="New Shoes"> + <menu_item_call.on_click + function="Gear.Create" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + label="New Socks" + layout="topleft" + name="New Socks"> + <menu_item_call.on_click + function="Gear.Create" + parameter="socks" /> + </menu_item_call> + <menu_item_call + label="New Jacket" + layout="topleft" + name="New Jacket"> + <menu_item_call.on_click + function="Gear.Create" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + label="New Skirt" + layout="topleft" + name="New Skirt"> + <menu_item_call.on_click + function="Gear.Create" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + label="New Gloves" + layout="topleft" + name="New Gloves"> + <menu_item_call.on_click + function="Gear.Create" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + label="New Undershirt" + layout="topleft" + name="New Undershirt"> + <menu_item_call.on_click + function="Gear.Create" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + label="New Underpants" + layout="topleft" + name="New Underpants"> + <menu_item_call.on_click + function="Gear.Create" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + label="New Alpha" + layout="topleft" + name="New Alpha"> + <menu_item_call.on_click + function="Gear.Create" + parameter="alpha" /> + </menu_item_call> + <menu_item_call + label="New Tattoo" + layout="topleft" + name="New Tattoo"> + <menu_item_call.on_click + function="Gear.Create" + parameter="tattoo" /> + </menu_item_call> + </menu> + <menu + height="85" + label="New Body Parts" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="New Body Parts" + top_pad="514" + width="118"> + <menu_item_call + label="New Shape" + layout="topleft" + name="New Shape"> + <menu_item_call.on_click + function="Gear.Create" + parameter="shape" /> + </menu_item_call> + <menu_item_call + label="New Skin" + layout="topleft" + name="New Skin"> + <menu_item_call.on_click + function="Gear.Create" + parameter="skin" /> + </menu_item_call> + <menu_item_call + label="New Hair" + layout="topleft" + name="New Hair"> + <menu_item_call.on_click + function="Gear.Create" + parameter="hair" /> + </menu_item_call> + <menu_item_call + label="New Eyes" + layout="topleft" + name="New Eyes"> + <menu_item_call.on_click + function="Gear.Create" + parameter="eyes" /> + </menu_item_call> + </menu> + <!-- copied from menu_inventory_add.xml --> + <menu_item_separator /> <menu_item_call label="Rename" layout="topleft" name="rename"> <on_click - function="Gear.OnClick" - parameter="rename"/> + function="Gear.Rename" /> <on_enable function="Gear.OnEnable" parameter="rename" /> @@ -41,10 +184,9 @@ layout="topleft" name="delete_outfit"> <on_click - function="Gear.OnClick" - parameter="delete_outfit"/> + function="Gear.Delete" /> <on_enable function="Gear.OnEnable" - parameter="delete_outfit" /> + parameter="delete" /> </menu_item_call> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml index 8f3e62157a..67559638d9 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml @@ -8,6 +8,9 @@ name="wear_replace"> <on_click function="Outfit.WearReplace" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_replace" /> </menu_item_call> <menu_item_call label="Wear - Add to Current Outfit" @@ -15,13 +18,29 @@ name="wear_add"> <on_click function="Outfit.WearAdd" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_add" /> </menu_item_call> <menu_item_call - label="Take Off - Remove Current Outfit" + label="Take Off - Remove from Current Outfit" layout="topleft" name="take_off"> <on_click function="Outfit.TakeOff" /> + <on_enable + function="Outfit.OnEnable" + parameter="take_off" /> + </menu_item_call> + <menu_item_call + label="Edit Outfit" + layout="topleft" + name="edit"> + <on_click + function="Outfit.Edit" /> + <on_enable + function="Outfit.OnEnable" + parameter="edit" /> </menu_item_call> <menu_item_separator /> <menu_item_call @@ -30,6 +49,9 @@ name="rename"> <on_click function="Outfit.Rename" /> + <on_enable + function="Outfit.OnEnable" + parameter="rename" /> </menu_item_call> <menu_item_call label="Delete Outfit" @@ -37,5 +59,8 @@ name="delete"> <on_click function="Outfit.Delete" /> + <on_enable + function="Outfit.OnEnable" + parameter="delete" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index 7ea7eaade5..e645702f93 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -9,22 +9,27 @@ function="Wearable.Wear" /> </menu_item_call> <menu_item_call + label="Take Off / Detach" + layout="topleft" + name="take_off_or_detach"> + <on_click + function="Wearable.TakeOffDetach" /> + </menu_item_call> + <menu_item_call label="Detach" layout="topleft" name="detach"> <on_click function="Attachment.Detach" /> </menu_item_call> -<!-- *TODO: implement the submenus - <menu - label="Attach to" + <context_menu + label="Attach to ▶" layout="topleft" - name="attach_to" /> - <menu - label="Attach to HUD" + name="wearable_attach_to" /> + <context_menu + label="Attach to HUD ▶" layout="topleft" - name="attach_to_hud" /> ---> + name="wearable_attach_to_hud" /> <menu_item_call label="Object Profile" layout="topleft" @@ -37,16 +42,14 @@ layout="topleft" name="take_off"> <on_click - function="Clothing.TakeOff" - parameter="take_off"/> + function="Clothing.TakeOff" /> </menu_item_call> <menu_item_call label="Edit" layout="topleft" name="edit"> <on_click - function="Wearable.Edit" - parameter="edit"/> + function="Wearable.Edit" /> </menu_item_call> <menu_item_call label="Show Original" @@ -55,4 +58,12 @@ <on_click function="Wearable.ShowOriginal" /> </menu_item_call> + <menu_item_call + label="Create New" + layout="topleft" + name="create_new" + translate="false"> + <on_click + function="Wearable.CreateNew" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c7eb90dbff..08302432ad 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1090,7 +1090,9 @@ The region [REGION] does not allow terraforming. icon="alertmodal.tga" name="CannotCopyWarning" type="alertmodal"> -You do not have permission to copy this item and will lose it from your inventory if you give it away. Do you really want to offer this item? +You do not have permission to copy the following items: +[ITEMS] +and will lose it from your inventory if you give it away. Do you really want to offer these items? <usetemplate name="okcancelbuttons" notext="No" @@ -2054,6 +2056,28 @@ Would you be my friend? <notification icon="alertmodal.tga" + label="Rename Outfit" + name="RenameOutfit" + type="alertmodal"> + New outfit name: + <form name="form"> + <input name="new_name" type="text"> + [NAME] + </input> + <button + default="true" + index="0" + name="Offer" + text="OK"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification + icon="alertmodal.tga" name="RemoveFromFriends" type="alertmodal"> Do you want to remove [NAME] from your Friends List? @@ -6197,6 +6221,28 @@ Drag items from inventory onto a person in the resident picker </notification> <notification icon="notifytip.tga" + name="ShareItemsConfirmation" + type="alertmodal"> +Are you sure you want to share the following items: + +[ITEMS] + +With the following Residents: + +[RESIDENTS] + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="Ok"/> + </notification> + <notification + icon="notifytip.tga" + name="ItemsShared" + type="notifytip"> +Items are successfully shared. + </notification> + <notification + icon="notifytip.tga" name="DeedToGroupFail" type="notifytip"> Deed to group failed. @@ -6340,8 +6386,8 @@ Mute everyone? <usetemplate ignoretext="Confirm before I mute all participants in a group call" name="okcancelignore" - notext="Ok" - yestext="Cancel"/> + yestext="Ok" + notext="Cancel"/> <unique/> </notification> diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml index d3f6695375..1e6a31d388 100644 --- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml @@ -11,14 +11,16 @@ width="280"> <button follows="top|left" - height="25" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back" - left="10" + left="4" tab_stop="false" - top="0" - width="25"/> + top="1" + width="30"/> <text follows="top|left|right" font="SansSerifLargeBold" diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index ac61c7da5d..82b2405ec9 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -222,38 +222,6 @@ min_height="28" min_width="52" mouse_opaque="false" - name="sidebar_btn_panel" - user_resize="false" - width="83"> -<!--*TODO: Implement toggle of sidebar with buttons -Disabled for now. ---> - <button - control_name="SidebarWithButtonsVisibility" - follows="left|right" - height="23" - image_pressed="PushButton_Press" - image_pressed_selected="PushButton_Selected_Press" - image_selected="PushButton_Selected_Press" - is_toggle="true" - label="Sidebar" - layout="topleft" - left="0" - name="sidebar_btn" - tool_tip="Shows/hides Sidebar" - top="5" - use_ellipses="true" - width="80"> - </button> - </layout_panel> - <layout_panel - auto_resize="false" - follows="left|right" - height="28" - layout="topleft" - min_height="28" - min_width="52" - mouse_opaque="false" name="build_btn_panel" user_resize="false" width="83"> diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index e3b331799c..859cc82e81 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -40,15 +40,17 @@ </panel.string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" picture_style="true" - left="11" + left="9" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index cf84c31078..5f34c24bca 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -9,6 +9,7 @@ name="cof_wearables" width="311"> <accordion + fit_parent="true" follows="all" height="200" layout="topleft" @@ -38,73 +39,31 @@ layout="topleft" name="tab_clothing" title="Clothing"> - - <!-- *NOTE there should be no any gaps between the button bar and the list - - accordiong-list adaptor won't employ them while calculating new height when the size of the list changes --> - <panel - background_visible="false" - class="accordion_list_adaptor" + <flat_list_view + allow_select="true" follows="all" - height="45" + height="10" layout="topleft" left="0" - name="button_bar_adaptor" + multi_select="true" + name="list_clothing" top="0" - width="311"> - <panel - bevel="none" - filename="panel_clothing_list_button_bar.xml" - height="35" - name="button_bar" - top="0" - width="311" /> - <flat_list_view - allow_select="true" - follows="all" - height="10" - layout="topleft" - left="0" - multi_select="true" - name="list_clothing" - top_pad="0" - width="311" /> - </panel> + width="311" /> </accordion_tab> <accordion_tab layout="topleft" name="tab_body_parts" title="Body Parts"> - - <!-- *NOTE there should be no any gaps between the button bar and the list - - accordiong-list adaptor won't employ them while calculating new height when the size of the list changes --> - <panel - background_visible="false" - class="accordion_list_adaptor" + <flat_list_view + allow_select="true" follows="all" - height="45" + height="10" layout="topleft" left="0" - name="button_bar_adaptor" + multi_select="true" + name="list_body_parts" top="0" - width="311"> - <panel - bevel="none" - filename="panel_bodyparts_list_button_bar.xml" - height="35" - name="button_bar" - top="0" - width="311"/> - <flat_list_view - allow_select="true" - follows="all" - height="10" - layout="topleft" - left="0" - multi_select="true" - name="list_body_parts" - top_pad="0" - width="311" /> - </panel> + width="311" /> </accordion_tab> </accordion> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index 62a364473c..1b4f547f9d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -24,15 +24,17 @@ </string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" picture_style="true" - left="12" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text type="string" length="1" @@ -218,12 +220,12 @@ value="Content type:" width="250" /> <icons_combo_box - follows="left|top" - height="23" + follows="left|top" + height="23" label="General Content" layout="topleft" left="10" - name="content_type" + name="content_type" top_pad="5" width="156"> <icons_combo_box.drop_down_button @@ -233,8 +235,8 @@ pad_left="3"/> <icons_combo_box.item label="Moderate Content" - name="mature_ci" - value="Mature"> + name="mature_ci" + value="Mature"> <item.columns halign="center" type="icon" @@ -243,8 +245,8 @@ </icons_combo_box.item> <icons_combo_box.item label="General Content" - name="pg_ci" - value="PG"> + name="pg_ci" + value="PG"> <item.columns halign="center" type="icon" diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml index 4149a0b06f..f173a2f3cb 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml @@ -51,6 +51,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml index 94fd2f9080..a490f27b9f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml index 9b60e83387..6bb5d2fa9b 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml @@ -51,6 +51,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml index 248ae9fe04..929cdffb3d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml @@ -80,6 +80,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml index 3ed1df2399..f22cf983aa 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 08ee0306dd..589ea10e8d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -18,14 +18,16 @@ </panel.string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" - left="12" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml index e088aa05ac..85823073b5 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml index e079047a86..b26fde68f1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml index 9158685c40..45591ba2ad 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml @@ -85,6 +85,7 @@ width="313"> <accordion layout="topleft" + fit_parent="true" follows="all" height ="300" left="0" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml index 87f3270b31..bb8e0dca07 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml index 5bd99969a2..d813d94d93 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_socks.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml index bbe5230341..19225e9757 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml index a79c1b9eaa..720a55dcc2 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 0455086ef3..67ff71cef1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -132,12 +132,14 @@ left="0" </string> <button follows="top|left" - height="25" - width="25" - image_overlay="BackArrow_Off" + height="24" + width="30" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" - left="10" + left="11" top="7" /> <text follows="top|left" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 789d69bc68..58b78cfa02 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -36,14 +36,16 @@ background_visible="true" layout="topleft"> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back" - left="8" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text_editor allow_scroll="false" bg_visible="false" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 31ba539c44..25674a1a39 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -55,15 +55,17 @@ value="Parcel_R_Dark" /> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="11" + left="8" name="back_btn" tool_tip="Back" tab_stop="false" top="4" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 0f97301856..48b021efcf 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -86,7 +86,6 @@ top="20" </text> <line_editor follows="left|bottom" -handle_edit_keys_directly="true" height="22" max_length="16" name="password_edit" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index abd96c89e7..76e5e20498 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -52,30 +52,19 @@ <string name="Filter.Clothes/Body" value="Clothes/Body"/> <string name="Filter.Objects" value="Objects"/> - <!-- - TODO remove this button. Added it temporary for QA to be able to test new edit wearable - panel (see EXT-6564) - --> - <button - follows="left|top|right" - height="20" - label="edit" - left="0" - top="0" - layout="topleft" - name="edit_wearable_btn" - width="40" /> <button follows="top|left" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" left="5" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|right" font="SansSerifHugeBold" @@ -150,8 +139,8 @@ <!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) --> -<!-- *NOTE: border_size is used to calculate space between layout panel and for resize bar height -required height for dragbar is 10, so resizebar height should be 10 px. +<!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height. +Required height for dragbar (icon in spec) is 10, so resizebar height should be 10 px. It is calculated as border_size + 2*UIResizeBarOverlap --> <layout_stack @@ -160,7 +149,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap clip="false" default_tab_group="2" follows="all" - height="468" + height="465" width="313" layout="topleft" orientation="vertical" @@ -170,7 +159,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap left="5"> <layout_panel layout="topleft" - height="193" + height="187" label="IM Control Panel" min_height="100" name="outfit_wearables_panel" @@ -178,94 +167,89 @@ It is calculated as border_size + 2*UIResizeBarOverlap auto_resize="true" user_resize="true"> + <layout_stack + animate="true" + border_size="0" + follows="all" + height="185" + width="313" + layout="topleft" + name="filter_panels" + top="0" + left="0"> + <layout_panel + auto_resize="true" + background_visible="true" + bg_alpha_color="DkGray2" + layout="topleft" + height="154" + label="add_button_and_combobox" + name="add_button_and_combobox" + width="311" + user_resize="false" + visible="true"> + <!-- List containing items from the COF and Base outfit --> <panel background_visible="false" class="cof_wearables" filename="panel_cof_wearables.xml" - follows="left|top|right|bottom" - height="193" + follows="all" + height="129" layout="topleft" left="1" name="cof_wearables_list" top="0" width="311" /> - </layout_panel> + <button + follows="left|bottom" + height="22" + is_toggle="true" + label="Add More..." + layout="topleft" + left="2" + name="show_add_wearables_btn" + top_pad="2" + width="125" /> - <layout_panel - background_visible="true" - bg_alpha_color="DkGray2" - auto_resize="true" - default_tab_group="3" - height="184" - min_height="210" - name="add_wearables_panel" - width="313" - tab_group="2" - user_resize="true" - visible="false"> - <icon - follows="left|top|right" - height="10" - image_name="Dragbar" - left="0" - top_pad="-9" - width="313" /> - <text - follows="top|left|right" - font="SansSerifBold" - height="13" + <combo_box + follows="left|right|bottom" + height="22" layout="topleft" - left="5" - name="add_to_outfit_label" - text_color="LtGray" - top="4" - value="Add to Outfit:" - use_ellipses="true" - width="150" /> + left_pad="5" + name="filter_wearables_combobox" + top_delta="0" + visible="false" + width="152"/> + <button - follows="top|right" - height="20" + follows="bottom|right" + height="22" image_overlay="Search_Icon" is_toggle="true" layout="topleft" - left_pad="5" name="filter_button" + right="-5" top_delta="0" + visible="false" width="20" /> - <combo_box - follows="top|left|right" - height="20" - layout="topleft" - right="-5" - name="filter_wearables_combobox" - top_delta="0" - width="110"/> + </layout_panel> - <layout_stack - animate="true" - follows="all" - height="155" - width="313" - layout="topleft" - name="filter_panels" - top_pad="5" - left="0"> <layout_panel auto_resize="false" - layout="topleft" - follows="left|top|right" + background_visible="true" + bg_alpha_color="DkGray2" height="30" - label="IM Control Panel" name="filter_panel" width="311" - user_resize="false" - visible="false"> + visible="false" + user_resize="false"> + <filter_editor background_image="TextField_Search_Off" enabled="true" - follows="left|top|right" + follows="left|right|top" font="SansSerif" label="Filter" layout="topleft" @@ -276,22 +260,41 @@ It is calculated as border_size + 2*UIResizeBarOverlap text_color="black" text_pad_left="25" visible="true"/> + + </layout_panel> + </layout_stack> </layout_panel> + + <layout_panel + background_visible="true" + bg_alpha_color="DkGray2" auto_resize="true" - background_visible="true" - bg_alpha_color="0.107 0.107 0.107 1" - height="145" - min_width="130" - name="inventory_panel" - width="311" - user_resize="true"> + default_tab_group="3" + height="211" + min_height="210" + name="add_wearables_panel" + width="313" + tab_group="2" + user_resize="true" + visible="false"> + + <!-- this icon represent dragbar between layout panels. + This is a workaround implemented in EXT-7255 becouse of an issue with layout stack (EXT-7471) --> + <icon + follows="left|top|right" + height="10" + image_name="Dragbar" + left="0" + top_pad="-9" + width="313" /> + <inventory_panel allow_multi_select="true" background_visible="false" border="false" follows="left|top|right|bottom" - height="140" + height="210" layout="topleft" left="0" mouse_opaque="false" @@ -306,7 +309,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap layout="topleft" follows="left|top|right|bottom" border="false" - height="140" + height="210" left="0" mouse_opaque="false" width="311" @@ -320,16 +323,51 @@ It is calculated as border_size + 2*UIResizeBarOverlap follows="all" multi_select="true" width="310" - height="140" + height="210" left="0" top="0"/> </panel> - </layout_panel> - </layout_stack> + </layout_panel> </layout_stack> - <!-- Button bar --> + + <!-- BUTTON BAR --> + <panel + background_visible="true" + bevel_style="none" + follows="bottom|left|right" + height="27" + label="bottom_panel" + layout="topleft" + left="5" + name="no_add_wearables_button_bar" + top_pad="0" + width="313"> + <button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left="0" + name="gear_menu_btn" + top="1" + width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="281" /> + </panel> + + + <!-- BUTTON BAR - WEARABLES ADDING MODE --> <panel background_visible="true" bevel_style="none" @@ -337,9 +375,10 @@ It is calculated as border_size + 2*UIResizeBarOverlap height="27" label="add_wearables_button_bar" layout="topleft" - left="4" + left="5" name="add_wearables_button_bar" - top_pad="0" + top_delta="0" + visible="false" width="313"> <button follows="bottom|left" @@ -365,7 +404,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="1" name="folder_view_btn" top="1" - visible="false" width="31" /> <button follows="bottom|left" @@ -379,7 +417,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="1" name="list_view_btn" top="1" - visible="false" width="31" /> <button follows="bottom|left" @@ -393,7 +430,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="1" name="add_to_outfit_btn" top="1" - visible="false" width="31" /> <icon follows="bottom|left|right" @@ -401,23 +437,12 @@ It is calculated as border_size + 2*UIResizeBarOverlap image_name="Toolbar_Right_Off" layout="topleft" left_pad="1" - name="add_wearables_dummy_icon" - top="1" - visible="false" + name="dummy_right_icon" width="184" > </icon> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left="32" - name="dummy_right_icon" - top="1" - width="281" > - </icon> </panel> + <!-- SAVE AND REVERT BUTTONS --> <panel follows="left|right|bottom" height="30" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index ecf5516390..49e1d16f6a 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -12,14 +12,16 @@ width="333"> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" - left="12" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 9725e9952a..57ac79686d 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -140,15 +140,17 @@ value="Parcel_DamageNo_Dark" /> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="11" + left="7" name="back_btn" tool_tip="Back" tab_stop="false" top="4" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" @@ -318,6 +320,7 @@ value="unknown" width="268" /> <accordion + fit_parent="true" follows="all" height="223" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 73882fea4d..7d9bd1bf2a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -98,7 +98,7 @@ Automatic position for: control_name="SidebarCameraMovement" follows="left|top" height="16" - initial_value="1" + initial_value="true" label="Sidebar" layout="topleft" name="appearance_sidebar_positioning" @@ -126,7 +126,7 @@ Automatic position for: name="first_person_avatar_visible" width="256" /> -<check_box + <check_box control_name="ArrowKeysAlwaysMove" follows="left|top" height="20" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index c43784a6f8..ead5ff8ae4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -256,10 +256,10 @@ name="show_my_name_checkbox1" top_pad="4" width="300" /> - <check_box + <check_box control_name="NameTagShowFriends" - enabled_control="AvatarNameTagMode" - height="16" + enabled_control="AvatarNameTagMode" + height="16" label="Highlight friends" left_delta="0" name="show_friends" @@ -268,7 +268,7 @@ <text follows="left|top" height="15" - layout="topleft" + layout="topleft" left="250" name="name_tags_textbox" top="175" @@ -392,7 +392,6 @@ text_readonly_color="LabelDisabledColor" bg_writeable_color="LtGray" use_ellipses="false" - hover="false" commit_on_focus_lost = "true" follows="left|top" height="42" diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index aca778193a..d6d6fa4975 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -18,14 +18,16 @@ </string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back" - left="12" + left="9" tab_stop="false" top="2" - width="23" /> + width="30" /> <text_editor h_pad="0" v_pad="0" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 713aaa21a9..8d19ab15b1 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -40,14 +40,16 @@ width="18" /> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="14" + left="12" name="back_btn" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 0f7dc47401..e038e104d3 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -58,14 +58,16 @@ </panel.string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="10" + left="8" name="back_btn" tab_stop="false" top="0" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHuge" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 695c6d0793..5f1d4e6ca6 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -87,9 +87,9 @@ <!-- tooltips for Urls --> <string name="TooltipHttpUrl">Click to view this web page</string> <string name="TooltipSLURL">Click to view this location's information</string> - <string name="TooltipAgentUrl">Click to view this Resident's profile</string> + <string name="TooltipAgentUrl">Click to view this Resident's profile</string> <string name="TooltipAgentInspect">Learn more about this Resident</string> - <string name="TooltipAgentMute">Click to mute this Resident</string> + <string name="TooltipAgentMute">Click to mute this Resident</string> <string name="TooltipAgentUnmute">Click to unmute this Resident</string> <string name="TooltipAgentIM">Click to IM this Resident</string> <string name="TooltipAgentPay">Click to Pay this Resident</string> @@ -103,7 +103,7 @@ <string name="TooltipObjectIMUrl">Click to view this object's description</string> <string name="TooltipMapUrl">Click to view this location on a map</string> <string name="TooltipSLAPP">Click to run the secondlife:// command</string> - <string name="CurrentURL" value=" CurrentURL: [CurrentURL]" /> + <string name="CurrentURL" value=" CurrentURL: [CurrentURL]" /> <string name="TooltipPrice" value=" L$[PRICE]-" /> @@ -122,7 +122,7 @@ <!-- ButtonToolTips, llfloater.cpp --> <string name="BUTTON_CLOSE_DARWIN">Close (⌘W)</string> <string name="BUTTON_CLOSE_WIN">Close (Ctrl+W)</string> - <string name="BUTTON_CLOSE_CHROME">Close</string>> + <string name="BUTTON_CLOSE_CHROME">Close</string> <string name="BUTTON_RESTORE">Restore</string> <string name="BUTTON_MINIMIZE">Minimize</string> <string name="BUTTON_TEAR_OFF">Tear Off</string> @@ -319,6 +319,10 @@ <!-- For use when we do not have land type back from the server --> <string name="land_type_unknown">(unknown)</string> + <!-- For land type back from the simulator --> + <string name="Estate / Full Region">Estate / Full Region</string> + <string name="Mainland / Full Region">Mainland / Full Region</string> + <!-- File load/save dialogs --> <string name="all_files">All Files</string> <string name="sound_files">Sounds</string> @@ -1827,6 +1831,7 @@ Clears (deletes) the media and all params from the given face. <!-- Wearable List--> <string name="NewWearable">New [WEARABLE_ITEM]</string> + <string name="CreateNewWearable">Create [WEARABLE_TYPE]</string> <!-- LLGroupNotify --> <!-- used in the construction of a Group Notice blue dialog box, buttons, tooltip etc. Seems to be no longer utilized by code in Viewer 2.0 --> @@ -3081,10 +3086,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. </string> <string name="unread_chat_single"> [SOURCES] has said something new - </string>" + </string> <string name="unread_chat_multiple"> [SOURCES] have said something new - </string>" + </string> <string name="session_initialization_timed_out_error"> The session initialization is timed out </string> @@ -3104,7 +3109,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="to join a group">to join a group</string> <string name="to upload">to upload</string> <string name="to publish a classified ad">to publish a classified ad</string> - + <string name="giving">Giving L$ [AMOUNT]</string> <string name="uploading_costs">Uploading costs L$ [AMOUNT]</string> <string name="this_costs">This costs L$ [AMOUNT]</string> @@ -3158,10 +3163,10 @@ Abuse Report</string> <string name="Male - Stick tougue out">Male - Stick tougue out</string> <string name="Male - Wow">Male - Wow</string> - <string name="FeMale - Excuse me">FeMale - Excuse me</string> - <string name="FeMale - Get lost">FeMale - Get lost</string> - <string name="FeMale - Blow kiss">FeMale - Blow kiss</string> - <string name="FeMale - Boo">FeMale - Boo</string> + <string name="Female - Excuse me">Female - Excuse me</string> + <string name="Female - Get lost">Female - Get lost</string> + <string name="Female - Blow kiss">Female - Blow kiss</string> + <string name="Female - Boo">Female - Boo</string> <string name="Female - Bored">Female - Bored</string> <string name="Female - Hey">Female - Hey</string> <string name="Female - Laugh">Female - Laugh</string> @@ -3178,6 +3183,7 @@ Abuse Report</string> <!-- language specific white-space characters, delimiters, spacers, item separation symbols --> <string name="sentences_separator" value=" "></string> + <string name="words_separator">, </string> <string name="server_is_down"> Despite our best efforts, something unexpected has gone wrong. diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index 6dcc27b469..2d0a1728d5 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -2,12 +2,12 @@ <!-- Additional attributes: image_pressed image_pressed_selected + image_flash --> <button image_unselected="PushButton_Off" image_selected="PushButton_Selected" image_disabled_selected="PushButton_Selected_Disabled" image_disabled="PushButton_Disabled" - image_flash="FlashIconAbsent" image_top_pad="0" image_bottom_pad="0" imgoverlay_label_space="1" diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 30b0a8462a..c37ead0be2 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -11,31 +11,28 @@ label_pad_left - padding to the left of tab button labels tab_height="21" label_pad_bottom="2" label_pad_left="4"> + <!-- + Possible additional attributes for tabs: + tab_bottom_image_flash + tab_left_image_flash + tab_top_image_flash + --> <first_tab tab_top_image_unselected="TabTop_Left_Off" tab_top_image_selected="TabTop_Left_Selected" - tab_top_image_flash="FlashIconAbsent" tab_bottom_image_unselected="Toolbar_Left_Off" tab_bottom_image_selected="Toolbar_Left_Selected" - tab_bottom_image_flash="FlashIconAbsent" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_left_image_flash="FlashIconAbsent"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <middle_tab tab_top_image_unselected="TabTop_Middle_Off" tab_top_image_selected="TabTop_Middle_Selected" - tab_top_image_flash="FlashIconAbsent" tab_bottom_image_unselected="Toolbar_Middle_Off" tab_bottom_image_selected="Toolbar_Middle_Selected" - tab_bottom_image_flash="FlashIconAbsent" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_left_image_flash="FlashIconAbsent"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <last_tab tab_top_image_unselected="TabTop_Right_Off" tab_top_image_selected="TabTop_Right_Selected" - tab_top_image_flash="FlashIconAbsent" tab_bottom_image_unselected="Toolbar_Right_Off" tab_bottom_image_selected="Toolbar_Right_Selected" - tab_bottom_image_flash="FlashIconAbsent" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_left_image_flash="FlashIconAbsent"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> </tab_container> diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml index 998ec5b170..3006df22b8 100644 --- a/indra/newview/skins/default/xui/en/widgets/text.xml +++ b/indra/newview/skins/default/xui/en/widgets/text.xml @@ -6,7 +6,6 @@ font_shadow="none" tab_stop="false" halign="left" - hover_color="LabelSelectedColor" h_pad="0" allow_scroll="false" text_readonly_color="LabelDisabledColor" @@ -14,7 +13,6 @@ use_ellipses="false" bg_visible="false" border_visible="false" - hover="false" sound_flags="0" text_color="LabelTextColor" v_pad="0" diff --git a/indra/newview/skins/default/xui/es/floater_world_map.xml b/indra/newview/skins/default/xui/es/floater_world_map.xml index c3a13980de..deda5b86c8 100644 --- a/indra/newview/skins/default/xui/es/floater_world_map.xml +++ b/indra/newview/skins/default/xui/es/floater_world_map.xml @@ -35,7 +35,7 @@ <text name="pg_label"> General </text> - <check_box initial_value="verdadero" name="event_mature_chk"/> + <check_box name="event_mature_chk"/> <text name="mature_label"> Moderado </text> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml index c3a23c74c4..6e6d0be81f 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml @@ -13,7 +13,7 @@ </text> <check_box label="Construir/Editar" name="edit_camera_movement" tool_tip="Usar el posicionamiento automático de la cámara al entrar en o salir del modo de edición"/> <check_box label="Apariencia" name="appearance_camera_movement" tool_tip="Usar el posicionamiento automático de la cámara mientras se está editando"/> - <check_box initial_value="1" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar el posicionamiento automático de la cámara para la barra lateral"/> + <check_box label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar el posicionamiento automático de la cámara para la barra lateral"/> <check_box label="Verme en vista subjetiva" name="first_person_avatar_visible"/> <check_box label="Las teclas del cursor siempre para moverme" name="arrow_keys_move_avatar_check"/> <check_box label="Correr siempre: atajo de teclado" name="tap_tap_hold_to_run"/> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml index fe9736f758..88f5ba42b5 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml @@ -37,10 +37,10 @@ <radio_item label="Usar mi navegador (IE, Firefox, Safari)" name="external" tool_tip="Usa tu navegador por defecto para ayuda, enlaces web, etc. No es aconsejable si estás a pantalla completa." value="1"/> <radio_item label="Usar el navegador incorporado" name="internal" tool_tip="Usa el navegador incorporado para ayuda, enlaces web, etc. Este navegador se abre en una nueva ventana dentro de [APP_NAME]." value=""/> </radio_group> - <check_box initial_value="verdadero" label="Activar plugins" name="browser_plugins_enabled"/> - <check_box initial_value="verdadero" label="Aceptar las 'cookies'" name="cookies_enabled"/> - <check_box initial_value="verdadero" label="Activar Javascript" name="browser_javascript_enabled"/> - <check_box initial_value="false" label="Activar web proxy" name="web_proxy_enabled"/> + <check_box label="Activar plugins" name="browser_plugins_enabled"/> + <check_box label="Aceptar las 'cookies'" name="cookies_enabled"/> + <check_box label="Activar Javascript" name="browser_javascript_enabled"/> + <check_box label="Activar web proxy" name="web_proxy_enabled"/> <text name="Proxy location"> Localización del proxy: </text> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_sound.xml b/indra/newview/skins/default/xui/es/panel_preferences_sound.xml index 1e8b0c736c..2d3c76d215 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_sound.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Sonidos" name="Preference Media panel"> <slider label="Volumen general" name="System Volume"/> - <check_box initial_value="true" label="Silenciar cuando minimice" name="mute_when_minimized"/> + <check_box label="Silenciar cuando minimice" name="mute_when_minimized"/> <slider label="Botones" name="UI Volume"/> <slider label="Ambiental" name="Wind Volume"/> <slider label="Efectos de sonido" name="SFX Volume"/> @@ -11,8 +11,8 @@ <check_box label="Activada" name="enable_media"/> <slider label="Chat de voz" name="Voice Volume"/> <check_box label="Activado" name="enable_voice_check"/> - <check_box label="Permitir la ejecución automática de los media" name="media_auto_play_btn" tool_tip="Marcar esto para permitir la ejecución automática de los media" value="Sí"/> - <check_box label="Ejecutar para otros avatares los media anexados" name="media_show_on_others_btn" tool_tip="Al desmarcar esto se esconderán los media anexados a otros avatares cercanos" value="Sí"/> + <check_box label="Permitir la ejecución automática de los media" name="media_auto_play_btn" tool_tip="Marcar esto para permitir la ejecución automática de los media"/> + <check_box label="Ejecutar para otros avatares los media anexados" name="media_show_on_others_btn" tool_tip="Al desmarcar esto se esconderán los media anexados a otros avatares cercanos"/> <text name="voice_chat_settings"> Configuración del chat de voz </text> diff --git a/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml index afd9001df0..5e7442b877 100644 --- a/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="clothing_list_button_bar_panel"> - <button label="Permuter" name="switch_btn"/> + <button label="Changer" name="switch_btn"/> <button label="Acheter >" name="bodyparts_shop_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml index 24cb92dde7..0b58a4e40b 100644 --- a/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="clothing_list_button_bar_panel"> - <button label="Ajouter +" name="add_btn"/> + <button label="Ajout +" name="add_btn"/> <button label="Acheter >" name="clothing_shop_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml index 9bae9878e2..6b8e68bd98 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml @@ -13,7 +13,7 @@ </text> <check_box label="Construire/Modifier" name="edit_camera_movement" tool_tip="Utilisez le positionnement automatique de la caméra quand vous accédez au mode de modification et quand vous le quittez"/> <check_box label="Apparence" name="appearance_camera_movement" tool_tip="Utiliser le positionnement automatique de la caméra quand je suis en mode Édition"/> - <check_box initial_value="1" label="Panneau latéral" name="appearance_sidebar_positioning" tool_tip="Positionnement auto de la caméra pour le panneau latéral"/> + <check_box label="Panneau latéral" name="appearance_sidebar_positioning" tool_tip="Positionnement auto de la caméra pour le panneau latéral"/> <check_box label="Afficher en vue subjective" name="first_person_avatar_visible"/> <check_box label="Les touches de direction me font toujours me déplacer" name="arrow_keys_move_avatar_check"/> <check_box label="Appuyer deux fois et maintenir enfoncé pour courir" name="tap_tap_hold_to_run"/> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml b/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml index 4c055a2b8d..c9676c898b 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml @@ -11,8 +11,8 @@ <check_box label="Activé" name="enable_media"/> <slider label="Chat vocal" name="Voice Volume"/> <check_box label="Activé" name="enable_voice_check"/> - <check_box label="Autoriser la lecture automatique du média" name="media_auto_play_btn" tool_tip="Cochez pour autoriser la lecture automatique du média" value="vrai"/> - <check_box label="Jouer le média aux autres avatars" name="media_show_on_others_btn" tool_tip="Décochez pour masquer le média aux autres avatars près de vous" value="vrai"/> + <check_box label="Autoriser la lecture automatique du média" name="media_auto_play_btn" tool_tip="Cochez pour autoriser la lecture automatique du média"/> + <check_box label="Jouer le média aux autres avatars" name="media_show_on_others_btn" tool_tip="Décochez pour masquer le média aux autres avatars près de vous"/> <text name="voice_chat_settings"> Paramètres du chat vocal </text> diff --git a/indra/newview/skins/default/xui/fr/panel_region_estate.xml b/indra/newview/skins/default/xui/fr/panel_region_estate.xml index 2c12547d61..fb650ff646 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_estate.xml @@ -73,6 +73,6 @@ domaine. <button label="?" name="ban_resident_help"/> <button label="Ajouter..." name="add_banned_avatar_btn"/> <button label="Supprimer..." name="remove_banned_avatar_btn"/> - <button label="Envoyer un message au domaine..." name="message_estate_btn"/> - <button label="Éjecter un résident du domaine..." name="kick_user_from_estate_btn"/> + <button label="Message au domaine..." name="message_estate_btn"/> + <button label="Éjecter du domaine..." name="kick_user_from_estate_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/it/floater_world_map.xml b/indra/newview/skins/default/xui/it/floater_world_map.xml index 31d7a8df9e..b07daac6fb 100644 --- a/indra/newview/skins/default/xui/it/floater_world_map.xml +++ b/indra/newview/skins/default/xui/it/floater_world_map.xml @@ -35,7 +35,7 @@ <text name="pg_label"> Generale </text> - <check_box initial_value="vero" name="event_mature_chk"/> + <check_box name="event_mature_chk"/> <text name="mature_label"> Moderato </text> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml index cedf93beed..29618485c2 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml @@ -37,10 +37,10 @@ <radio_item label="Usa il mio browser (IE, Firefox, Safari)" name="external" tool_tip="Utilizza il browser Web predefinito di sistema per l'aiuto, per i link Web e così via. Sconsigliato durante l'esecuzione a tutto schermo." value="1"/> <radio_item label="Utilizza il browser Web integrato" name="internal" tool_tip="Utilizza il browser Web integrato per l'aiuto, per i link Web e così via. Questo browser si apre in una nuova finestra in [APP_NAME]." value=""/> </radio_group> - <check_box initial_value="vero" label="Abilita plugin" name="browser_plugins_enabled"/> - <check_box initial_value="vero" label="Accetta cookie" name="cookies_enabled"/> - <check_box initial_value="vero" label="Abilita Javascript" name="browser_javascript_enabled"/> - <check_box initial_value="false" label="Abilita proxy Web" name="web_proxy_enabled"/> + <check_box label="Abilita plugin" name="browser_plugins_enabled"/> + <check_box label="Accetta cookie" name="cookies_enabled"/> + <check_box label="Abilita Javascript" name="browser_javascript_enabled"/> + <check_box label="Abilita proxy Web" name="web_proxy_enabled"/> <text name="Proxy location"> Ubicazione proxy: </text> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_sound.xml b/indra/newview/skins/default/xui/it/panel_preferences_sound.xml index 6936f24a8a..9f8a13fedc 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_sound.xml @@ -11,8 +11,8 @@ <check_box label="Abilitato" name="enable_media"/> <slider label="Chat vocale" name="Voice Volume"/> <check_box label="Abilitato" name="enable_voice_check"/> - <check_box label="Consenti riproduzione multimediale automatica" name="media_auto_play_btn" tool_tip="Seleziona qui per consentire la riproduzione multimediale automatica" value="vero"/> - <check_box label="Riproduci media in uso da altri avatar" name="media_show_on_others_btn" tool_tip="Deseleziona qui per nascondere i media in uso dagli altri avatar nei dintorni" value="vero"/> + <check_box label="Consenti riproduzione multimediale automatica" name="media_auto_play_btn" tool_tip="Seleziona qui per consentire la riproduzione multimediale automatica"/> + <check_box label="Riproduci media in uso da altri avatar" name="media_show_on_others_btn" tool_tip="Deseleziona qui per nascondere i media in uso dagli altri avatar nei dintorni"/> <text name="voice_chat_settings"> Impostazioni Chat vocale </text> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 5d162eb80f..1ac7677b07 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -639,7 +639,7 @@ L$ が不足しているのでこのグループに参加することができ 次のファイルのエンコードができません: [FILE] </notification> <notification name="CorruptedProtectedDataStore"> - あなたの保護されたデータを読みとることが出来ないためリセットされます。 + 保護されているデータを読みとることが出来ないためリセットされます。 ネットワーク設定を変更すると起こることがあります。 <usetemplate name="okbutton" yestext="OK"/> </notification> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml index 94ee5c6ff4..732a5df75f 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml @@ -13,7 +13,7 @@ </text> <check_box label="制作・編集" name="edit_camera_movement" tool_tip="編集モードのオン・オフの切り替えに、自動カメラポジションを使います"/> <check_box label="容姿" name="appearance_camera_movement" tool_tip="編集モードに入ったときに、自動カメラポジションを使います"/> - <check_box initial_value="1" label="サイドバー" name="appearance_sidebar_positioning" tool_tip="サイドバーの切り替え時に自動カメラポジションを使います"/> + <check_box label="サイドバー" name="appearance_sidebar_positioning" tool_tip="サイドバーの切り替え時に自動カメラポジションを使います"/> <check_box label="一人称視点で表示する" name="first_person_avatar_visible"/> <check_box label="常にキー操作で動くようにする" name="arrow_keys_move_avatar_check"/> <check_box label="上矢印キー2度押し+長押しで走る" name="tap_tap_hold_to_run"/> diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml index e4908deb07..163868f200 100644 --- a/indra/newview/skins/default/xui/pl/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml @@ -196,13 +196,13 @@ Idź do Świat > O Posiadłości albo wybierz inną posiadłość żeby pokaz <text name="resellable_lbl"> Odsprzedaj: </text> - <text left="115" name="resellable_clause" width="338"> + <text left="115" name="resellable_clause"> Posiadłość zakupiona w tym Regionie nie może być odsprzedana. </text> <text name="changeable_lbl"> Podziel: </text> - <text left="115" name="changeable_clause" width="338"> + <text left="115" name="changeable_clause"> Posiadłość zakupiona w tym Regionie nie może być łączona/dzielona. </text> diff --git a/indra/newview/skins/default/xui/pl/floater_world_map.xml b/indra/newview/skins/default/xui/pl/floater_world_map.xml index 95010e0b91..05287ad42a 100644 --- a/indra/newview/skins/default/xui/pl/floater_world_map.xml +++ b/indra/newview/skins/default/xui/pl/floater_world_map.xml @@ -35,7 +35,7 @@ <text name="pg_label"> Ogólne </text> - <check_box initial_value="prawda" name="event_mature_chk"/> + <check_box name="event_mature_chk"/> <text name="mature_label"> Moderuj </text> diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml index f74f4f2333..98fdffeb50 100644 --- a/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml @@ -38,10 +38,10 @@ <radio_item label="Użyj zewnętrznej przeglądarki (IE, Firefox, Safari)" name="external" tool_tip="Używaj zewnętrznej przeglądarki. Nie jest to rekomendowane w trybie pełnoekranowym." value="1"/> <radio_item label="Używaj wbudowanej przeglądarki." name="internal" tool_tip="Używaj wbudowanej przeglądarki. Ta przeglądarka otworzy nowe okno w [APP_NAME]." value=""/> </radio_group> - <check_box initial_value="prawda" label="Zezwalaj na wtyczki" name="browser_plugins_enabled"/> - <check_box initial_value="prawda" label="Akceptuj ciasteczka z Internetu" name="cookies_enabled"/> - <check_box initial_value="prawda" label="Zezwalaj na Javascript" name="browser_javascript_enabled"/> - <check_box initial_value="false" label="Używaj Serwera Proxy" name="web_proxy_enabled"/> + <check_box label="Zezwalaj na wtyczki" name="browser_plugins_enabled"/> + <check_box label="Akceptuj ciasteczka z Internetu" name="cookies_enabled"/> + <check_box label="Zezwalaj na Javascript" name="browser_javascript_enabled"/> + <check_box label="Używaj Serwera Proxy" name="web_proxy_enabled"/> <text name="Proxy location"> Lokalizacja Proxy: </text> diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml b/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml index 04372208d6..6ab5be77d8 100644 --- a/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Dźwięki" name="Preference Media panel"> <slider label="Główny" name="System Volume"/> - <check_box initial_value="true" label="Wycisz podczas minimalizacji" name="mute_when_minimized"/> + <check_box label="Wycisz podczas minimalizacji" name="mute_when_minimized"/> <slider label="Interfejs" name="UI Volume"/> <slider label="Otoczenie" name="Wind Volume"/> <slider label="Efekty dźwiękowe" name="SFX Volume"/> @@ -11,8 +11,8 @@ <check_box label="Odtwarzaj media" name="enable_media"/> <slider label="Komunikacja Głosowa" name="Voice Volume"/> <check_box label="Pozwól na rozmowy głosowe" name="enable_voice_check"/> - <check_box label="Automatycznie odtwarzaj media" name="media_auto_play_btn" tool_tip="Zaznacz tę funkcję by uruchomić automatyczne uruchamianie mediów" value="prawda"/> - <check_box label="Uruchom media załączone do innych awatarów" name="media_show_on_others_btn" tool_tip="Odznacz tę funkcję by ukryć media załączone to awatarów w publiżu" value="prawda"/> + <check_box label="Automatycznie odtwarzaj media" name="media_auto_play_btn" tool_tip="Zaznacz tę funkcję by uruchomić automatyczne uruchamianie mediów"/> + <check_box label="Uruchom media załączone do innych awatarów" name="media_show_on_others_btn" tool_tip="Odznacz tę funkcję by ukryć media załączone to awatarów w publiżu"/> <text name="voice_chat_settings"> Ustawienia Komunikacji Głosowej </text> diff --git a/indra/newview/skins/default/xui/pt/floater_world_map.xml b/indra/newview/skins/default/xui/pt/floater_world_map.xml index efd90dfaa4..65e48b4bfd 100644 --- a/indra/newview/skins/default/xui/pt/floater_world_map.xml +++ b/indra/newview/skins/default/xui/pt/floater_world_map.xml @@ -39,7 +39,7 @@ <text name="pg_label"> Público geral </text> - <check_box initial_value="verdadeiro" label="Mature" name="event_mature_chk"/> + <check_box label="Mature" name="event_mature_chk"/> <text name="mature_label"> Moderado </text> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml index f03063d05b..5266f646b7 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml @@ -37,9 +37,9 @@ <radio_item label="Usar meu navegador (IE, Firefox, Safari)" name="external" tool_tip="Use o navegador incluso para consultar a ajuda, abrir links da web, etc. Uso em tela inteira não recomendado." value="1"/> <radio_item label="Usar navegador incluso" name="internal" tool_tip="Use este navegador para consultar a ajuda, abrir links da web, etc. As janelas abrem dentro do [APP_NAME]." value=""/> </radio_group> - <check_box initial_value="verdadeiro" label="Habilitar plugins" name="browser_plugins_enabled"/> - <check_box initial_value="verdadeiro" label="Aceitar cookies" name="cookies_enabled"/> - <check_box initial_value="verdadeiro" label="Habilitar Javascript" name="browser_javascript_enabled"/> + <check_box initial_value="true" label="Habilitar plugins" name="browser_plugins_enabled"/> + <check_box initial_value="true" label="Aceitar cookies" name="cookies_enabled"/> + <check_box initial_value="true" label="Habilitar Javascript" name="browser_javascript_enabled"/> <check_box initial_value="false" label="Ativar web proxy" name="web_proxy_enabled"/> <text name="Proxy location"> Localização do proxy: diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml b/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml index 5dbd3d4904..43c970841a 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml @@ -11,8 +11,8 @@ <check_box label="Ativado" name="enable_media"/> <slider label="Bate-papo de voz" name="Voice Volume"/> <check_box label="Ativado" name="enable_voice_check"/> - <check_box label="Autorizar auto-play de mídias" name="media_auto_play_btn" tool_tip="Marque esta opção para auto-executar mídias, se elas quiserem" value="verdadeiro"/> - <check_box label="Tocar mídia anexada em outros avatares" name="media_show_on_others_btn" tool_tip="Desmarque esta opção para ocultar mídias anexadas em avatares por perto" value="verdadeiro"/> + <check_box label="Autorizar auto-play de mídias" name="media_auto_play_btn" tool_tip="Marque esta opção para auto-executar mídias, se elas quiserem"/> + <check_box label="Tocar mídia anexada em outros avatares" name="media_show_on_others_btn" tool_tip="Desmarque esta opção para ocultar mídias anexadas em avatares por perto"/> <text name="voice_chat_settings"> Configuração de bate-papo de voz </text> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2a966f4adf..c887097575 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -105,6 +105,12 @@ class ViewerManifest(LLManifest): self.end_prefix("*/html") self.end_prefix("skins") + # local_assets dir (for pre-cached textures) + if self.prefix(src="local_assets"): + self.path("*.j2c") + self.path("*.tga") + self.end_prefix("local_assets") + # Files in the newview/ directory self.path("gpu_table.txt") |