diff options
Diffstat (limited to 'indra/newview')
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(); | 
