diff options
55 files changed, 981 insertions, 264 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index af759e5bcb..fa470cccae 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -8,6 +8,7 @@ Able Whitman VWR-650 VWR-1460 VWR-1691 + VWR-1735 Adam Marker VWR-2755 Aimee Trescothick @@ -168,6 +169,7 @@ Jacek Antonelli VWR-188 VWR-427 VWR-597 + VWR-2448 Joghert LeSabre VWR-64 Kage Pixel diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp index 3e5a1e6705..415b945e88 100644 --- a/indra/llcharacter/llanimationstates.cpp +++ b/indra/llcharacter/llanimationstates.cpp @@ -260,76 +260,77 @@ LLUUID LLAnimationLibrary::stringToAnimState( const char *name, BOOL allow_ids ) } // Animation states that the user can trigger as part of a gesture +// See struct LLAnimStateEntry in header for label location information const LLAnimStateEntry gUserAnimStates[] = { - LLAnimStateEntry("Afraid", "express_afraid", ANIM_AGENT_AFRAID), - LLAnimStateEntry("Angry", "express_anger", ANIM_AGENT_ANGRY), - LLAnimStateEntry("Away", "away", ANIM_AGENT_AWAY), - LLAnimStateEntry("Backflip", "backflip", ANIM_AGENT_BACKFLIP), - LLAnimStateEntry("Belly Laugh", "express_laugh", ANIM_AGENT_BELLY_LAUGH), - LLAnimStateEntry("BigSmile", "express_toothsmile", ANIM_AGENT_EXPRESS_TOOTHSMILE), - LLAnimStateEntry("Blow Kiss", "blowkiss", ANIM_AGENT_BLOW_KISS), - LLAnimStateEntry("Bored", "express_bored", ANIM_AGENT_BORED), - LLAnimStateEntry("Bow", "bow", ANIM_AGENT_BOW), - LLAnimStateEntry("Clap", "clap", ANIM_AGENT_CLAP), - LLAnimStateEntry("Court Bow", "courtbow", ANIM_AGENT_COURTBOW), - LLAnimStateEntry("Cry", "express_cry", ANIM_AGENT_CRY), - LLAnimStateEntry("Dance 1", "dance1", ANIM_AGENT_DANCE1), - LLAnimStateEntry("Dance 2", "dance2", ANIM_AGENT_DANCE2), - LLAnimStateEntry("Dance 3", "dance3", ANIM_AGENT_DANCE3), - LLAnimStateEntry("Dance 4", "dance4", ANIM_AGENT_DANCE4), - LLAnimStateEntry("Dance 5", "dance5", ANIM_AGENT_DANCE5), - LLAnimStateEntry("Dance 6", "dance6", ANIM_AGENT_DANCE6), - LLAnimStateEntry("Dance 7", "dance7", ANIM_AGENT_DANCE7), - LLAnimStateEntry("Dance 8", "dance8", ANIM_AGENT_DANCE8), - LLAnimStateEntry("Disdain", "express_disdain", ANIM_AGENT_EXPRESS_DISDAIN), - LLAnimStateEntry("Drink", "drink", ANIM_AGENT_DRINK), - LLAnimStateEntry("Embarrassed", "express_embarrased", ANIM_AGENT_EMBARRASSED), - LLAnimStateEntry("Finger Wag", "angry_fingerwag", ANIM_AGENT_FINGER_WAG), - LLAnimStateEntry("Fist Pump", "fist_pump", ANIM_AGENT_FIST_PUMP), - LLAnimStateEntry("Floating Yoga", "yoga_float", ANIM_AGENT_YOGA_FLOAT), - LLAnimStateEntry("Frown", "express_frown", ANIM_AGENT_EXPRESS_FROWN), - LLAnimStateEntry("Impatient", "impatient", ANIM_AGENT_IMPATIENT), - LLAnimStateEntry("Jump For Joy", "jumpforjoy", ANIM_AGENT_JUMP_FOR_JOY), - LLAnimStateEntry("Kiss My Butt", "kissmybutt", ANIM_AGENT_KISS_MY_BUTT), - LLAnimStateEntry("Kiss", "express_kiss", ANIM_AGENT_EXPRESS_KISS), - LLAnimStateEntry("Laugh", "laugh_short", ANIM_AGENT_LAUGH_SHORT), - LLAnimStateEntry("Muscle Beach", "musclebeach", ANIM_AGENT_MUSCLE_BEACH), - LLAnimStateEntry("No (Unhappy)", "no_unhappy", ANIM_AGENT_NO_UNHAPPY), - LLAnimStateEntry("No", "no_head", ANIM_AGENT_NO), - LLAnimStateEntry("Nya-nya-nya", "nyanya", ANIM_AGENT_NYAH_NYAH), - LLAnimStateEntry("One-Two Punch", "punch_onetwo", ANIM_AGENT_ONETWO_PUNCH), - LLAnimStateEntry("Open Mouth", "express_open_mouth", ANIM_AGENT_EXPRESS_OPEN_MOUTH), - LLAnimStateEntry("Peace", "peace", ANIM_AGENT_PEACE), - LLAnimStateEntry("Point at Other", "point_you", ANIM_AGENT_POINT_YOU), - LLAnimStateEntry("Point at Self", "point_me", ANIM_AGENT_POINT_ME), - LLAnimStateEntry("Punch Left", "punch_l", ANIM_AGENT_PUNCH_LEFT), - LLAnimStateEntry("Punch Right", "punch_r", ANIM_AGENT_PUNCH_RIGHT), - LLAnimStateEntry("RPS count", "rps_countdown", ANIM_AGENT_RPS_COUNTDOWN), - LLAnimStateEntry("RPS paper", "rps_paper", ANIM_AGENT_RPS_PAPER), - LLAnimStateEntry("RPS rock", "rps_rock", ANIM_AGENT_RPS_ROCK), - LLAnimStateEntry("RPS scissors", "rps_scissors", ANIM_AGENT_RPS_SCISSORS), - LLAnimStateEntry("Repulsed", "express_repulsed", ANIM_AGENT_EXPRESS_REPULSED), - LLAnimStateEntry("Roundhouse Kick", "kick_roundhouse_r", ANIM_AGENT_ROUNDHOUSE_KICK), - LLAnimStateEntry("Sad", "express_sad", ANIM_AGENT_SAD), - LLAnimStateEntry("Salute", "salute", ANIM_AGENT_SALUTE), - LLAnimStateEntry("Shout", "shout", ANIM_AGENT_SHOUT), - LLAnimStateEntry("Shrug", "express_shrug", ANIM_AGENT_SHRUG), - LLAnimStateEntry("Smile", "express_smile", ANIM_AGENT_EXPRESS_SMILE), - LLAnimStateEntry("Smoke Idle", "smoke_idle", ANIM_AGENT_SMOKE_IDLE), - LLAnimStateEntry("Smoke Inhale", "smoke_inhale", ANIM_AGENT_SMOKE_INHALE), - LLAnimStateEntry("Smoke Throw Down","smoke_throw_down", ANIM_AGENT_SMOKE_THROW_DOWN), - LLAnimStateEntry("Surprise", "express_surprise", ANIM_AGENT_SURPRISE), - LLAnimStateEntry("Sword Strike", "sword_strike_r", ANIM_AGENT_SWORD_STRIKE), - LLAnimStateEntry("Tantrum", "angry_tantrum", ANIM_AGENT_TANTRUM), - LLAnimStateEntry("TongueOut", "express_tongue_out", ANIM_AGENT_EXPRESS_TONGUE_OUT), - LLAnimStateEntry("Wave", "hello", ANIM_AGENT_HELLO), - LLAnimStateEntry("Whisper", "whisper", ANIM_AGENT_WHISPER), - LLAnimStateEntry("Whistle", "whistle", ANIM_AGENT_WHISTLE), - LLAnimStateEntry("Wink", "express_wink", ANIM_AGENT_WINK), - LLAnimStateEntry("Wink (Hollywood)","wink_hollywood", ANIM_AGENT_WINK_HOLLYWOOD), - LLAnimStateEntry("Worry", "express_worry", ANIM_AGENT_EXPRESS_WORRY), - LLAnimStateEntry("Yes (Happy)", "yes_happy", ANIM_AGENT_YES_HAPPY), - LLAnimStateEntry("Yes", "yes_head", ANIM_AGENT_YES), + LLAnimStateEntry("express_afraid", ANIM_AGENT_AFRAID), + LLAnimStateEntry("express_anger", ANIM_AGENT_ANGRY), + LLAnimStateEntry("away", ANIM_AGENT_AWAY), + LLAnimStateEntry("backflip", ANIM_AGENT_BACKFLIP), + LLAnimStateEntry("express_laugh", ANIM_AGENT_BELLY_LAUGH), + LLAnimStateEntry("express_toothsmile", ANIM_AGENT_EXPRESS_TOOTHSMILE), + LLAnimStateEntry("blowkiss", ANIM_AGENT_BLOW_KISS), + LLAnimStateEntry("express_bored", ANIM_AGENT_BORED), + LLAnimStateEntry("bow", ANIM_AGENT_BOW), + LLAnimStateEntry("clap", ANIM_AGENT_CLAP), + LLAnimStateEntry("courtbow", ANIM_AGENT_COURTBOW), + LLAnimStateEntry("express_cry", ANIM_AGENT_CRY), + LLAnimStateEntry("dance1", ANIM_AGENT_DANCE1), + LLAnimStateEntry("dance2", ANIM_AGENT_DANCE2), + LLAnimStateEntry("dance3", ANIM_AGENT_DANCE3), + LLAnimStateEntry("dance4", ANIM_AGENT_DANCE4), + LLAnimStateEntry("dance5", ANIM_AGENT_DANCE5), + LLAnimStateEntry("dance6", ANIM_AGENT_DANCE6), + LLAnimStateEntry("dance7", ANIM_AGENT_DANCE7), + LLAnimStateEntry("dance8", ANIM_AGENT_DANCE8), + LLAnimStateEntry("express_disdain", ANIM_AGENT_EXPRESS_DISDAIN), + LLAnimStateEntry("drink", ANIM_AGENT_DRINK), + LLAnimStateEntry("express_embarrased", ANIM_AGENT_EMBARRASSED), + LLAnimStateEntry("angry_fingerwag", ANIM_AGENT_FINGER_WAG), + LLAnimStateEntry("fist_pump", ANIM_AGENT_FIST_PUMP), + LLAnimStateEntry("yoga_float", ANIM_AGENT_YOGA_FLOAT), + LLAnimStateEntry("express_frown", ANIM_AGENT_EXPRESS_FROWN), + LLAnimStateEntry("impatient", ANIM_AGENT_IMPATIENT), + LLAnimStateEntry("jumpforjoy", ANIM_AGENT_JUMP_FOR_JOY), + LLAnimStateEntry("kissmybutt", ANIM_AGENT_KISS_MY_BUTT), + LLAnimStateEntry("express_kiss", ANIM_AGENT_EXPRESS_KISS), + LLAnimStateEntry("laugh_short", ANIM_AGENT_LAUGH_SHORT), + LLAnimStateEntry("musclebeach", ANIM_AGENT_MUSCLE_BEACH), + LLAnimStateEntry("no_unhappy", ANIM_AGENT_NO_UNHAPPY), + LLAnimStateEntry("no_head", ANIM_AGENT_NO), + LLAnimStateEntry("nyanya", ANIM_AGENT_NYAH_NYAH), + LLAnimStateEntry("punch_onetwo", ANIM_AGENT_ONETWO_PUNCH), + LLAnimStateEntry("express_open_mouth", ANIM_AGENT_EXPRESS_OPEN_MOUTH), + LLAnimStateEntry("peace", ANIM_AGENT_PEACE), + LLAnimStateEntry("point_you", ANIM_AGENT_POINT_YOU), + LLAnimStateEntry("point_me", ANIM_AGENT_POINT_ME), + LLAnimStateEntry("punch_l", ANIM_AGENT_PUNCH_LEFT), + LLAnimStateEntry("punch_r", ANIM_AGENT_PUNCH_RIGHT), + LLAnimStateEntry("rps_countdown", ANIM_AGENT_RPS_COUNTDOWN), + LLAnimStateEntry("rps_paper", ANIM_AGENT_RPS_PAPER), + LLAnimStateEntry("rps_rock", ANIM_AGENT_RPS_ROCK), + LLAnimStateEntry("rps_scissors", ANIM_AGENT_RPS_SCISSORS), + LLAnimStateEntry("express_repulsed", ANIM_AGENT_EXPRESS_REPULSED), + LLAnimStateEntry("kick_roundhouse_r", ANIM_AGENT_ROUNDHOUSE_KICK), + LLAnimStateEntry("express_sad", ANIM_AGENT_SAD), + LLAnimStateEntry("salute", ANIM_AGENT_SALUTE), + LLAnimStateEntry("shout", ANIM_AGENT_SHOUT), + LLAnimStateEntry("express_shrug", ANIM_AGENT_SHRUG), + LLAnimStateEntry("express_smile", ANIM_AGENT_EXPRESS_SMILE), + LLAnimStateEntry("smoke_idle", ANIM_AGENT_SMOKE_IDLE), + LLAnimStateEntry("smoke_inhale", ANIM_AGENT_SMOKE_INHALE), + LLAnimStateEntry("smoke_throw_down", ANIM_AGENT_SMOKE_THROW_DOWN), + LLAnimStateEntry("express_surprise", ANIM_AGENT_SURPRISE), + LLAnimStateEntry("sword_strike_r", ANIM_AGENT_SWORD_STRIKE), + LLAnimStateEntry("angry_tantrum", ANIM_AGENT_TANTRUM), + LLAnimStateEntry("express_tongue_out", ANIM_AGENT_EXPRESS_TONGUE_OUT), + LLAnimStateEntry("hello", ANIM_AGENT_HELLO), + LLAnimStateEntry("whisper", ANIM_AGENT_WHISPER), + LLAnimStateEntry("whistle", ANIM_AGENT_WHISTLE), + LLAnimStateEntry("express_wink", ANIM_AGENT_WINK), + LLAnimStateEntry("wink_hollywood", ANIM_AGENT_WINK_HOLLYWOOD), + LLAnimStateEntry("express_worry", ANIM_AGENT_EXPRESS_WORRY), + LLAnimStateEntry("yes_happy", ANIM_AGENT_YES_HAPPY), + LLAnimStateEntry("yes_head", ANIM_AGENT_YES), }; const S32 gUserAnimStatesCount = sizeof(gUserAnimStates) / sizeof(gUserAnimStates[0]); diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h index cceb952926..ae3f6894db 100644 --- a/indra/llcharacter/llanimationstates.h +++ b/indra/llcharacter/llanimationstates.h @@ -227,13 +227,18 @@ public: struct LLAnimStateEntry { - LLAnimStateEntry(const char* label, const char* name, const LLUUID& id) - : mLabel(label), + LLAnimStateEntry(const char* name, const LLUUID& id) : mName(name), mID(id) - { } + { + // LABELS: + // Look to newview/LLAnimStateLabels.* for how to get the labels. + // The labels should no longer be stored in this structure. The server + // shouldn't care about the local friendly name of an animation, and + // this is common code. + } + - const char* mLabel; const char* mName; const LLUUID mID; }; diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index ccc666e74d..0b9732a718 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -377,6 +377,27 @@ 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 a5719b0685..2c0451d46c 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -207,6 +207,9 @@ public: // set all morph weights to 0 void clearVisualParamWeights(); + // see if all the weights are default + BOOL visualParamWeightsAreDefault(); + // visual parameter accessors LLVisualParam* getFirstVisualParam() { diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 3dd99a4636..538641d060 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -565,6 +565,8 @@ void LLComboBox::showList() S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); + // make sure we have up to date content width metrics + mList->calcColumnWidths(); S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); if (mListPosition == BELOW) diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index b54470d44a..90e0552861 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -132,7 +132,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, mSelectAllonFocusReceived( FALSE ), mPassDelete(FALSE), mReadOnly(FALSE), - mImage( sImage ) + mImage( sImage ), + mReplaceNewlinesWithSpaces( TRUE ) { llassert( max_length_bytes > 0 ); @@ -961,7 +962,7 @@ void LLLineEditor::paste() LLWString clean_string(paste); LLWString::replaceTabsWithSpaces(clean_string, 1); //clean_string = wstring_detabify(paste, 1); - LLWString::replaceChar(clean_string, '\n', ' '); + LLWString::replaceChar(clean_string, '\n', mReplaceNewlinesWithSpaces ? ' ' : 182); // 182 == paragraph character // Insert the string @@ -2547,6 +2548,10 @@ S32 LLLineEditor::getPreeditFontSize() const return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); } +void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace) +{ + mReplaceNewlinesWithSpaces = replace; +} static LLRegisterWidget<LLSearchEditor> r2("search_editor"); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index f5d7ecd4c4..8b41dd1d87 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -211,6 +211,8 @@ public: void setEnableLineHistory( BOOL enabled ) { mHaveHistory = enabled; } // switches line history on or off void updateHistory(); // stores current line in history + void setReplaceNewlinesWithSpaces(BOOL replace); + private: // private helper methods void removeChar(); @@ -311,6 +313,8 @@ private: // Instances that by default point to the statics but can be overidden in XML. LLPointer<LLUIImage> mImage; + BOOL mReplaceNewlinesWithSpaces; // if false, will replace pasted newlines with paragraph symbol. + // private helper class class LLLineEditorRollback { diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp index e82e93a7ba..82be9672b6 100644 --- a/indra/llui/llresizebar.cpp +++ b/indra/llui/llresizebar.cpp @@ -50,6 +50,7 @@ LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLR mMaxSize( max_size ), mSide( side ), mSnappingEnabled(TRUE), + mAllowDoubleClickSnapping(TRUE), mResizingView(resizing_view) { // set up some generically good follow code. @@ -260,27 +261,31 @@ BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask) LLRect orig_rect = mResizingView->getRect(); LLRect scaled_rect = orig_rect; - if (mSnappingEnabled) + if (mSnappingEnabled && mAllowDoubleClickSnapping) { switch( mSide ) { case LEFT: mResizingView->findSnapEdge(scaled_rect.mLeft, LLCoordGL(0, 0), SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + scaled_rect.mLeft = scaled_rect.mRight - llclamp(scaled_rect.getWidth(), mMinSize, mMaxSize); break; case TOP: mResizingView->findSnapEdge(scaled_rect.mTop, LLCoordGL(0, 0), SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + scaled_rect.mTop = scaled_rect.mBottom + llclamp(scaled_rect.getHeight(), mMinSize, mMaxSize); break; case RIGHT: mResizingView->findSnapEdge(scaled_rect.mRight, LLCoordGL(0, 0), SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + scaled_rect.mRight = scaled_rect.mLeft + llclamp(scaled_rect.getWidth(), mMinSize, mMaxSize); break; case BOTTOM: mResizingView->findSnapEdge(scaled_rect.mBottom, LLCoordGL(0, 0), SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + scaled_rect.mBottom = scaled_rect.mTop - llclamp(scaled_rect.getHeight(), mMinSize, mMaxSize); break; } + + mResizingView->userSetShape(scaled_rect); } - mResizingView->reshape(scaled_rect.getWidth(), scaled_rect.getHeight()); - mResizingView->setOrigin(scaled_rect.mLeft, scaled_rect.mBottom); return TRUE; } diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index f45653cbad..b760abf13d 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -50,6 +50,7 @@ public: void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; } + void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; } private: S32 mDragLastScreenX; @@ -61,6 +62,7 @@ private: S32 mMaxSize; const Side mSide; BOOL mSnappingEnabled; + BOOL mAllowDoubleClickSnapping; LLView* mResizingView; }; diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 8b82a84b46..6896ee288f 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -37,7 +37,7 @@ #include "llfont.h" #include "llui.h" -class LLStyle +class LLStyle : public LLRefCount { public: LLStyle(); @@ -46,8 +46,6 @@ public: LLStyle &operator=(const LLStyle &rhs); - virtual ~LLStyle() { } - virtual void init (BOOL is_visible, const LLColor4 &color, const LLString& font_name); virtual const LLColor4& getColor() const { return mColor; } @@ -101,6 +99,9 @@ public: S32 mImageWidth; S32 mImageHeight; +protected: + virtual ~LLStyle() { } + private: BOOL mVisible; LLColor4 mColor; @@ -111,4 +112,6 @@ private: BOOL mIsEmbeddedItem; }; +typedef LLPointer<LLStyle> LLStyleSP; + #endif // LL_LLSTYLE_H diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 7c8c0fe81c..5617eb4873 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1244,14 +1244,14 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { - if(cur_segment->getStyle().isLink()) + if(cur_segment->getStyle()->isLink()) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl; getWindow()->setCursor(UI_CURSOR_HAND); handled = TRUE; } else - if(cur_segment->getStyle().getIsEmbeddedItem()) + if(cur_segment->getStyle()->getIsEmbeddedItem()) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl; getWindow()->setCursor(UI_CURSOR_HAND); @@ -2928,23 +2928,26 @@ void LLTextEditor::drawText() S32 clipped_len = clipped_end - seg_start; if( clipped_len > 0 ) { - LLStyle style = cur_segment->getStyle(); - if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) + LLStyleSP style = cur_segment->getStyle(); + if ( style->isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) { - LLUIImagePtr image = style.getImage(); - image->draw(llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight); + S32 style_image_height = style->mImageHeight; + S32 style_image_width = style->mImageWidth; + LLUIImagePtr image = style->getImage(); + image->draw(llround(text_x), llround(text_y)+line_height-style_image_height, + style_image_width, style_image_height); } - if (cur_segment == mHoverSegment && style.getIsEmbeddedItem()) + if (cur_segment == mHoverSegment && style->getIsEmbeddedItem()) { - style.mUnderline = TRUE; + style->mUnderline = TRUE; } S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) ) { - mHTML = style.getLinkHREF(); + mHTML = style->getLinkHREF(); } drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x ); @@ -2963,38 +2966,38 @@ void LLTextEditor::drawText() } // Draws a single text segment, reversing the color for selection if needed. -void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& style, F32* right_x ) +void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& style, F32* right_x ) { - if (!style.isVisible()) + if (!style->isVisible()) { return; } const LLFontGL* font = mGLFont; - LLColor4 color = style.getColor(); + LLColor4 color = style->getColor(); - if ( style.getFontString()[0] ) + if ( style->getFontString()[0] ) { - font = LLResMgr::getInstance()->getRes(style.getFontID()); + font = LLResMgr::getInstance()->getRes(style->getFontID()); } U8 font_flags = LLFontGL::NORMAL; - if (style.mBold) + if (style->mBold) { font_flags |= LLFontGL::BOLD; } - if (style.mItalic) + if (style->mItalic) { font_flags |= LLFontGL::ITALIC; } - if (style.mUnderline) + if (style->mUnderline) { font_flags |= LLFontGL::UNDERLINE; } - if (style.getIsEmbeddedItem()) + if (style->getIsEmbeddedItem()) { if (mReadOnly) { @@ -3434,17 +3437,17 @@ void LLTextEditor::appendColoredText(const LLString &new_text, const LLColor4 &color, const LLString& font_name) { - LLStyle style; - style.setVisible(true); - style.setColor(color); - style.setFontName(font_name); + LLStyleSP style(new LLStyle); + style->setVisible(true); + style->setColor(color); + style->setFontName(font_name); appendStyledText(new_text, allow_undo, prepend_newline, &style); } void LLTextEditor::appendStyledText(const LLString &new_text, bool allow_undo, bool prepend_newline, - const LLStyle* style) + const LLStyleSP *stylep) { if(mParseHTML) { @@ -3453,17 +3456,17 @@ void LLTextEditor::appendStyledText(const LLString &new_text, LLString text = new_text; while ( findHTML(text, &start, &end) ) { - LLStyle html; - html.setVisible(true); - html.setColor(mLinkColor); - if (style) + LLStyleSP html(new LLStyle); + html->setVisible(true); + html->setColor(mLinkColor); + if (stylep) { - html.setFontName(style->getFontString()); + html->setFontName((*stylep)->getFontString()); } - html.mUnderline = TRUE; + html->mUnderline = TRUE; - if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, style); - html.setLinkHREF(text.substr(start,end-start)); + if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, stylep); + html->setLinkHREF(text.substr(start,end-start)); appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html); if (end < (S32)text.length()) { @@ -3475,17 +3478,17 @@ void LLTextEditor::appendStyledText(const LLString &new_text, break; } } - if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, style); + if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, stylep); } else { - appendText(new_text, allow_undo, prepend_newline, style); + appendText(new_text, allow_undo, prepend_newline, stylep); } } // Appends new text to end of document void LLTextEditor::appendText(const LLString &new_text, bool allow_undo, bool prepend_newline, - const LLStyle* segment_style) + const LLStyleSP *stylep) { // Save old state BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); @@ -3513,11 +3516,11 @@ void LLTextEditor::appendText(const LLString &new_text, bool allow_undo, bool pr append(utf8str_to_wstring(new_text), TRUE ); } - if (segment_style) + if (stylep) { S32 segment_start = old_length; S32 segment_end = getLength(); - LLTextSegment* segment = new LLTextSegment(*segment_style, segment_start, segment_end ); + LLTextSegment* segment = new LLTextSegment(*stylep, segment_start, segment_end ); mSegments.push_back(segment); } @@ -3803,8 +3806,8 @@ void LLTextEditor::findEmbeddedItemSegments() in_text = TRUE; } - LLStyle embedded_style; - embedded_style.setIsEmbeddedItem( TRUE ); + LLStyleSP embedded_style(new LLStyle); + embedded_style->setIsEmbeddedItem( TRUE ); // Start with i just after the first embedded item while ( text[idx] ) @@ -4003,7 +4006,7 @@ BOOL LLTextEditor::exportBuffer(LLString &buffer ) LLTextSegment::LLTextSegment(S32 start) : mStart(start) { } -LLTextSegment::LLTextSegment( const LLStyle& style, S32 start, S32 end ) : +LLTextSegment::LLTextSegment( const LLStyleSP& style, S32 start, S32 end ) : mStyle( style ), mStart( start), mEnd( end ), @@ -4011,9 +4014,8 @@ LLTextSegment::LLTextSegment( const LLStyle& style, S32 start, S32 end ) : mIsDefault(FALSE) { } -LLTextSegment::LLTextSegment( - const LLColor4& color, S32 start, S32 end, BOOL is_visible) : - mStyle( is_visible, color,"" ), +LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible) : + mStyle(new LLStyle(is_visible,color,"")), mStart( start), mEnd( end ), mToken(NULL), @@ -4021,7 +4023,7 @@ LLTextSegment::LLTextSegment( { } LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end ) : - mStyle( TRUE, color,"" ), + mStyle(new LLStyle(TRUE, color,"" )), mStart( start), mEnd( end ), mToken(NULL), @@ -4029,7 +4031,7 @@ LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end ) : { } LLTextSegment::LLTextSegment( const LLColor3& color, S32 start, S32 end ) : - mStyle( TRUE, color,"" ), + mStyle(new LLStyle(TRUE, color,"" )), mStart( start), mEnd( end ), mToken(NULL), diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 00dc70ba92..af2dbcfd5f 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -139,7 +139,7 @@ public: void insertText(const LLString &text); // appends text at end void appendText(const LLString &wtext, bool allow_undo, bool prepend_newline, - const LLStyle* segment_style = NULL); + const LLStyleSP *stylep = NULL); void appendColoredText(const LLString &wtext, bool allow_undo, bool prepend_newline, @@ -148,7 +148,7 @@ public: // if styled text starts a line, you need to prepend a newline. void appendStyledText(const LLString &new_text, bool allow_undo, bool prepend_newline, - const LLStyle* style); + const LLStyleSP *stylep = NULL); // Removes text from the end of document // Does not change highlight or cursor position. @@ -429,7 +429,7 @@ private: void drawSelectionBackground(); void drawCursor(); void drawText(); - void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); + void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x); // // Data @@ -528,7 +528,7 @@ class LLTextSegment public: // for creating a compare value LLTextSegment(S32 start); - LLTextSegment( const LLStyle& style, S32 start, S32 end ); + LLTextSegment( const LLStyleSP& style, S32 start, S32 end ); LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible); LLTextSegment( const LLColor4& color, S32 start, S32 end ); LLTextSegment( const LLColor3& color, S32 start, S32 end ); @@ -536,10 +536,10 @@ public: S32 getStart() const { return mStart; } S32 getEnd() const { return mEnd; } void setEnd( S32 end ) { mEnd = end; } - const LLColor4& getColor() const { return mStyle.getColor(); } - void setColor(const LLColor4 &color) { mStyle.setColor(color); } - const LLStyle& getStyle() const { return mStyle; } - void setStyle(const LLStyle &style) { mStyle = style; } + const LLColor4& getColor() const { return mStyle->getColor(); } + void setColor(const LLColor4 &color) { mStyle->setColor(color); } + const LLStyleSP& getStyle() const { return mStyle; } + void setStyle(const LLStyleSP &style) { mStyle = style; } void setIsDefault(BOOL b) { mIsDefault = b; } BOOL getIsDefault() const { return mIsDefault; } void setToken( LLKeywordToken* token ) { mToken = token; } @@ -557,7 +557,7 @@ public: }; private: - LLStyle mStyle; + LLStyleSP mStyle; S32 mStart; S32 mEnd; LLKeywordToken* mToken; diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index e2019a8e60..d4b4a4655b 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -32,7 +32,9 @@ #ifndef LL_LLXMLNODE_H #define LL_LLXMLNODE_H -#define XML_STATIC +#ifndef XML_STATIC +#define XML_STATIC 1 +#endif #ifdef LL_STANDALONE #include <expat.h> #else diff --git a/indra/llxml/llxmlparser.h b/indra/llxml/llxmlparser.h index d86af69bef..747cf3d0ca 100644 --- a/indra/llxml/llxmlparser.h +++ b/indra/llxml/llxmlparser.h @@ -32,7 +32,9 @@ #ifndef LL_LLXMLPARSER_H #define LL_LLXMLPARSER_H -#define XML_STATIC +#ifndef XML_STATIC +#define XML_STATIC 1 +#endif #ifdef LL_STANDALONE #include <expat.h> #else diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 73a832ead7..e954d97310 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5903,6 +5903,17 @@ <key>Value</key> <real>0.25</real> </map> + <key>RenderUnloadedAvatar</key> + <map> + <key>Comment</key> + <string>Show avatars which haven't finished loading</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderVBOEnable</key> <map> <key>Comment</key> diff --git a/indra/newview/llanimstatelabels.cpp b/indra/newview/llanimstatelabels.cpp new file mode 100644 index 0000000000..380bf7c39c --- /dev/null +++ b/indra/newview/llanimstatelabels.cpp @@ -0,0 +1,39 @@ +/** + * @file llanimationstatenames.cpp + * @brief Names for built-in animation states + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llanimstatelabels.h" +#include "lltrans.h" + +std::string LLAnimStateLabels::getStateLabel( const char *animName ) +{ + return LLTrans::getString("anim_" + LLString(animName) ); +} diff --git a/indra/newview/llanimstatelabels.h b/indra/newview/llanimstatelabels.h new file mode 100644 index 0000000000..5a6406f7e9 --- /dev/null +++ b/indra/newview/llanimstatelabels.h @@ -0,0 +1,42 @@ +/** + * @file llanimstatelabels.h + * @brief Declaration of LLVOAvatar class which is a derivation fo + * LLViewerObject + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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_LLANIMSTATELABELS_H +#define LL_LLANIMSTATELABELS_H + +class LLAnimStateLabels +{ +public: + static std::string getStateLabel( const char *animName ); +}; + +#endif // LL_ANIMSTATELABELS_H diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ee471d21ac..45fbb5e65f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -102,6 +102,7 @@ #include "audioengine.h" #include "llviewermenu.h" #include "llselectmgr.h" +#include "lltrans.h" #include "lltracker.h" #include "llviewerparcelmgr.h" #include "llworldmapview.h" @@ -2088,6 +2089,7 @@ bool LLAppViewer::initWindow() LLAlertDialog::parseAlerts("alerts.xml"); LLNotifyBox::parseNotify("notify.xml"); + LLTrans::parseStrings("strings.xml"); // Show watch cursor gViewerWindow->setCursor(UI_CURSOR_WAIT); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 01b093e6f6..59553922ed 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -144,6 +144,7 @@ BOOL LLChatBar::postBuild() mInputEditor->setRevertOnEsc( FALSE ); mInputEditor->setIgnoreTab(TRUE); mInputEditor->setPassDelete(TRUE); + mInputEditor->setReplaceNewlinesWithSpaces(FALSE); mInputEditor->setMaxTextLength(1023); mInputEditor->setEnableLineHistory(TRUE); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 06536660e2..4aeb741b2c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1170,11 +1170,13 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* LLSpatialGroup* group = av->getSpatialGroup(); BOOL impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor(); - + BOOL loaded = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded(); + if (!group || av->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance || LLDrawable::getCurrentFrame() - av->mVisible > 1 || - impostor) + impostor || + !loaded) { return; } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 99bb2049b5..1c430b3a14 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -395,6 +395,31 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } + if (!avatarp->isFullyLoaded()) + { + + /* // debug code to draw a cube in place of avatar + LLGLSNoTexture gls_no_texture; + LLVector3 pos = avatarp->getPositionAgent(); + + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(GL_LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + } + gGL.end(); + */ + + + // don't render please + return; + } + BOOL impostor = avatarp->isImpostor() && !single_avatar; if (impostor && pass != 0) diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index 2e971a8324..33925fa305 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -186,7 +186,10 @@ void LLFloaterAuction::onClickSnapshot(void* data) self->mTransactionID.generate(); self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - gViewerWindow->playSnapshotAnimAndSound(); + if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) + { + gViewerWindow->playSnapshotAnimAndSound(); + } llinfos << "Writing TGA..." << llendl; LLPointer<LLImageTGA> tga = new LLImageTGA; diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 22e418d60d..1d4801bd35 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -72,6 +72,7 @@ #include "lltexteditor.h" #include "llfloaterhtml.h" #include "llweb.h" +#include "llstylemap.h" // Used for LCD display extern void AddNewIMToLCD(const LLString &newLine); @@ -188,14 +189,26 @@ void LLFloaterChat::updateConsoleVisibility() || (getHost() && getHost()->isMinimized() )); // are we hosted in a minimized floater? } -void add_timestamped_line(LLViewerTextEditor* edit, const LLString& line, const LLColor4& color) +void add_timestamped_line(LLViewerTextEditor* edit, const LLChat &chat, const LLColor4& color) { + LLString line = chat.mText; bool prepend_newline = true; if (gSavedSettings.getBOOL("ChatShowTimestamps")) { edit->appendTime(prepend_newline); prepend_newline = false; } + + // If the msg is not from an agent (not yourself though), + // extract out the sender name and replace it with the hotlinked name. + if (chat.mSourceType == CHAT_SOURCE_AGENT && + chat.mFromID != LLUUID::null && + (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) + { + line = line.substr(chat.mFromName.length()); + const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID); + edit->appendStyledText(chat.mFromName, false, false, &sourceStyle); + } edit->appendColoredText(line, false, prepend_newline, color); } @@ -243,14 +256,14 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) if (!chat.mMuted) { - add_timestamped_line(history_editor, chat.mText, color); - add_timestamped_line(history_editor_with_mute, chat.mText, color); + add_timestamped_line(history_editor, chat, color); + add_timestamped_line(history_editor_with_mute, chat, color); } else { // desaturate muted chat LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f); - add_timestamped_line(history_editor_with_mute, chat.mText, color); + add_timestamped_line(history_editor_with_mute, chat, color); } // add objects as transient speakers that can be muted diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 771a6a385d..d015b88197 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -49,6 +49,8 @@ struct LLResourceData; // these flags are used to label info requests to the server const U32 BUG_REPORT_REQUEST = 0x01 << 0; const U32 COMPLAINT_REPORT_REQUEST = 0x01 << 1; +const U32 OBJECT_PAY_REQUEST = 0x01 << 2; + // ************************************************************ // THESE ENUMS ARE IN THE DATABASE!!! diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 6f31508fb8..e5b9eef72a 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -183,6 +183,7 @@ protected: LLQuaternion mCameraRot; BOOL mSnapshotActive; LLViewerWindow::ESnapshotType mSnapshotBufferType; + bool mSnapshotSoundPlayed; public: static std::set<LLSnapshotLivePreview*> sList; @@ -208,7 +209,8 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : mCameraPos(LLViewerCamera::getInstance()->getOrigin()), mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), mSnapshotActive(FALSE), - mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR) + mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR), + mSnapshotSoundPlayed(false) { mSnapshotDelayTimer.setTimerExpirySec(0.0f); mSnapshotDelayTimer.start(); @@ -764,6 +766,19 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents()); + if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) + { + // Always play the sound once, on window open. + // Don't keep playing if automatic + // updates are enabled. It's too invasive. JC + if (!previewp->mSnapshotSoundPlayed + || !gSavedSettings.getBOOL("AutoSnapshot") ) + { + gViewerWindow->playSnapshotAnimAndSound(); + previewp->mSnapshotSoundPlayed = true; + } + } + if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD) { // *FIX: just resize and reuse existing jpeg? @@ -923,7 +938,9 @@ BOOL LLSnapshotLivePreview::saveLocal() class LLFloaterSnapshot::Impl { public: - Impl() : mLastToolset(NULL) + Impl() + : mAvatarPauseHandles(), + mLastToolset(NULL) { } ~Impl() @@ -1054,7 +1071,13 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); } - if (floaterp->childGetValue("freeze_frame_check").asBoolean()) + bool use_freeze_frame = floaterp->childGetValue("freeze_frame_check").asBoolean(); + // For now, auto-snapshot only works in freeze frame mode. + // This can be changed in the future by taking the FreezeTime check + // out of the onIdle() camera movement detection. JC + floaterp->childSetEnabled("auto_snapshot_check", use_freeze_frame); + + if (use_freeze_frame) { // stop all mouse events at fullscreen preview layer floaterp->getParent()->setMouseOpaque(TRUE); @@ -1089,6 +1112,9 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) } else // turning off freeze frame mode { + // Force off auto-snapshot, see comment above about onIdle. JC + gSavedSettings.setBOOL("AutoSnapshot", FALSE); + floaterp->getParent()->setMouseOpaque(FALSE); floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); if (previewp) @@ -1287,12 +1313,6 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data) if (gSavedSettings.getBOOL("CloseSnapshotOnKeep")) { view->close(); - // only plays sound and anim when keeping a snapshot, and closing the snapshot UI, - // and only if the save succeeded (i.e. was not canceled) - if (succeeded) - { - gViewerWindow->playSnapshotAnimAndSound(); - } } else { diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 0e58363de5..55be7a199c 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -194,12 +194,16 @@ BOOL LLFloaterTools::postBuild() mBtnLand = getChild<LLButton>("button land" ); childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance()); mTextStatus = getChild<LLTextBox>("text status"); - mRadioZoom = getChild<LLCheckBoxCtrl>("radio zoom"); + childSetCommitCallback("slider zoom",commit_slider_zoom,this); + + mRadioZoom = getChild<LLCheckBoxCtrl>("radio zoom"); + childSetCommitCallback("radio zoom",commit_radio_zoom,this); mRadioOrbit = getChild<LLCheckBoxCtrl>("radio orbit"); childSetCommitCallback("radio orbit",commit_radio_orbit,this); mRadioPan = getChild<LLCheckBoxCtrl>("radio pan"); childSetCommitCallback("radio pan",commit_radio_pan,this); + mRadioMove = getChild<LLCheckBoxCtrl>("radio move"); childSetCommitCallback("radio move",click_popup_grab_drag,this); mRadioLift = getChild<LLCheckBoxCtrl>("radio lift"); @@ -492,6 +496,7 @@ void LLFloaterTools::dirty() // floater is closed. void LLFloaterTools::resetToolState() { + gCameraBtnZoom = TRUE; gCameraBtnOrbit = FALSE; gCameraBtnPan = FALSE; @@ -524,7 +529,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioOrbit ->setVisible( focus_visible ); mRadioPan ->setVisible( focus_visible ); childSetVisible("slider zoom", focus_visible); - + childSetEnabled("slider zoom", gCameraBtnZoom); + mRadioZoom ->set( !gCameraBtnOrbit && !gCameraBtnPan && !(mask == MASK_ORBIT) && @@ -867,18 +873,21 @@ void click_popup_grab_spin(LLUICtrl*, void*) void commit_radio_zoom(LLUICtrl *, void*) { + gCameraBtnZoom = TRUE; gCameraBtnOrbit = FALSE; gCameraBtnPan = FALSE; } void commit_radio_orbit(LLUICtrl *, void*) { + gCameraBtnZoom = FALSE; gCameraBtnOrbit = TRUE; gCameraBtnPan = FALSE; } void commit_radio_pan(LLUICtrl *, void*) { + gCameraBtnZoom = FALSE; gCameraBtnOrbit = FALSE; gCameraBtnPan = TRUE; } diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 087452919e..075ed81a53 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -3144,6 +3144,10 @@ void LLFolderView::draw() { closeAutoOpenedFolders(); } + if(gViewerWindow->hasKeyboardFocus(this) && !getVisible()) + { + gViewerWindow->setKeyboardFocus( NULL ); + } // while dragging, update selection rendering to reflect single/multi drag status if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 35cf36bd07..ba43352eb5 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -48,16 +48,19 @@ #include "llchat.h" #include "llconsole.h" #include "llfloater.h" +#include "llfloatergroupinfo.h" +#include "llimview.h" #include "llinventory.h" #include "llinventorymodel.h" #include "llinventoryview.h" +#include "llfloateractivespeakers.h" #include "llfloateravatarinfo.h" #include "llfloaterchat.h" #include "llkeyboard.h" #include "lllineeditor.h" +#include "llnotify.h" #include "llresmgr.h" #include "lltabcontainer.h" -#include "llimview.h" #include "llviewertexteditor.h" #include "llviewermessage.h" #include "llviewerstats.h" @@ -68,11 +71,8 @@ #include "llfloaterhtml.h" #include "llweb.h" #include "llhttpclient.h" -#include "llfloateractivespeakers.h" // LLSpeakerMgr -#include "llfloatergroupinfo.h" -#include "llsdutil.h" -#include "llnotify.h" #include "llmutelist.h" +#include "llstylemap.h" // // Constants @@ -1454,24 +1454,20 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids) return TRUE; } -void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &utf8msg, const LLColor4& color, bool log_to_file) +void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file, const LLUUID& source, const char *name) { // start tab flashing when receiving im for background session from user - LLMultiFloater* hostp = getHost(); - if( !isInVisibleChain() - && hostp - && source != gAgent.getID()) + if (source != LLUUID::null) { - hostp->setFloaterFlashing(this, TRUE); + LLMultiFloater* hostp = getHost(); + if( !isInVisibleChain() + && hostp + && source != gAgent.getID()) + { + hostp->setFloaterFlashing(this, TRUE); + } } - addHistoryLine(utf8msg, color, log_to_file); - mSpeakers->speakerChatted(source); - mSpeakers->setSpeakerTyping(source, FALSE); -} - -void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file) -{ // Now we're adding the actual line of text, so erase the // "Foo is typing..." text segment, and the optional timestamp // if it was present. JC @@ -1485,6 +1481,22 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 timestring = mHistoryEditor->appendTime(prepend_newline); prepend_newline = false; } + + // 'name' is a sender name that we want to hotlink so that clicking on it opens a profile. + if (name != NULL) // If name exists, then add it to the front of the message. + { + // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. + if (!strcmp(name,SYSTEM_FROM)) + { + mHistoryEditor->appendColoredText(name,false,false,color); + } + else + { + // Convert the name to a hotlink and add to message. + const LLStyleSP &source_style = LLStyleMap::instance().lookup(source); + mHistoryEditor->appendStyledText(name, false, false, &source_style); + } + } mHistoryEditor->appendColoredText(utf8msg, false, prepend_newline, color); if (log_to_file @@ -1492,9 +1504,9 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 { LLString histstr; if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp")) - histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + utf8msg; + histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + LLString(name) + utf8msg; else - histstr = utf8msg; + histstr = LLString(name) + utf8msg; LLLogChat::saveHistory(getTitle(),histstr); } @@ -1503,6 +1515,12 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 { mNumUnreadMessages++; } + + if (source != LLUUID::null) + { + mSpeakers->speakerChatted(source); + mSpeakers->setSpeakerTyping(source, FALSE); + } } @@ -1836,6 +1854,11 @@ void deliver_message(const std::string& utf8_text, (EInstantMessage)new_dialog, im_session_id); gAgent.sendReliableMessage(); + + if (LLMuteList::getInstance()) + { + LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); + } } void LLFloaterIMPanel::sendMsg() @@ -1888,7 +1911,7 @@ void LLFloaterIMPanel::sendMsg() BOOL other_was_typing = mOtherTyping; - addHistoryLine(gAgent.getID(), history_echo, gSavedSettings.getColor("IMChatColor")); + addHistoryLine(history_echo, gSavedSettings.getColor("IMChatColor"), true, gAgent.getID()); if (other_was_typing) { @@ -2189,4 +2212,3 @@ void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data) } - diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index c5bb8956cd..a3ece98727 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -38,6 +38,7 @@ #include "lldarray.h" #include "llinstantmessage.h" #include "llvoiceclient.h" +#include "llstyle.h" class LLLineEditor; class LLViewerTextEditor; @@ -202,13 +203,12 @@ public: // Return TRUE if successful, otherwise FALSE. BOOL inviteToSession(const LLDynamicArray<LLUUID>& agent_ids); - void addHistoryLine(const LLUUID& source, - const std::string &utf8msg, - const LLColor4& color = LLColor4::white, - bool log_to_file = true); void addHistoryLine(const std::string &utf8msg, const LLColor4& color = LLColor4::white, - bool log_to_file = true); + bool log_to_file = true, + const LLUUID& source = LLUUID::null, + const char *name = NULL); + void setInputFocus( BOOL b ); void selectAll(); @@ -357,6 +357,9 @@ private: LLFrameTimer mLastKeystrokeTimer; void disableWhileSessionStarting(); + + typedef std::map<LLUUID, LLStyleSP> styleMap; + static styleMap mStyleMap; }; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 536f4b44da..75aacabeea 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -83,6 +83,7 @@ LLIMMgr* gIMMgr = NULL; // *FIXME: make these all either UIStrings or Strings static LLString sOnlyUserMessage; static LLUIString sOfflineMessage; +static LLString sMutedMessage; static LLUIString sInviteMessage; std::map<std::string,LLString> LLFloaterIM::sEventStringsMap; @@ -161,6 +162,7 @@ BOOL LLFloaterIM::postBuild() sOfflineMessage = getUIString("offline_message"); sInviteMessage = getUIString("invite_message"); + sMutedMessage = childGetText("muted_message"); if ( sErrorStringsMap.find("generic") == sErrorStringsMap.end() ) { @@ -400,10 +402,10 @@ void LLIMMgr::addMessage( EInstantMessage dialog, U32 parent_estate_id, const LLUUID& region_id, - const LLVector3& position) + const LLVector3& position, + bool link_name) // If this is true, then we insert the name and link it to a profile { LLUUID other_participant_id = target_id; - bool is_from_system = target_id.isNull() || !strcmp(from, SYSTEM_FROM); // don't process muted IMs if (LLMuteList::getInstance()->isMuted( @@ -420,8 +422,6 @@ void LLIMMgr::addMessage( other_participant_id = LLUUID::null; } - - LLFloaterIMPanel* floater; LLUUID new_session_id = session_id; if (new_session_id.isNull()) @@ -482,15 +482,17 @@ void LLIMMgr::addMessage( } // now add message to floater - if ( is_from_system ) // chat came from system + bool is_from_system = target_id.isNull() || !strcmp(from, SYSTEM_FROM); + const LLColor4& color = ( is_from_system ? + gSavedSettings.getColor4("SystemChatColor") : + gSavedSettings.getColor("IMChatColor")); + if ( !link_name ) { - floater->addHistoryLine( - msg, - gSavedSettings.getColor4("SystemChatColor")); + floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally } else { - floater->addHistoryLine(other_participant_id, msg, gSavedSettings.getColor("IMChatColor")); + floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message } LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(LLSD()); @@ -615,6 +617,8 @@ LLUUID LLIMMgr::addSession( noteOfflineUsers(floater, ids); LLFloaterChatterBox::showInstance(session_id); + noteMutedUsers(floater, ids); + LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater); } else { @@ -659,6 +663,7 @@ LLUUID LLIMMgr::addSession( noteOfflineUsers(floater, ids); LLFloaterChatterBox::showInstance(session_id); + noteMutedUsers(floater, ids); } else { @@ -1232,6 +1237,31 @@ void LLIMMgr::noteOfflineUsers( } } +void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater, + const LLDynamicArray<LLUUID>& ids) +{ + S32 count = ids.count(); + if(count > 0) + { + const LLRelationship* info = NULL; + LLAvatarTracker& at = LLAvatarTracker::instance(); + for(S32 i = 0; i < count; ++i) + { + info = at.getBuddyInfo(ids.get(i)); + char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + if(info && LLMuteList::getInstance() && LLMuteList::getInstance()->isMuted(ids.get(i)) + && gCacheName->getName(ids.get(i), first, last)) + { + LLUIString muted = sMutedMessage; + muted.setArg("[FIRST]", first); + muted.setArg("[LAST]", last); + floater->addHistoryLine(muted); + } + } + } +} + void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info) { processIMTypingCore(im_info, TRUE); @@ -1520,8 +1550,7 @@ public: snprintf( buffer, sizeof(buffer), - "%s%s%s%s", - name.c_str(), + "%s%s%s", separator_string, saved, (message.c_str() + message_offset)); /*Flawfinder: ignore*/ @@ -1540,7 +1569,8 @@ public: IM_SESSION_INVITE, message_params["parent_estate_id"].asInteger(), message_params["region_id"].asUUID(), - ll_vector3_from_sd(message_params["position"])); + ll_vector3_from_sd(message_params["position"]), + true); snprintf( buffer, @@ -1628,4 +1658,3 @@ LLHTTPRegistration<LLViewerChatterBoxInvitation> gHTTPRegistrationMessageChatterBoxInvitation( "/message/ChatterBoxInvitation"); - diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index e787368324..91768132ed 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -65,7 +65,8 @@ public: EInstantMessage dialog = IM_NOTHING_SPECIAL, U32 parent_estate_id = 0, const LLUUID& region_id = LLUUID::null, - const LLVector3& position = LLVector3::zero); + const LLVector3& position = LLVector3::zero, + bool link_name = false); void addSystemMessage(const LLUUID& session_id, const LLString& message_name, const LLString::format_map_t& args); @@ -192,6 +193,7 @@ private: // reduce 'hello' messages to the linden employees unlucky enough // to have their calling card in the default inventory. void noteOfflineUsers(LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids); + void noteMutedUsers(LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids); void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 24eb9ee34a..6edd9d0b7d 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -62,6 +62,12 @@ #include "llviewergenericmessage.h" // for gGenericDispatcher #include "llviewerwindow.h" #include "llworld.h" //for particle system banning +#include "llchat.h" +#include "llfloaterchat.h" +#include "llimpanel.h" +#include "llimview.h" +#include "llnotify.h" +#include "lluistring.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -437,6 +443,78 @@ void LLMuteList::updateRemove(const LLMute& mute) gAgent.sendReliableMessage(); } +void notify_automute_callback(const LLUUID& agent_id, const char* first_name, const char* last_name, BOOL is_group, void* user_data) +{ + U32 temp_data = (U32)user_data; + LLMuteList::EAutoReason reason = (LLMuteList::EAutoReason)temp_data; + LLUIString auto_message; + + switch (reason) + { + default: + case LLMuteList::AR_IM: + auto_message = LLNotifyBox::getTemplateMessage("AutoUnmuteByIM"); + break; + case LLMuteList::AR_INVENTORY: + auto_message = LLNotifyBox::getTemplateMessage("AutoUnmuteByInventory"); + break; + case LLMuteList::AR_MONEY: + auto_message = LLNotifyBox::getTemplateMessage("AutoUnmuteByMoney"); + break; + } + + auto_message.setArg("[FIRST]", first_name); + auto_message.setArg("[LAST]", last_name); + + if (reason == LLMuteList::AR_IM) + { + LLFloaterIMPanel *timp = gIMMgr->findFloaterBySession(agent_id); + if (timp) + { + timp->addHistoryLine(auto_message.getString()); + } + } + + LLChat auto_chat(auto_message.getString()); + LLFloaterChat::addChat(auto_chat, FALSE, FALSE); +} + + +BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, const LLString& first_name, const LLString& last_name) +{ + BOOL removed = FALSE; + + if (isMuted(agent_id)) + { + LLMute automute(agent_id, "", LLMute::AGENT); + removed = TRUE; + remove(automute); + + if (first_name.empty() && last_name.empty()) + { + char cache_first[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ + char cache_last[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ + if (gCacheName->getName(agent_id, cache_first, cache_last)) + { + // name in cache, call callback directly + notify_automute_callback(agent_id, cache_first, cache_last, FALSE, (void *)reason); + } + else + { + // not in cache, lookup name from cache + gCacheName->get(agent_id, FALSE, notify_automute_callback, (void *)reason); + } + } + else + { + // call callback directly + notify_automute_callback(agent_id, first_name.c_str(), last_name.c_str(), FALSE, (void *)reason); + } + } + + return removed; +} + std::vector<LLMute> LLMuteList::getMutes() const { diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index dc69e98286..5f2306e0a6 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -82,6 +82,15 @@ public: class LLMuteList : public LLSingleton<LLMuteList> { public: + // reasons for auto-unmuting a resident + enum EAutoReason + { + AR_IM = 0, // agent IMed a muted resident + AR_MONEY = 1, // agent paid L$ to a muted resident + AR_INVENTORY = 2, // agent offered inventory to a muted resident + AR_COUNT // enum count + }; + LLMuteList(); ~LLMuteList(); @@ -98,6 +107,7 @@ public: // Remove both normal and legacy mutes, for any or all properties. BOOL remove(const LLMute& mute, U32 flags = 0); + BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason, const LLString& first_name = "", const LLString& last_name = ""); // Name is required to test against legacy text-only mutes. BOOL isMuted(const LLUUID& id, const LLString& name = LLString::null, U32 flags = 0) const; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 07e65e3d54..9b86690088 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -67,9 +67,10 @@ #include "llviewerstats.h" #include "llviewerwindow.h" // busycount #include "llappviewer.h" // gVFS - +#include "llanimstatelabels.h" #include "llresmgr.h" + // *TODO: Translate? const char NONE_LABEL[] = "---"; const char SHIFT_LABEL[] = "Shift"; @@ -592,7 +593,7 @@ void LLPreviewGesture::addAnimations() for (i = 0; i < gUserAnimStatesCount; ++i) { // Use the user-readable name - const char* label = gUserAnimStates[i].mLabel; + std::string label = LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ); const LLUUID& id = gUserAnimStates[i].mID; combo->add(label, id); } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index cd59c8e300..abda5067e5 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -62,6 +62,7 @@ #include "llhudmanager.h" #include "llinventorymodel.h" #include "llmenugl.h" +#include "llmutelist.h" #include "llstatusbar.h" #include "llsurface.h" #include "lltool.h" @@ -4442,6 +4443,11 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use reporterp->setPickedObjectProperties(name, fullname, owner_id); } } + else if (request_flags & OBJECT_PAY_REQUEST) + { + // check if the owner of the paid object is muted + LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY); + } // Now look through all of the hovered nodes struct f : public LLSelectedNodeFunctor diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 139ab8f1aa..7d9bab59df 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -127,6 +127,7 @@ #include "llsky.h" #include "llsrv.h" #include "llstatview.h" +#include "lltrans.h" #include "llsurface.h" #include "lltexturecache.h" #include "lltexturefetch.h" @@ -884,7 +885,7 @@ BOOL idle_startup() // Poke the VFS, which could potentially block for a while if // Windows XP is acting up - set_startup_status(0.07f, "Verifying cache files (can take 60-90 seconds)...", NULL); + set_startup_status(0.07f, LLTrans::getString("LoginVerifyingCache").c_str(), NULL); display_startup(); gVFS->pokeFiles(); @@ -953,9 +954,10 @@ BOOL idle_startup() } sAuthUriNum = 0; auth_method = "login_to_simulator"; - auth_desc = "Logging in. "; - auth_desc += LLAppViewer::instance()->getSecondLifeTitle(); - auth_desc += " may appear frozen. Please wait."; + + LLString::format_map_t args; + args["[APP_NAME]"] = LLAppViewer::instance()->getSecondLifeTitle(); + auth_desc = LLTrans::getString("LoginInProgress", args).c_str(); LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); } @@ -1061,7 +1063,7 @@ BOOL idle_startup() } LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE ); progress += 0.01f; - set_startup_status(progress, "Processing Response...", auth_message.c_str()); + set_startup_status(progress, LLTrans::getString("LoginProcessingResponse").c_str(), auth_message.c_str()); return do_normal_idle; } @@ -1096,11 +1098,11 @@ BOOL idle_startup() auth_message = LLUserAuth::getInstance()->getResponse("message"); if(auth_method.substr(0, 5) == "login") { - auth_desc.assign("Authenticating..."); + auth_desc.assign(LLTrans::getString("LoginAuthenticating").c_str()); } else { - auth_desc.assign("Performing account maintenance..."); + auth_desc.assign(LLTrans::getString("LoginMaintenance").c_str()); } // ignoring the duration & options array for now. // Go back to authenticate. @@ -1213,9 +1215,9 @@ BOOL idle_startup() } else { sAuthUriNum++; std::ostringstream s; - s << "Previous login attempt failed. Logging in, attempt " - << (sAuthUriNum + 1) << ". "; - auth_desc = s.str(); + LLString::format_map_t args; + args["[NUMBER]"] = sAuthUriNum + 1; + auth_desc = LLTrans::getString("LoginAttempt", args).c_str(); LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); return do_normal_idle; } @@ -1493,7 +1495,7 @@ BOOL idle_startup() //--------------------------------------------------------------------- if (STATE_WORLD_INIT == LLStartUp::getStartupState()) { - set_startup_status(0.40f, "Initializing World...", gAgent.mMOTD.c_str()); + set_startup_status(0.40f, LLTrans::getString("LoginInitializingWorld").c_str(), gAgent.mMOTD.c_str()); display_startup(); // We should have an agent id by this point. llassert(!(gAgentID == LLUUID::null)); @@ -1709,7 +1711,7 @@ BOOL idle_startup() for (int i = 0; i < DECODE_TIME_SEC; i++) { F32 frac = (F32)i / (F32)DECODE_TIME_SEC; - set_startup_status(0.45f + frac*0.1f, "Decoding images...", gAgent.mMOTD.c_str()); + set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages").c_str(), gAgent.mMOTD.c_str()); display_startup(); gImageList.decodeAllImages(1.f); } @@ -1754,7 +1756,7 @@ BOOL idle_startup() if(STATE_WORLD_WAIT == LLStartUp::getStartupState()) { //llinfos << "Waiting for simulator ack...." << llendl; - set_startup_status(0.59f, "Waiting for region handshake...", gAgent.mMOTD.c_str()); + set_startup_status(0.59f, LLTrans::getString("LoginWaitingForRegionHandshake").c_str(), gAgent.mMOTD.c_str()); if(gGotUseCircuitCodeAck) { LLStartUp::setStartupState( STATE_AGENT_SEND ); @@ -1773,7 +1775,7 @@ BOOL idle_startup() if (STATE_AGENT_SEND == LLStartUp::getStartupState()) { llinfos << "Connecting to region..." << llendl; - set_startup_status(0.60f, "Connecting to region...", gAgent.mMOTD.c_str()); + set_startup_status(0.60f, LLTrans::getString("LoginConnectingToRegion").c_str(), gAgent.mMOTD.c_str()); // register with the message system so it knows we're // expecting this message LLMessageSystem* msg = gMessageSystem; @@ -2249,7 +2251,7 @@ BOOL idle_startup() { update_texture_fetch(); set_startup_status(0.f + 0.25f * wearables_time / MAX_WEARABLES_TIME, - "Downloading clothing...", + LLTrans::getString("LoginDownloadingClothing").c_str(), gAgent.mMOTD.c_str()); } return do_normal_idle; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 5d6ab669f4..94f8b8ae67 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -429,26 +429,18 @@ void LLStatusBar::refresh() childSetVisible("restrictpush", FALSE); } - BOOL voice_enabled = gVoiceClient->voiceEnabled(); BOOL have_voice = parcel && parcel->getVoiceEnabled(); - if (!voice_enabled) + if (have_voice) { childSetVisible("status_no_voice", FALSE); } else { - if (have_voice) - { - childSetVisible("status_no_voice", FALSE); - } - else if (!have_voice) - { - childSetVisible("status_no_voice", TRUE); - childGetRect( "status_no_voice", buttonRect ); - r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight()); - childSetRect( "status_no_voice", r ); - x += buttonRect.getWidth(); - } + childSetVisible("status_no_voice", TRUE); + childGetRect( "status_no_voice", buttonRect ); + r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight()); + childSetRect( "status_no_voice", r ); + x += buttonRect.getWidth(); } BOOL canBuyLand = parcel diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp new file mode 100644 index 0000000000..09578a011a --- /dev/null +++ b/indra/newview/llstylemap.cpp @@ -0,0 +1,75 @@ +/** + * @file llstylemap.cpp + * @brief LLStyleMap class implementation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llstylemap.h" +#include "llstring.h" +#include "llui.h" +#include "llviewercontrol.h" +#include "llagent.h" + +LLStyleMap::LLStyleMap() +{ +} + +LLStyleMap::~LLStyleMap() +{ +} + +LLStyleMap &LLStyleMap::instance() +{ + static LLStyleMap mStyleMap; + return mStyleMap; +} + +// This is similar to the [] accessor except that if the entry doesn't already exist, +// then this will create the entry. +const LLStyleSP &LLStyleMap::lookup(const LLUUID &source) +{ + // Find this style in the map or add it if not. This map holds links to residents' profiles. + if (find(source) == end()) + { + LLStyleSP style(new LLStyle); + style->setVisible(true); + style->setFontName(LLString::null); + if (source != gAgent.getID() && source != LLUUID::null) + { + style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); + LLString link = llformat("secondlife:///app/agent/%s/about",source.asString().c_str()); + style->setLinkHREF(link); + } + else + style->setColor(LLColor4::white); + (*this)[source] = style; + } + return (*this)[source]; +} diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h new file mode 100644 index 0000000000..4cff69fc73 --- /dev/null +++ b/indra/newview/llstylemap.h @@ -0,0 +1,54 @@ +/** + * @file LLStyleMap.h + * @brief LLStyleMap class definition + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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_LLSTYLE_MAP_H +#define LL_LLSTYLE_MAP_H + +#include "llstyle.h" +#include "lluuid.h" + +// Lightweight class for holding and managing mappings between UUIDs and links. +// Used (for example) to create clickable name links off of IM chat. + +typedef std::map<LLUUID, LLStyleSP> style_map_t; + +class LLStyleMap : public style_map_t +{ +public: + LLStyleMap(); + ~LLStyleMap(); + // Just like the [] accessor but it will add the entry in if it doesn't exist. + const LLStyleSP &lookup(const LLUUID &source); + static LLStyleMap &instance(); +}; + +#endif // LL_LLSTYLE_MAP_H diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 606bc75103..1ab1b15108 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -288,10 +288,15 @@ void LLToolBar::refresh() // Clothing button updated inside LLFloaterClothing - childSetEnabled("fly_btn", gAgent.canFly() || gAgent.getFlying() ); + BOOL sitting = FALSE; + if (gAgent.getAvatarObject()) + { + sitting = gAgent.getAvatarObject()->mIsSitting; + } - childSetEnabled("build_btn", LLViewerParcelMgr::getInstance()->agentCanBuild() ); + childSetEnabled("fly_btn", (gAgent.canFly() || gAgent.getFlying()) && !sitting ); + childSetEnabled("build_btn", LLViewerParcelMgr::getInstance()->agentCanBuild() ); // Check to see if we're in build mode BOOL build_mode = LLToolMgr::getInstance()->inEdit(); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 2f937822cf..8574448dce 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -47,6 +47,7 @@ #include "llhudmanager.h" #include "llinventorymodel.h" #include "llinventoryview.h" +#include "llmutelist.h" #include "llnotify.h" #include "llpreviewnotecard.h" #include "llselectmgr.h" @@ -1693,6 +1694,8 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent, effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); gFloaterTools->dirty(); + + LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); } void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent, @@ -1895,6 +1898,8 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent, effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); gFloaterTools->dirty(); + + LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); } } diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index e2985a0141..7b1394461a 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -57,6 +57,7 @@ #include "llmorphview.h" // Globals +BOOL gCameraBtnZoom = TRUE; BOOL gCameraBtnOrbit = FALSE; BOOL gCameraBtnPan = FALSE; @@ -403,7 +404,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) } lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPan" << llendl; } - else + else if (gCameraBtnZoom) { // Zoom tool if (hasMouseCapture()) diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index 71df8078e6..2ed456b188 100644 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -77,5 +77,6 @@ protected: extern BOOL gCameraBtnOrbit; extern BOOL gCameraBtnPan; +extern BOOL gCameraBtnZoom; #endif diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2cb60785d3..0a7a14dbfa 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3163,6 +3163,21 @@ class LLWorldFly : public view_listener_t } }; +class LLWorldEnableFly : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + BOOL sitting = FALSE; + if (gAgent.getAvatarObject()) + { + sitting = gAgent.getAvatarObject()->mIsSitting; + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(!sitting); + return true; + } +}; + + void handle_agent_stop_moving(void*) { // stop agent @@ -7766,6 +7781,7 @@ void initialize_menus() addMenu(new LLWorldChat(), "World.Chat"); addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); addMenu(new LLWorldFly(), "World.Fly"); + addMenu(new LLWorldEnableFly(), "World.EnableFly"); addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation"); addMenu(new LLWorldTeleportHome(), "World.TeleportHome"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index cb2630380c..6a0b5280ab 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -414,18 +414,6 @@ class LLFileTakeSnapshotToDisk : public view_listener_t } }; -class LLFileSetWindowSize : public view_listener_t -{ - bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) - { - LLString size = userdata.asString(); - S32 width, height; - sscanf(size.c_str(), "%d,%d", &width, &height); - LLViewerWindow::movieSize(width, height); - return true; - } -}; - class LLFileQuit : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -1024,7 +1012,6 @@ void init_menu_file() (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); - (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize"); (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 8afb0879a3..c157b5790c 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1426,7 +1426,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // now store incoming IM in chat history - snprintf(buffer, sizeof(buffer), "%s%s%s", name, separator_string, (message+message_offset)); /* Flawfinder: ignore */ + snprintf(buffer, sizeof(buffer), "%s%s", separator_string, (message+message_offset)); /* Flawfinder: ignore */ llinfos << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << llendl; @@ -1440,7 +1440,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) dialog, parent_estate_id, region_id, - position); + position, + true); // pretend this is chat generated by self, so it does not show up on screen snprintf(buffer, sizeof(buffer), "IM: %s%s%s", name, separator_string, (message+message_offset)); /* Flawfinder: ignore */ @@ -1481,7 +1482,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) snprintf(saved, MAX_STRING, "(Saved %s) ", /* Flawfinder: ignore */ formatted_time(timestamp, time_buf)); } - snprintf(buffer, sizeof(buffer), "%s%s%s%s", name, separator_string, saved,(message+message_offset)); /* Flawfinder: ignore */ + snprintf(buffer, sizeof(buffer), "%s%s%s", separator_string, saved,(message+message_offset)); /* Flawfinder: ignore */ llinfos << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << llendl; @@ -1496,7 +1497,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) dialog, parent_estate_id, region_id, - position); + position, + true); snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */ chat.mText = buffer; @@ -1776,7 +1778,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) "(Saved %s) ", formatted_time(timestamp, time_buf)); } - snprintf(buffer, sizeof(buffer), "%s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */ + snprintf(buffer, sizeof(buffer), "%s%s%s", separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */ BOOL is_this_agent = FALSE; if(from_id == gAgentID) { @@ -1791,7 +1793,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) IM_SESSION_INVITE, parent_estate_id, region_id, - position); + position, + true); snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */ chat.mText = buffer; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 30668172f1..227a0d9ebe 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4068,6 +4068,37 @@ BOOL LLViewerObject::isParticleSource() const return !mPartSourcep.isNull() && !mPartSourcep->isDead(); } +void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id) +{ + if (mPartSourcep) + { + deleteParticleSource(); + } + + LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::createPSS(this, particle_parameters); + mPartSourcep = pss; + + if (mPartSourcep) + { + mPartSourcep->setOwnerUUID(owner_id); + + if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) + { + LLViewerImage* image; + if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) + { + image = gImageList.getImageFromFile("pixiesmall.tga"); + } + else + { + image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + } + mPartSourcep->setImage(image); + } + } + LLViewerPartSim::getInstance()->addPartSource(pss); +} + void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id) { if (!mPartSourcep.isNull() && mPartSourcep->isDead()) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 20616b32d6..ed38911d4e 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -558,6 +558,7 @@ protected: void unpackParticleSource(const S32 block_num, const LLUUID& owner_id); void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id); void deleteParticleSource(); + void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index 7e9f3e2fa9..b6f16d1002 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -466,6 +466,25 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer } } + +/* static */ +LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters) +{ + LLMemType mt(LLMemType::MTYPE_PARTICLES); + + LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp); + + new_pssp->mPartSysData = particle_parameters; + + if (new_pssp->mPartSysData.mTargetUUID.notNull()) + { + LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID); + new_pssp->setTargetObject(target_objp); + } + return new_pssp; +} + + void LLViewerPartSourceScript::setImage(LLViewerImage *imagep) { LLMemType mt(LLMemType::MTYPE_PARTICLES); diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h index 7a49a919bc..303eef1230 100644 --- a/indra/newview/llviewerpartsource.h +++ b/indra/newview/llviewerpartsource.h @@ -119,6 +119,7 @@ public: // Returns a new particle source to attach to an object... static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num); static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp); + static LLPointer<LLViewerPartSourceScript> createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters); LLViewerImage *getImage() const { return mImagep; } void setImage(LLViewerImage *imagep); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 17b79fecdf..771f6615cf 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -631,7 +631,7 @@ BOOL LLViewerTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* stic if( cur_segment ) { BOOL has_tool_tip = FALSE; - if( cur_segment->getStyle().getIsEmbeddedItem() ) + if( cur_segment->getStyle()->getIsEmbeddedItem() ) { LLWString wtip; has_tool_tip = getEmbeddedItemToolTipAtPos(cur_segment->getStart(), wtip); @@ -851,14 +851,14 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { - if(cur_segment->getStyle().isLink()) + if(cur_segment->getStyle()->isLink()) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl; getWindow()->setCursor(UI_CURSOR_HAND); handled = TRUE; } else - if(cur_segment->getStyle().getIsEmbeddedItem()) + if(cur_segment->getStyle()->getIsEmbeddedItem()) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl; getWindow()->setCursor(UI_CURSOR_HAND); @@ -970,10 +970,10 @@ BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) // const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); // if( cur_segment ) // { -// if(cur_segment->getStyle().isLink()) +// if(cur_segment->getStyle()->isLink()) // { // handled = TRUE; -// mHTML = cur_segment->getStyle().getLinkHREF(); +// mHTML = cur_segment->getStyle()->getLinkHREF(); // } // } // } @@ -1008,7 +1008,7 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) if( allowsEmbeddedItems() ) { const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); - if( cur_segment && cur_segment->getStyle().getIsEmbeddedItem() ) + if( cur_segment && cur_segment->getStyle()->getIsEmbeddedItem() ) { if( openEmbeddedItemAtPos( cur_segment->getStart() ) ) { @@ -1598,7 +1598,7 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF text_editor->initFromXML(node, parent); // add text after all parameters have been set - text_editor->appendStyledText(text, FALSE, FALSE, NULL); + text_editor->appendStyledText(text, FALSE, FALSE); return text_editor; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2c283faf3b..b3f8c6d5eb 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4184,8 +4184,9 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) if ( (size.mX != new_width + BORDERWIDTH) ||(size.mY != new_height + BORDERHEIGHT)) { - S32 x = gViewerWindow->getWindowWidth(); - S32 y = gViewerWindow->getWindowHeight(); + // use actual display dimensions, not virtual UI dimensions + S32 x = gViewerWindow->getWindowDisplayWidth(); + S32 y = gViewerWindow->getWindowDisplayHeight(); BORDERWIDTH = size.mX - x; BORDERHEIGHT = size.mY- y; LLCoordScreen new_size(new_width + BORDERWIDTH, diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e785c93f19..afe5f5f9fb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -117,6 +117,7 @@ #include "llglslshader.h" #include "llappviewer.h" #include "llsky.h" +#include "llanimstatelabels.h" //#include "vtune/vtuneapi.h" @@ -678,7 +679,8 @@ LLVOAvatar::LLVOAvatar( mTexHairColor( NULL ), mTexEyeColor( NULL ), mNeedsSkin(FALSE), - mUpdatePeriod(1) + mUpdatePeriod(1), + mFullyLoadedInitialized(FALSE) { LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -2752,6 +2754,47 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) dirtyMesh(); } + // update visibility when avatar is partially loaded + if (updateIsFullyLoaded()) // changed? + { + if (isFullyLoaded()) + { + deleteParticleSource(); + } + else + { + LLPartSysData particle_parameters; + + // fancy particle cloud designed by Brent + particle_parameters.mPartData.mMaxAge = 4.f; + particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; + particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; + particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f; + particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f; + particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f; + particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); + particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); + particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; + LLViewerImage* cloud = gImageList.getImageFromFile("cloud-particle.j2c"); + particle_parameters.mPartImageID = cloud->getID(); + particle_parameters.mMaxAge = 0.f; + particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; + particle_parameters.mInnerAngle = 3.14159f; + particle_parameters.mOuterAngle = 0.f; + particle_parameters.mBurstRate = 0.02f; + particle_parameters.mBurstRadius = 0.0f; + particle_parameters.mBurstPartCount = 1; + particle_parameters.mBurstSpeedMin = 0.1f; + particle_parameters.mBurstSpeedMax = 1.f; + particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | + LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | + LLPartData::LL_PART_TARGET_POS_MASK ); + + setParticleSource(particle_parameters, getID()); + } + } + + // update wind effect if ((LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)) { @@ -6685,6 +6728,89 @@ BOOL LLVOAvatar::isVisible() } +// call periodically to keep isFullyLoaded up to date. +// returns true if the value has changed. +BOOL LLVOAvatar::updateIsFullyLoaded() +{ + // a "heuristic" to determine if we have enough avatar data to render + // (to avoid rendering a "Ruth" - DEV-3168) + + BOOL loading = FALSE; + + // do we have a shape? + if (visualParamWeightsAreDefault()) + { + loading = TRUE; + } + + // are our texture settings still default? + if ((getTEImage( TEX_HAIR )->getID() == IMG_DEFAULT)) + { + loading = TRUE; + } + + // special case to keep nudity off orientation island - + // this is fragilely dependent on the compositing system, + // which gets available textures in the following order: + // + // 1) use the baked texture + // 2) use the layerset + // 3) use the previously baked texture + // + // on orientation island case (3) can show naked skin. + // so we test for that here: + // + // if we were previously unloaded, and we don't have enough + // texture info for our shirt/pants, stay unloaded: + if (!mPreviousFullyLoaded) + { + if ((!isLocalTextureDataAvailable(mLowerBodyLayerSet)) && + (getTEImage(TEX_LOWER_BAKED)->getID() == IMG_DEFAULT_AVATAR)) + { + loading = TRUE; + } + + if ((!isLocalTextureDataAvailable(mUpperBodyLayerSet)) && + (getTEImage(TEX_UPPER_BAKED)->getID() == IMG_DEFAULT_AVATAR)) + { + loading = TRUE; + } + } + + + // we wait a little bit before giving the all clear, + // to let textures settle down + const F32 PAUSE = 1.f; + if (loading) + mFullyLoadedTimer.reset(); + + mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); + + + // did our loading state "change" from last call? + const S32 UPDATE_RATE = 30; + BOOL changed = + ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call + (!mFullyLoadedInitialized) || // if we've never been called before + (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change + + mPreviousFullyLoaded = mFullyLoaded; + mFullyLoadedInitialized = TRUE; + mFullyLoadedFrameCounter++; + + return changed; +} + + +BOOL LLVOAvatar::isFullyLoaded() +{ + if (gSavedSettings.getBOOL("RenderUnloadedAvatar")) + return TRUE; + else + return mFullyLoaded; +} + + //----------------------------------------------------------------------------- // findMotion() //----------------------------------------------------------------------------- @@ -8337,12 +8463,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } // static -void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels ) +void LLVOAvatar::getAnimLabels( LLDynamicArray<std::string>* labels ) { S32 i; for( i = 0; i < gUserAnimStatesCount; i++ ) { - labels->put( gUserAnimStates[i].mLabel ); + labels->put( LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ) ); } // Special case to trigger away (AFK) state @@ -8350,13 +8476,13 @@ void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels ) } // static -void LLVOAvatar::getAnimNames( LLDynamicArray<const char*>* names ) +void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names ) { S32 i; for( i = 0; i < gUserAnimStatesCount; i++ ) { - names->put( gUserAnimStates[i].mName ); + names->put( std::string(gUserAnimStates[i].mName) ); } // Special case to trigger away (AFK) state diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 8b742f153c..0d495311e7 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -413,8 +413,8 @@ public: //-------------------------------------------------------------------- BOOL allocateCollisionVolumes( U32 num ); void resetHUDAttachments(); - static void getAnimLabels( LLDynamicArray<const char*>* labels ); - static void getAnimNames( LLDynamicArray<const char*>* names ); + static void getAnimLabels( LLDynamicArray<std::string>* labels ); + static void getAnimNames( LLDynamicArray<std::string>* names ); static void onCustomizeStart(); static void onCustomizeEnd(); @@ -968,7 +968,21 @@ protected: static LLVOAvatarSkeletonInfo* sSkeletonInfo; static LLVOAvatarInfo* sAvatarInfo; + + //-------------------------------------------------------------------- + // Handling partially loaded avatars (Ruth) + //-------------------------------------------------------------------- +public: + BOOL isFullyLoaded(); + BOOL updateIsFullyLoaded(); +private: + BOOL mFullyLoaded; + BOOL mPreviousFullyLoaded; + BOOL mFullyLoadedInitialized; + S32 mFullyLoadedFrameCounter; + LLFrameTimer mFullyLoadedTimer; + protected: BOOL loadSkeletonNode(); |