summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2008-04-30 23:30:09 +0000
committerJames Cook <james@lindenlab.com>2008-04-30 23:30:09 +0000
commit36fccc3888c5dc318a8a235da8a5cae4faeb637d (patch)
tree021e439fe9fa3a285062d70bf0b8c0f799471681 /indra/newview
parentcf2a96375f62316b98c2dddd57f812f7565584be (diff)
svn merge -r 86190:86191 maint-ui-11-merge (EFFECTIVE MERGE: -r 84579:85724 maint-ui-11-qa).
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llanimstatelabels.cpp39
-rw-r--r--indra/newview/llanimstatelabels.h42
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llchatbar.cpp1
-rw-r--r--indra/newview/lldrawable.cpp6
-rw-r--r--indra/newview/lldrawpoolavatar.cpp25
-rw-r--r--indra/newview/llfloaterauction.cpp5
-rw-r--r--indra/newview/llfloaterchat.cpp21
-rw-r--r--indra/newview/llfloaterreporter.h2
-rw-r--r--indra/newview/llfloatersnapshot.cpp38
-rw-r--r--indra/newview/llfloatertools.cpp13
-rw-r--r--indra/newview/llfolderview.cpp4
-rw-r--r--indra/newview/llimpanel.cpp66
-rw-r--r--indra/newview/llimpanel.h13
-rw-r--r--indra/newview/llimview.cpp55
-rw-r--r--indra/newview/llimview.h4
-rw-r--r--indra/newview/llmutelist.cpp78
-rw-r--r--indra/newview/llmutelist.h10
-rw-r--r--indra/newview/llpreviewgesture.cpp5
-rw-r--r--indra/newview/llselectmgr.cpp6
-rw-r--r--indra/newview/llstartup.cpp32
-rw-r--r--indra/newview/llstatusbar.cpp20
-rw-r--r--indra/newview/llstylemap.cpp75
-rw-r--r--indra/newview/llstylemap.h54
-rw-r--r--indra/newview/lltoolbar.cpp9
-rw-r--r--indra/newview/lltooldraganddrop.cpp5
-rw-r--r--indra/newview/lltoolfocus.cpp3
-rw-r--r--indra/newview/lltoolfocus.h1
-rw-r--r--indra/newview/llviewermenu.cpp16
-rw-r--r--indra/newview/llviewermenufile.cpp13
-rw-r--r--indra/newview/llviewermessage.cpp15
-rw-r--r--indra/newview/llviewerobject.cpp31
-rw-r--r--indra/newview/llviewerobject.h1
-rw-r--r--indra/newview/llviewerpartsource.cpp19
-rw-r--r--indra/newview/llviewerpartsource.h1
-rw-r--r--indra/newview/llviewertexteditor.cpp14
-rw-r--r--indra/newview/llviewerwindow.cpp5
-rw-r--r--indra/newview/llvoavatar.cpp136
-rw-r--r--indra/newview/llvoavatar.h18
40 files changed, 786 insertions, 128 deletions
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();