From 36fccc3888c5dc318a8a235da8a5cae4faeb637d Mon Sep 17 00:00:00 2001 From: James Cook Date: Wed, 30 Apr 2008 23:30:09 +0000 Subject: svn merge -r 86190:86191 maint-ui-11-merge (EFFECTIVE MERGE: -r 84579:85724 maint-ui-11-qa). --- indra/newview/app_settings/settings.xml | 11 +++ indra/newview/llanimstatelabels.cpp | 39 +++++++++ indra/newview/llanimstatelabels.h | 42 ++++++++++ indra/newview/llappviewer.cpp | 2 + indra/newview/llchatbar.cpp | 1 + indra/newview/lldrawable.cpp | 6 +- indra/newview/lldrawpoolavatar.cpp | 25 ++++++ indra/newview/llfloaterauction.cpp | 5 +- indra/newview/llfloaterchat.cpp | 21 ++++- indra/newview/llfloaterreporter.h | 2 + indra/newview/llfloatersnapshot.cpp | 38 ++++++--- indra/newview/llfloatertools.cpp | 13 ++- indra/newview/llfolderview.cpp | 4 + indra/newview/llimpanel.cpp | 66 ++++++++++------ indra/newview/llimpanel.h | 13 +-- indra/newview/llimview.cpp | 55 ++++++++++--- indra/newview/llimview.h | 4 +- indra/newview/llmutelist.cpp | 78 ++++++++++++++++++ indra/newview/llmutelist.h | 10 +++ indra/newview/llpreviewgesture.cpp | 5 +- indra/newview/llselectmgr.cpp | 6 ++ indra/newview/llstartup.cpp | 32 ++++---- indra/newview/llstatusbar.cpp | 20 ++--- indra/newview/llstylemap.cpp | 75 ++++++++++++++++++ indra/newview/llstylemap.h | 54 +++++++++++++ indra/newview/lltoolbar.cpp | 9 ++- indra/newview/lltooldraganddrop.cpp | 5 ++ indra/newview/lltoolfocus.cpp | 3 +- indra/newview/lltoolfocus.h | 1 + indra/newview/llviewermenu.cpp | 16 ++++ indra/newview/llviewermenufile.cpp | 13 --- indra/newview/llviewermessage.cpp | 15 ++-- indra/newview/llviewerobject.cpp | 31 ++++++++ indra/newview/llviewerobject.h | 1 + indra/newview/llviewerpartsource.cpp | 19 +++++ indra/newview/llviewerpartsource.h | 1 + indra/newview/llviewertexteditor.cpp | 14 ++-- indra/newview/llviewerwindow.cpp | 5 +- indra/newview/llvoavatar.cpp | 136 ++++++++++++++++++++++++++++++-- indra/newview/llvoavatar.h | 18 ++++- 40 files changed, 786 insertions(+), 128 deletions(-) create mode 100644 indra/newview/llanimstatelabels.cpp create mode 100644 indra/newview/llanimstatelabels.h create mode 100644 indra/newview/llstylemap.cpp create mode 100644 indra/newview/llstylemap.h (limited to 'indra/newview') 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 @@ Value 0.25 + RenderUnloadedAvatar + + Comment + Show avatars which haven't finished loading + Persist + 1 + Type + Boolean + Value + 0 + RenderVBOEnable Comment 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* 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 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 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("button land" ); childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance()); mTextStatus = getChild("text status"); - mRadioZoom = getChild("radio zoom"); + childSetCommitCallback("slider zoom",commit_slider_zoom,this); + + mRadioZoom = getChild("radio zoom"); + childSetCommitCallback("radio zoom",commit_radio_zoom,this); mRadioOrbit = getChild("radio orbit"); childSetCommitCallback("radio orbit",commit_radio_orbit,this); mRadioPan = getChild("radio pan"); childSetCommitCallback("radio pan",commit_radio_pan,this); + mRadioMove = getChild("radio move"); childSetCommitCallback("radio move",click_popup_grab_drag,this); mRadioLift = getChild("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& 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& 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 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 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& 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 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& ids); + void noteMutedUsers(LLFloaterIMPanel* panel, const LLDynamicArray& 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 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 { 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 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 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 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 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 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::unpackPSS(LLViewer } } + +/* static */ +LLPointer LLViewerPartSourceScript::createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters) +{ + LLMemType mt(LLMemType::MTYPE_PARTICLES); + + LLPointer 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 unpackPSS(LLViewerObject *source_objp, LLPointer pssp, const S32 block_num); static LLPointer unpackPSS(LLViewerObject *source_objp, LLPointer pssp, LLDataPacker &dp); + static LLPointer 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* labels ) +void LLVOAvatar::getAnimLabels( LLDynamicArray* 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* labels ) } // static -void LLVOAvatar::getAnimNames( LLDynamicArray* names ) +void LLVOAvatar::getAnimNames( LLDynamicArray* 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* labels ); - static void getAnimNames( LLDynamicArray* names ); + static void getAnimLabels( LLDynamicArray* labels ); + static void getAnimNames( LLDynamicArray* 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(); -- cgit v1.2.3