diff options
| author | James Cook <james@lindenlab.com> | 2008-07-18 17:50:25 +0000 | 
|---|---|---|
| committer | James Cook <james@lindenlab.com> | 2008-07-18 17:50:25 +0000 | 
| commit | ed386ae547c225e352c39e8d14921572ee534b0b (patch) | |
| tree | f67ff767edfc07900c0c8c16cd4439eb38d05be0 /indra/newview | |
| parent | 292627c09df6085c985a189edd5df06d3ca1eb47 (diff) | |
merge support-featurettes-snapshot-merge-2 for QAR-754, includes:
    * featurettes-4 89061:89589 (which is all of featurettes-1, -2, and -3, and part of -4)
    * gteam-showstoppers-3 91950:91951 (which is all of gteam-showstoppers-1, -2, and -3)
    * featurettes-5 92149:92150 (patch for last line of chat text not visible in chat history, DEV-17771)
    * snapshot-3 91988:91991 (which is all of snapshot-1, -2, and -3)
Merging revisions 92190-92387 of svn+ssh://svn.lindenlab.com/svn/linden/branches/support-featurettes-snapshot-merge-2 into release, respecting ancestry
* QAR-590 Merge Lock Request for Support Sprint
* QAR-627 Merge snapshot improvements
* QAR-686 Merge Lock request for Featurettes
Diffstat (limited to 'indra/newview')
26 files changed, 824 insertions, 578 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e185d96c98..0269e25658 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1079,16 +1079,16 @@        <real>0.5</real>      </map>      <key>ChatFontSize</key> -    <map> -      <key>Comment</key> -      <string>Size of chat text in chat console (0 = small, 1 = big)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>1</integer> -    </map> +        <map> +        <key>Comment</key> +            <string>Size of chat text in chat console (0 = small, 1 = medium, 2 = big)</string> +        <key>Persist</key> +            <integer>1</integer> +        <key>Type</key> +            <string>S32</string> +        <key>Value</key> +            <integer>1</integer> +        </map>      <key>ChatFullWidth</key>      <map>        <key>Comment</key> @@ -1123,16 +1123,16 @@        <integer>1</integer>      </map>      <key>ChatPersistTime</key> -    <map> -      <key>Comment</key> -      <string>Time for which chat stays visible in console (seconds)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>15.0</real> -    </map> +        <map> +        <key>Comment</key> +            <string>Time for which chat stays visible in console (seconds)</string> +        <key>Persist</key> +            <integer>1</integer> +        <key>Type</key> +            <string>F32</string> +        <key>Value</key> +            <real>20</real> +        </map>      <key>ChatShowTimestamps</key>      <map>        <key>Comment</key> @@ -1856,16 +1856,16 @@        <integer>0</integer>      </map>      <key>ConsoleBackgroundOpacity</key> -    <map> -      <key>Comment</key> -      <string>Opacity of chat console (0.0 = completely transparent, 1.0 = completely opaque)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>0.40000000596</real> -    </map> +        <map> +        <key>Comment</key> +            <string>Opacity of chat console (0.0 = completely transparent, 1.0 = completely opaque)</string> +        <key>Persist</key> +            <integer>1</integer> +        <key>Type</key> +            <string>F32</string> +        <key>Value</key> +            <real>0.700</real> +        </map>      <key>ConsoleBufferSize</key>      <map>        <key>Comment</key> @@ -5046,21 +5046,21 @@        <integer>0</integer>      </map>      <key>ObjectChatColor</key> -    <map> -      <key>Comment</key> -      <string>Color of chat messages from objects</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Color4</string> -      <key>Value</key> -      <array> -        <real>0.699999988079</real> -        <real>0.899999976158</real> -        <real>0.699999988079</real> -        <real>1.0</real> -      </array> -    </map> +        <map> +        <key>Comment</key> +            <string>Color of chat messages from objects</string> +        <key>Persist</key> +            <integer>1</integer> +        <key>Type</key> +            <string>Color4</string> +        <key>Value</key> +            <array> +                <real>1</real> +                <real>0.5</real> +                <real>0.0</real> +                <real>1</real> +            </array> +        </map>      <key>OpenDebugStatAdvanced</key>      <map>        <key>Comment</key> @@ -5599,6 +5599,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>LandBrushForce</key> +        <map> +        <key>Comment</key> +            <string>Multiplier for land modification brush force.</string> +        <key>Persist</key> +            <integer>1</integer> +        <key>Type</key> +            <string>F32</string> +        <key>Value</key> +            <real>1.0</real> +        </map>      <key>RecentItemsSortOrder</key>      <map>        <key>Comment</key> @@ -6999,16 +7010,16 @@        <integer>1</integer>      </map>      <key>ShowObjectUpdates</key> -    <map> -      <key>Comment</key> -      <string>Show when update messages are received for individual objects</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map> +        <map> +        <key>Comment</key> +            <string>Show when update messages are received for individual objects</string> +        <key>Persist</key> +            <integer>0</integer> +        <key>Type</key> +            <string>Boolean</string> +        <key>Value</key> +            <integer>0</integer> +        </map>      <key>ShowOverlayTitle</key>      <map>        <key>Comment</key> @@ -7346,6 +7357,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>SnapshotFormat</key> +        <map> +        <key>Comment</key> +            <string>Save snapshots in this format (0 = PNG, 1 = JPEG, 2 = BMP)</string> +        <key>Persist</key> +            <integer>1</integer> +        <key>Type</key> +            <string>S32</string> +        <key>Value</key> +            <integer>0</integer> +        </map>      <key>SnapshotPostcardLastResolution</key>      <map>        <key>Comment</key> diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index eaa2f61dce..9d2e06b31e 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -33,6 +33,11 @@  ##   LL_GL_BLACKLIST which solves your problems.  #export LL_GL_BLACKLIST=abcdefghijklmno +## - Some ATI/Radeon users report random X server crashes when the mouse +##   cursor changes shape.  If you suspect that you are a victim of this +##   driver bug, try enabling this option and report whether it helps: +#export LL_ATI_MOUSE_CURSOR_BUG=x +  ## Everything below this line is just for advanced troubleshooters.  ##------------------------------------------------------------------- @@ -56,6 +61,12 @@ if [ "$GTK_IM_MODULE" = "scim" ]; then      export GTK_IM_MODULE=xim  fi +## - Automatically work around the ATI mouse cursor crash bug: +## (this workaround is disabled as most fglrx users do not see the bug) +#if lsmod | grep fglrx &>/dev/null ; then +#	export LL_ATI_MOUSE_CURSOR_BUG=x +#fi +  ## Nothing worth editing below this line.  ##------------------------------------------------------------------- diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index e926e97f76..7fb9e57507 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -6438,20 +6438,9 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void  {  	// We should only receive this message a single time.  Ignore subsequent AgentWearablesUpdates  	// that may result from AgentWearablesRequest having been sent more than once.  -	static BOOL first = TRUE; -	if( first ) -	{ -		first = FALSE; -	} -	else -	{ -		return; -	} -	 -	if (gNoRender) -	{ -		return; -	} +	static bool first = true; +	if (!first) return; +	first = false;  	LLUUID agent_id;  	gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -6467,16 +6456,6 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void  			// Transitional state.  Avatars should always have at least their body parts (hair, eyes, shape and skin).  			// The fact that they don't have any here (only a dummy is sent) implies that this account existed  			// before we had wearables, or that the database has gotten messed up. -			// Deal with this by creating new body parts. -			//avatar->createStandardWearables(); - -			// no, deal with it by noting that we need to choose a -			// gender, but only if an initial outfit load isn't happening. -			// This whole check (num_wearables < 4) can probably be deleted. JC -			if (gInitialOutfit.empty()) -			{ -				gAgent.setGenderChosen(FALSE); -			}  			return;  		} diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index dc160a29ac..ebd708736e 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -60,7 +60,7 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect)  {  	LLRect r; -	r.set(0, rect.getHeight() - 100, rect.getWidth()/2, 100); +	r.set(10, rect.getHeight() - 100, rect.getWidth()/2, 100);  	mDebugConsolep = new LLConsole("debug console", 20, r, -1, 0.f );  	mDebugConsolep->setFollowsBottom();  	mDebugConsolep->setFollowsLeft(); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 344917150f..0f180472fd 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -357,6 +357,26 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)  			L"Bitmap Images (*.bmp)\0*.bmp\0" \  			L"\0";  		break; +	case FFSAVE_PNG: +		if (filename.empty()) +		{ +			wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/ +		} +		mOFN.lpstrDefExt = L"png"; +		mOFN.lpstrFilter = +			L"PNG Images (*.png)\0*.png\0" \ +			L"\0"; +		break; +	case FFSAVE_JPEG: +		if (filename.empty()) +		{ +			wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/ +		} +		mOFN.lpstrDefExt = L"jpeg"; +		mOFN.lpstrFilter = +			L"JPEG Images (*.jpeg)\0*.jpeg\0" \ +			L"\0"; +		break;  	case FFSAVE_AVI:  		if (filename.empty())  		{ @@ -642,7 +662,16 @@ OSStatus	LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& fi  			creator = 'prvw';  			extension = CFSTR(".bmp");  			break; -		 +		case FFSAVE_JPEG: +			type = 'JPEG'; +			creator = 'prvw'; +			extension = CFSTR(".jpeg"); +			break; +		case FFSAVE_PNG: +			type = 'PNG '; +			creator = 'prvw'; +			extension = CFSTR(".png"); +			break;  		case FFSAVE_AVI:  			type = '\?\?\?\?';  			creator = '\?\?\?\?'; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 012524a541..83a9357523 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -107,6 +107,8 @@ public:  		FFSAVE_COLLADA = 10,  		FFSAVE_RAW = 11,  		FFSAVE_J2C = 12, +		FFSAVE_PNG = 13, +		FFSAVE_JPEG = 14,  	};  	// open the dialog. This is a modal operation diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 58ad07c5bb..5dfbee73a4 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -434,7 +434,7 @@ void LLPanelLandGeneral::refresh()  		mEditName->setText(LLStringUtil::null);  		mEditDesc->setEnabled(FALSE); -		mEditDesc->setText(LLStringUtil::null); +		mEditDesc->setText(getString("no_selection_text"));  		mTextSalePending->setText(LLStringUtil::null);  		mTextSalePending->setEnabled(FALSE); @@ -1430,6 +1430,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo  	LLUUID	owner_id;  	BOOL	is_group_owned;  	S32		object_count; +	U32		most_recent_time = 0;  	BOOL	is_online;  	std::string object_count_str;  	//BOOL b_need_refresh = FALSE; @@ -1447,7 +1448,10 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo  		msg->getBOOLFast(_PREHASH_Data, _PREHASH_IsGroupOwned,	is_group_owned,	i);  		msg->getS32Fast (_PREHASH_Data, _PREHASH_Count,			object_count,	i);  		msg->getBOOLFast(_PREHASH_Data, _PREHASH_OnlineStatus,	is_online,		i); - +		if(msg->getNumberOfBlocks("DataExtended")) +		{ +			msg->getU32("DataExtended", "TimeStamp", most_recent_time, i); +		}  		if (owner_id.isNull())  		{  			continue; @@ -1474,6 +1478,9 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo  		object_count_str = llformat("%d", object_count);  		row->addColumn(object_count_str, FONT); +		 +		row->addColumn(formatted_time((time_t)most_recent_time), FONT); +  		if (is_group_owned)  		{ @@ -2165,7 +2172,6 @@ LLPanelLandAccess::LLPanelLandAccess(LLParcelSelectionHandle& parcel)  } -  BOOL LLPanelLandAccess::postBuild()  {  	childSetCommitCallback("public_access", onCommitPublicAccess, this); @@ -2427,12 +2433,14 @@ void LLPanelLandAccess::refresh_ui()  		childSetEnabled("AccessList", can_manage_allowed);  		S32 allowed_list_count = parcel->mAccessList.size();  		childSetEnabled("add_allowed", can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); -		childSetEnabled("remove_allowed", can_manage_allowed && allowed_list_count > 0); +		BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0; +		childSetEnabled("remove_allowed", can_manage_allowed && has_selected);  		childSetEnabled("BannedList", can_manage_banned);  		S32 banned_list_count = parcel->mBanList.size();  		childSetEnabled("add_banned", can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); -		childSetEnabled("remove_banned", can_manage_banned && banned_list_count > 0); +		has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0; +		childSetEnabled("remove_banned", can_manage_banned && has_selected);  	}  } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index fc3c0952cb..3b2fb43f61 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -816,8 +816,7 @@ BOOL LLPanelRegionDebugInfo::postBuild()  	initHelpBtn("restart_help",				"HelpRegionRestart");  	childSetAction("choose_avatar_btn", onClickChooseAvatar, this); -	childSetAction("return_scripted_other_land_btn", onClickReturnScriptedOtherLand, this); -	childSetAction("return_scripted_all_btn", onClickReturnScriptedAll, this); +	childSetAction("return_btn", onClickReturn, this);  	childSetAction("top_colliders_btn", onClickTopColliders, this);  	childSetAction("top_scripts_btn", onClickTopScripts, this);  	childSetAction("restart_btn", onClickRestart, this); @@ -832,10 +831,13 @@ bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region)  	BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());  	setCtrlsEnabled(allow_modify);  	childDisable("apply_btn"); - +	childDisable("target_avatar_name"); +	  	childSetEnabled("choose_avatar_btn", allow_modify); -	childSetEnabled("return_scripted_other_land_btn", allow_modify && !mTargetAvatar.isNull()); -	childSetEnabled("return_scripted_all_btn", allow_modify && !mTargetAvatar.isNull()); +	childSetEnabled("return_scripts", allow_modify && !mTargetAvatar.isNull()); +	childSetEnabled("return_other_land", allow_modify && !mTargetAvatar.isNull()); +	childSetEnabled("return_estate_wide", allow_modify && !mTargetAvatar.isNull()); +	childSetEnabled("return_btn", allow_modify && !mTargetAvatar.isNull());  	childSetEnabled("top_colliders_btn", allow_modify);  	childSetEnabled("top_scripts_btn", allow_modify);  	childSetEnabled("restart_btn", allow_modify); @@ -881,61 +883,56 @@ void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector<std::string>& na  }  // static -void LLPanelRegionDebugInfo::onClickReturnScriptedOtherLand(void* data) +void LLPanelRegionDebugInfo::onClickReturn(void* data)  {  	LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;  	if (panelp->mTargetAvatar.isNull()) return;  	LLStringUtil::format_map_t args;  	args["[USER_NAME]"] = panelp->childGetValue("target_avatar_name").asString(); -	gViewerWindow->alertXml("ReturnScriptedOnOthersLand", args, callbackReturnScriptedOtherLand, data); +	gViewerWindow->alertXml("EstateObjectReturn", args, callbackReturn, data);  }  // static -void LLPanelRegionDebugInfo::callbackReturnScriptedOtherLand( S32 option, void* userdata ) +void LLPanelRegionDebugInfo::callbackReturn( S32 option, void* userdata )  {  	if (option != 0) return;  	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) userdata;  	if (!self->mTargetAvatar.isNull())  	{ -		U32 flags = 0; -		flags = flags | SWD_OTHERS_LAND_ONLY; -		flags = flags | SWD_ALWAYS_RETURN_OBJECTS; -		flags |= SWD_SCRIPTED_ONLY; - -		send_sim_wide_deletes(self->mTargetAvatar, flags); -	} -} +		U32 flags = SWD_ALWAYS_RETURN_OBJECTS; -// static -void LLPanelRegionDebugInfo::onClickReturnScriptedAll(void* data) -{ -	LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; -	if (panelp->mTargetAvatar.isNull()) return; -	 -	 -	LLStringUtil::format_map_t args; -	args["[USER_NAME]"] = panelp->childGetValue("target_avatar_name").asString(); -	gViewerWindow->alertXml("ReturnScriptedOnAllLand", args, callbackReturnScriptedAll, data); -} - -// static -void LLPanelRegionDebugInfo::callbackReturnScriptedAll( S32 option, void* userdata ) -{ -	if (option != 0) return; +		if (self->childGetValue("return_scripts").asBoolean()) +		{ +			flags |= SWD_SCRIPTED_ONLY; +		} +		 +		if (self->childGetValue("return_other_land").asBoolean()) +		{ +			flags |= SWD_OTHERS_LAND_ONLY; +		} -	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) userdata; -	if (!self->mTargetAvatar.isNull()) -	{ -		U32 flags = 0; -		flags |= SWD_ALWAYS_RETURN_OBJECTS; -		flags |= SWD_SCRIPTED_ONLY; +		if (self->childGetValue("return_estate_wide").asBoolean()) +		{ +			// send as estate message - routed by spaceserver to all regions in estate +			strings_t strings; +			strings.push_back(llformat("%d", flags)); +			strings.push_back(self->mTargetAvatar.asString()); -		send_sim_wide_deletes(self->mTargetAvatar, flags); +			LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); +		 +			self->sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); +		} +		else +		{ +			// send to this simulator only +			send_sim_wide_deletes(self->mTargetAvatar, flags); +		}  	}  } +  // static  void LLPanelRegionDebugInfo::onClickTopColliders(void* data)  { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 7d05ffa5bc..8bcab111b5 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -186,10 +186,8 @@ protected:  	static void onClickChooseAvatar(void*);  	static void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data); -	static void onClickReturnScriptedOtherLand(void*); -	static void callbackReturnScriptedOtherLand(S32 option, void*); -	static void onClickReturnScriptedAll(void*); -	static void callbackReturnScriptedAll(S32 option, void*); +	static void onClickReturn(void *); +	static void callbackReturn(S32 option, void*);  	static void onClickTopColliders(void*);  	static void onClickTopScripts(void*);  	static void onClickRestart(void* data); diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 1f601e6dc1..811fc4eb03 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -68,6 +68,8 @@  #include "llgl.h"  #include "llglheaders.h"  #include "llimagejpeg.h" +#include "llimagepng.h" +#include "llimagebmp.h"  #include "llimagej2c.h"  #include "llvfile.h"  #include "llvfs.h" @@ -83,7 +85,7 @@ LLSnapshotFloaterView* gSnapshotFloaterView = NULL;  LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL; -const F32 SNAPSHOT_TIME_DELAY = 1.f; +const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;  F32 SHINE_TIME = 0.5f;  F32 SHINE_WIDTH = 0.6f; @@ -93,6 +95,7 @@ S32 BORDER_WIDTH = 6;  const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte  const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 +  ///----------------------------------------------------------------------------  /// Class LLSnapshotLivePreview   ///---------------------------------------------------------------------------- @@ -103,9 +106,10 @@ public:  	{  		SNAPSHOT_POSTCARD,  		SNAPSHOT_TEXTURE, -		SNAPSHOT_BITMAP +		SNAPSHOT_LOCAL  	}; +  	LLSnapshotLivePreview(const LLRect& rect);  	~LLSnapshotLivePreview(); @@ -119,6 +123,7 @@ public:  	S32  getMaxImageSize() {return mMaxImageSize ;}  	ESnapshotType getSnapshotType() const { return mSnapshotType; } +	LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }  	BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }  	BOOL isSnapshotActive() { return mSnapshotActive; }  	LLImageGL* getThumbnailImage() const { return mThumbnailImage ; } @@ -133,9 +138,10 @@ public:  	BOOL isImageScaled();  	void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } +	void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }  	void setSnapshotQuality(S32 quality);  	void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } -	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE); +	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);  	LLFloaterPostcard* savePostcard();  	void saveTexture();  	BOOL saveLocal(); @@ -147,7 +153,7 @@ public:  	static void onIdle( void* snapshot_preview ); -protected: +private:  	LLColor4					mColor;  	LLPointer<LLImageGL>		mViewerImage[2];  	LLRect						mImageRect[2]; @@ -165,9 +171,9 @@ protected:  	BOOL                        mThumbnailUpToDate ;  	S32							mCurImageIndex; -	LLPointer<LLImageRaw>		mRawImage; -	LLPointer<LLImageRaw>		mRawImageEncoded; -	LLPointer<LLImageJPEG>		mJPEGImage; +	LLPointer<LLImageRaw>		mPreviewImage; +	LLPointer<LLImageRaw>		mPreviewImageEncoded; +	LLPointer<LLImageFormatted>	mFormattedImage;  	LLFrameTimer				mSnapshotDelayTimer;  	S32							mShineCountdown;  	LLFrameTimer				mShineAnimTimer; @@ -177,6 +183,7 @@ protected:  	S32							mSnapshotQuality;  	S32							mDataSize;  	ESnapshotType				mSnapshotType; +	LLFloaterSnapshot::ESnapshotFormat	mSnapshotFormat;  	BOOL						mSnapshotUpToDate;  	LLFrameTimer				mFallAnimTimer;  	LLVector3					mCameraPos; @@ -195,16 +202,17 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :  	LLView(std::string("snapshot_live_preview"), rect, FALSE),   	mColor(1.f, 0.f, 0.f, 0.5f),   	mCurImageIndex(0), -	mRawImage(NULL), +	mPreviewImage(NULL),  	mThumbnailImage(NULL) , -	mRawImageEncoded(NULL), -	mJPEGImage(NULL), +	mPreviewImageEncoded(NULL), +	mFormattedImage(NULL),  	mShineCountdown(0),  	mFlashAlpha(0.f),  	mNeedsFlash(TRUE),  	mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),  	mDataSize(0),  	mSnapshotType(SNAPSHOT_POSTCARD), +	mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),  	mSnapshotUpToDate(FALSE),  	mCameraPos(LLViewerCamera::getInstance()->getOrigin()),  	mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), @@ -212,6 +220,7 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :  	mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR),  	mSnapshotSoundPlayed(false)  { +	setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));  	mSnapshotDelayTimer.setTimerExpirySec(0.0f);  	mSnapshotDelayTimer.start();  // 	gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); @@ -233,9 +242,9 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :  LLSnapshotLivePreview::~LLSnapshotLivePreview()  {  	// delete images -	mRawImage = NULL; -	mRawImageEncoded = NULL; -	mJPEGImage = NULL; +	mPreviewImage = NULL; +	mPreviewImageEncoded = NULL; +	mFormattedImage = NULL;  // 	gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );  	sList.erase(this); @@ -293,7 +302,7 @@ BOOL LLSnapshotLivePreview::isImageScaled()  	return mImageScaled[mCurImageIndex];  } -void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail)  +void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay)   {   	if (mSnapshotUpToDate)  	{ @@ -333,7 +342,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail  	if (new_snapshot)  	{  		mSnapshotDelayTimer.start(); -		mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY); +		mSnapshotDelayTimer.setTimerExpirySec(delay);  	}  	else if(new_thumbnail)  	{ @@ -347,6 +356,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail  void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)  { +	llclamp(quality, 0, 100);  	if (quality != mSnapshotQuality)  	{  		mSnapshotQuality = quality; @@ -396,7 +406,7 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)  void LLSnapshotLivePreview::draw()  {  	if (mViewerImage[mCurImageIndex].notNull() && -	    mRawImageEncoded.notNull() && +	    mPreviewImageEncoded.notNull() &&  	    mSnapshotUpToDate)  	{  		LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); @@ -685,8 +695,8 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)  	LLPointer<LLImageRaw> raw = NULL ;  	S32 w , h ; -	w = get_nearest_power_two(mThumbnailWidth, 512) * 2 ; -	h = get_nearest_power_two(mThumbnailHeight, 512) * 2 ; +	w = get_lower_power_two(mThumbnailWidth, 512) * 2 ; +	h = get_lower_power_two(mThumbnailHeight, 512) * 2 ;  	{  		raw = new LLImageRaw ; @@ -723,131 +733,155 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )  		previewp->mCameraPos = new_camera_pos;  		previewp->mCameraRot = new_camera_rot;  		// request a new snapshot whenever the camera moves, with a time delay - 		previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot")); +		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot"); +		previewp->updateSnapshot(autosnap, FALSE, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); +	} + +	// see if it's time yet to snap the shot and bomb out otherwise. +	previewp->mSnapshotActive =  +		(previewp->mSnapshotDelayTimer.getStarted() &&	previewp->mSnapshotDelayTimer.hasExpired()) +		&& !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active +	if ( ! previewp->mSnapshotActive) +	{ +		return;  	} -	previewp->mSnapshotActive = (previewp->mSnapshotDelayTimer.getStarted() &&	 -								 previewp->mSnapshotDelayTimer.hasExpired()); +	// time to produce a snapshot -	// don't take snapshots while ALT-zoom active -	if (LLToolCamera::getInstance()->hasMouseCapture()) +	if (!previewp->mPreviewImage)  	{ -		previewp->mSnapshotActive = FALSE; +		previewp->mPreviewImage = new LLImageRaw;  	} -	if (previewp->mSnapshotActive) +	if (!previewp->mPreviewImageEncoded)  	{ -		if (!previewp->mRawImage) -		{ -			previewp->mRawImage = new LLImageRaw; -		} +		previewp->mPreviewImageEncoded = new LLImageRaw; +	} -		if (!previewp->mRawImageEncoded) +	previewp->setVisible(FALSE); +	previewp->setEnabled(FALSE); +	 +	previewp->getWindow()->incBusyCount(); +	previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; + +	// grab the raw image and encode it into desired format +	if(gViewerWindow->rawSnapshot( +							previewp->mPreviewImage, +							previewp->mWidth[previewp->mCurImageIndex], +							previewp->mHeight[previewp->mCurImageIndex], +							previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), +							previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, +							gSavedSettings.getBOOL("RenderUIInSnapshot"), +							FALSE, +							previewp->mSnapshotBufferType, +							previewp->getMaxImageSize())) +	{ +		previewp->mPreviewImageEncoded->resize( +			previewp->mPreviewImage->getWidth(),  +			previewp->mPreviewImage->getHeight(),  +			previewp->mPreviewImage->getComponents()); + +		if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))  		{ -			previewp->mRawImageEncoded = new LLImageRaw; +			// 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; +			}  		} - -		previewp->setVisible(FALSE); -		previewp->setEnabled(FALSE); -		previewp->getWindow()->incBusyCount(); -		previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; - -		// do update -		if(gViewerWindow->rawSnapshot(previewp->mRawImage, -								previewp->mWidth[previewp->mCurImageIndex], -								previewp->mHeight[previewp->mCurImageIndex], -								previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), -								previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, -								gSavedSettings.getBOOL("RenderUIInSnapshot"), -								FALSE, -								previewp->mSnapshotBufferType, -								previewp->getMaxImageSize())) +		if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)  		{ -			previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents()); - -			if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) +			LLPointer<LLImageJ2C> formatted = new LLImageJ2C; +			LLPointer<LLImageRaw> scaled = new LLImageRaw( +				previewp->mPreviewImage->getData(), +				previewp->mPreviewImage->getWidth(), +				previewp->mPreviewImage->getHeight(), +				previewp->mPreviewImage->getComponents()); +		 +			scaled->biasedScaleToPowerOfTwo(512); +			previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; +			if (formatted->encode(scaled, 0.f))  			{ -				// 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; -				} +				previewp->mDataSize = formatted->getDataSize(); +				formatted->decode(previewp->mPreviewImageEncoded, 0);  			} - -			if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD) +		} +		else +		{ +			// delete any existing image +			previewp->mFormattedImage = NULL; +			// now create the new one of the appropriate format. +			// note: postcards hardcoded to use jpeg always. +			LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotType() == SNAPSHOT_POSTCARD +				? LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG : previewp->getSnapshotFormat(); +			switch(format)  			{ -				// *FIX: just resize and reuse existing jpeg? -				previewp->mJPEGImage = NULL; // deletes image -				previewp->mJPEGImage = new LLImageJPEG(); -				previewp->mJPEGImage->setEncodeQuality(llclamp(previewp->mSnapshotQuality, 0, 100)); -				if (previewp->mJPEGImage->encode(previewp->mRawImage, 0.0f)) -				{ -					previewp->mDataSize = previewp->mJPEGImage->getDataSize(); -					previewp->mJPEGImage->decode(previewp->mRawImageEncoded, 0.0f); -				} +			case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: +				previewp->mFormattedImage = new LLImagePNG();  +				break; +			case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: +				previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality);  +				break; +			case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: +				previewp->mFormattedImage = new LLImageBMP();  +				break;  			} -			else if (previewp->getSnapshotType() == SNAPSHOT_TEXTURE) +			if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))  			{ -				LLPointer<LLImageJ2C> formatted = new LLImageJ2C; -				LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImage->getData(), -															  previewp->mRawImage->getWidth(), -															  previewp->mRawImage->getHeight(), -															  previewp->mRawImage->getComponents()); -			 -				scaled->biasedScaleToPowerOfTwo(512); -				previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; -				if (formatted->encode(scaled, 0.0f)) +				// special case BMP to copy instead of decode otherwise decode will crash. +				if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)  				{ -					previewp->mDataSize = formatted->getDataSize(); -					formatted->decode(previewp->mRawImageEncoded, 0.0f); +					previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage); +				} +				else +				{ +					previewp->mDataSize = previewp->mFormattedImage->getDataSize(); +					previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);  				}  			} -			else -			{ -				previewp->mRawImageEncoded->copy(previewp->mRawImage); -				previewp->mDataSize = previewp->mRawImage->getDataSize(); -			} +		} -			LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImageEncoded->getData(), -														  previewp->mRawImageEncoded->getWidth(), -														  previewp->mRawImageEncoded->getHeight(), -														  previewp->mRawImageEncoded->getComponents()); -			 -			// leave original image dimensions, just scale up texture buffer -			if (previewp->mRawImageEncoded->getWidth() > 1024 || previewp->mRawImageEncoded->getHeight() > 1024) -			{ -				// go ahead and shrink image to appropriate power of 2 for display -				scaled->biasedScaleToPowerOfTwo(1024); -				previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; -			} -			else -			{ -				// expand image but keep original image data intact -				scaled->expandToPowerOfTwo(1024, FALSE); -			} +		LLPointer<LLImageRaw> scaled = new LLImageRaw( +			previewp->mPreviewImageEncoded->getData(), +			previewp->mPreviewImageEncoded->getWidth(), +			previewp->mPreviewImageEncoded->getHeight(), +			previewp->mPreviewImageEncoded->getComponents()); +		 +		// leave original image dimensions, just scale up texture buffer +		if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024) +		{ +			// go ahead and shrink image to appropriate power of 2 for display +			scaled->biasedScaleToPowerOfTwo(1024); +			previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; +		} +		else +		{ +			// expand image but keep original image data intact +			scaled->expandToPowerOfTwo(1024, FALSE); +		} -			previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE); -			previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE); -			LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]); -			previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE); +		previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE); +		previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE); +		LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]); +		previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE); -			previewp->mSnapshotUpToDate = TRUE; -			previewp->generateThumbnailImage(TRUE) ; +		previewp->mSnapshotUpToDate = TRUE; +		previewp->generateThumbnailImage(TRUE) ; -			previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal(); -			previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame -		} -		previewp->getWindow()->decBusyCount(); -		// only show fullscreen preview when in freeze frame mode -		previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame")); -		previewp->mSnapshotDelayTimer.stop(); -		previewp->mSnapshotActive = FALSE; +		previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal(); +		previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame  	} +	previewp->getWindow()->decBusyCount(); +	// only show fullscreen preview when in freeze frame mode +	previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame")); +	previewp->mSnapshotDelayTimer.stop(); +	previewp->mSnapshotActive = FALSE; +  	if(!previewp->getThumbnailUpToDate())  	{  		previewp->generateThumbnailImage() ; @@ -876,11 +910,16 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard()  		image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight()));  	} - -	LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(mJPEGImage, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal); +	LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get()); +	if(!jpg) +	{ +		llwarns << "Formatted image not a JPEG" << llendl; +		return NULL; +	} +	LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal);  	// relinquish lifetime of viewerimage and jpeg image to postcard floater  	mViewerImage[mCurImageIndex] = NULL; -	mJPEGImage = NULL; +	mFormattedImage = NULL;  	return floater;  } @@ -893,10 +932,10 @@ void LLSnapshotLivePreview::saveTexture()  	LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());  	LLPointer<LLImageJ2C> formatted = new LLImageJ2C; -	LLPointer<LLImageRaw> scaled = new LLImageRaw(mRawImage->getData(), -												  mRawImage->getWidth(), -												  mRawImage->getHeight(), -												  mRawImage->getComponents()); +	LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(), +												  mPreviewImage->getWidth(), +												  mPreviewImage->getHeight(), +												  mPreviewImage->getComponents());  	scaled->biasedScaleToPowerOfTwo(512); @@ -928,7 +967,7 @@ void LLSnapshotLivePreview::saveTexture()  BOOL LLSnapshotLivePreview::saveLocal()  { -	return gViewerWindow->saveImageNumbered(mRawImage); +	return gViewerWindow->saveImageNumbered(mFormattedImage);  }  ///---------------------------------------------------------------------------- @@ -951,6 +990,7 @@ public:  	}  	static void onClickDiscard(void* data);  	static void onClickKeep(void* data); +	static void onCommitSave(LLUICtrl* ctrl, void* data);  	static void onClickNewSnapshot(void* data);  	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);  	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); @@ -965,6 +1005,7 @@ public:  	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);  	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);  	static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); +	static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data);  	static void onCommitCustomResolution(LLUICtrl *ctrl, void* data);  	static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ;  	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); @@ -973,12 +1014,14 @@ public:  	static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname);  	static void updateControls(LLFloaterSnapshot* floater);  	static void updateLayout(LLFloaterSnapshot* floater); +	static void updateResolutionTextEntry(LLFloaterSnapshot* floater);  	static LLHandle<LLView> sPreviewHandle;  	static BOOL         sAspectRatioCheckOff ;  private:  	static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); +	static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater);  	static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater);  	static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname);  	static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); @@ -995,6 +1038,7 @@ LLHandle<LLView> LLFloaterSnapshot::Impl::sPreviewHandle;  //static   BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ; +  // static  LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)  { @@ -1013,10 +1057,28 @@ LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFlo  	else if (id == "texture")  		index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;  	else if (id == "local") -		index = LLSnapshotLivePreview::SNAPSHOT_BITMAP; +		index = LLSnapshotLivePreview::SNAPSHOT_LOCAL; +	return index; +} + + +// static +LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getFormatIndex(LLFloaterSnapshot* floater) +{ +	ESnapshotFormat index = SNAPSHOT_FORMAT_PNG; +	LLSD value = floater->childGetValue("local_format_combo"); +	const std::string id = value.asString(); +	if (id == "PNG") +		index = SNAPSHOT_FORMAT_PNG; +	else if (id == "JPEG") +		index = SNAPSHOT_FORMAT_JPEG; +	else if (id == "BMP") +		index = SNAPSHOT_FORMAT_BMP;  	return index;  } + +  // static  LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater)  { @@ -1141,10 +1203,10 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)  // static  void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)  { -	BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot") ;  	LLRadioGroup* snapshot_type_radio = floater->getChild<LLRadioGroup>("snapshot_type_radio");  	snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType"));  	LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater); +	ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); //getFormatIndex(floater);	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);  	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);  	floater->childSetVisible("postcard_size_combo", FALSE); @@ -1158,114 +1220,102 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)  	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));  	combo = floater->getChild<LLComboBox>("local_size_combo");  	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); - -	floater->childSetVisible("upload_btn", FALSE); -	floater->childSetVisible("send_btn", FALSE); -	floater->childSetVisible("save_btn", FALSE); -	floater->childSetEnabled("keep_aspect_check", FALSE) ; +	combo = floater->getChild<LLComboBox>("local_format_combo"); +	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); + +	floater->childSetVisible("upload_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE); +	floater->childSetVisible("send_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD); +	floater->childSetVisible("save_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); +	floater->childSetEnabled("keep_aspect_check",	shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !sAspectRatioCheckOff); +	floater->childSetEnabled("layer_types",			shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); + +	BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot"); +	BOOL is_local = shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL; +	BOOL show_slider =  +		shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD +		|| (is_local && shot_format == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG); + +	floater->childSetVisible("more_btn", !is_advance); // the only item hidden in advanced mode +	floater->childSetVisible("less_btn",				is_advance); +	floater->childSetVisible("type_label2",				is_advance); +	floater->childSetVisible("format_label",			is_advance && is_local); +	floater->childSetVisible("local_format_combo",		is_advance && is_local); +	floater->childSetVisible("layer_types",				is_advance); +	floater->childSetVisible("layer_type_label",		is_advance); +	floater->childSetVisible("snapshot_width",			is_advance); +	floater->childSetVisible("snapshot_height",			is_advance); +	floater->childSetVisible("keep_aspect_check",		is_advance); +	floater->childSetVisible("ui_check",				is_advance); +	floater->childSetVisible("hud_check",				is_advance); +	floater->childSetVisible("keep_open_check",			is_advance); +	floater->childSetVisible("freeze_frame_check",		is_advance); +	floater->childSetVisible("auto_snapshot_check",		is_advance); +	floater->childSetVisible("image_quality_slider",	is_advance && show_slider);  	switch(shot_type)  	{  	  case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:  		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;  		floater->childSetValue("layer_types", "colors"); -		floater->childSetEnabled("layer_types", FALSE); -		  		if(is_advance)  		{			 -			floater->childSetEnabled("image_quality_slider", TRUE);  			setResolution(floater, "postcard_size_combo"); - -			if(!sAspectRatioCheckOff) -			{ -				floater->childSetEnabled("keep_aspect_check", TRUE) ; -			}  		} - -		floater->childSetVisible("send_btn", TRUE);  		break;  	  case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:  		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;  		floater->childSetValue("layer_types", "colors"); -		floater->childSetEnabled("layer_types", FALSE); -		floater->childSetEnabled("image_quality_slider", FALSE); -  		if(is_advance)  		{  			setResolution(floater, "texture_size_combo");			  		} - -		floater->childSetVisible("upload_btn", TRUE);  		break; -	  case LLSnapshotLivePreview::SNAPSHOT_BITMAP: -		floater->childSetEnabled("layer_types", TRUE); -		floater->childSetEnabled("image_quality_slider", FALSE); -		 +	  case  LLSnapshotLivePreview::SNAPSHOT_LOCAL:  		if(is_advance)  		{  			setResolution(floater, "local_size_combo"); - -			if(!sAspectRatioCheckOff) -			{ -				floater->childSetEnabled("keep_aspect_check", TRUE) ; -			}  		} - -		floater->childSetVisible("save_btn", TRUE);  		break;  	  default:  		break;  	} -	if(is_advance) -	{ -		floater->childSetVisible("type_label2", TRUE) ; -		floater->childSetVisible("layer_types", TRUE) ; -		floater->childSetVisible("layer_type_label", TRUE) ; -		floater->childSetVisible("snapshot_width", TRUE) ; -		floater->childSetVisible("snapshot_height", TRUE) ; -		floater->childSetVisible("keep_aspect_check", TRUE) ; -		floater->childSetVisible("ui_check", TRUE) ; -		floater->childSetVisible("hud_check", TRUE) ; -		floater->childSetVisible("keep_open_check", TRUE) ; -		floater->childSetVisible("freeze_frame_check", TRUE) ; -		floater->childSetVisible("auto_snapshot_check", TRUE) ; -		floater->childSetVisible("image_quality_slider", TRUE); -		floater->childSetVisible("more_btn", FALSE); -		floater->childSetVisible("less_btn", TRUE); -	} -	else -	{ -		floater->childSetVisible("type_label2", FALSE) ; -		floater->childSetVisible("layer_types", FALSE) ; -		floater->childSetVisible("layer_type_label", FALSE) ; -		floater->childSetVisible("snapshot_width", FALSE) ; -		floater->childSetVisible("snapshot_height", FALSE) ; -		floater->childSetVisible("keep_aspect_check", FALSE) ; -		floater->childSetVisible("ui_check", FALSE) ; -		floater->childSetVisible("hud_check", FALSE) ; -		floater->childSetVisible("keep_open_check", FALSE) ; -		floater->childSetVisible("freeze_frame_check", FALSE) ; -		floater->childSetVisible("auto_snapshot_check", FALSE) ; -		floater->childSetVisible("image_quality_slider", FALSE); -		floater->childSetVisible("more_btn", TRUE); -		floater->childSetVisible("less_btn", FALSE); -	} +	updateResolutionTextEntry(floater);  	LLSnapshotLivePreview* previewp = getPreviewView(floater);  	if (previewp)  	{  		previewp->setSnapshotType(shot_type); +		previewp->setSnapshotFormat(shot_format);  		previewp->setSnapshotBufferType(layer_type);  	}  }  // static +void LLFloaterSnapshot::Impl::updateResolutionTextEntry(LLFloaterSnapshot* floater) +{ +	LLSpinCtrl* width_spinner = floater->getChild<LLSpinCtrl>("snapshot_width"); +	LLSpinCtrl* height_spinner = floater->getChild<LLSpinCtrl>("snapshot_height"); + +	if(getTypeIndex(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) +	{ +		width_spinner->setAllowEdit(FALSE); +		height_spinner->setAllowEdit(FALSE); +	} +	else +	{ +		width_spinner->setAllowEdit(TRUE); +		height_spinner->setAllowEdit(TRUE); +	} +} + +// static  void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)  {  	if (previewp) -	{		 -		previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"), update_thumbnail); +	{ +		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot"); +		previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);  	}  } @@ -1279,6 +1329,17 @@ void LLFloaterSnapshot::Impl::onClickDiscard(void* data)  	}  } + +// static +void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data) +{ +	if (ctrl->getValue().asString() == "save as") +	{ +		gViewerWindow->resetSnapshotLoc(); +	} +	onClickKeep(data); +} +  // static  void LLFloaterSnapshot::Impl::onClickKeep(void* data)  { @@ -1294,7 +1355,7 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data)  			LLFloaterPostcard* floater = previewp->savePostcard();  			// if still in snapshot mode, put postcard floater in snapshot floaterview  			// and link it to snapshot floater -			if (!gSavedSettings.getBOOL("CloseSnapshotOnKeep")) +			if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep"))  			{  				gFloaterView->removeChild(floater);  				gSnapshotFloaterView->addChild(floater); @@ -1610,6 +1671,22 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data)  	}  } + +//static  +void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data) +{ +	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;		 +	if (view) +	{ +		gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view)); +		getPreviewView(view)->updateSnapshot(TRUE); +		updateControls(view); +	} +} + + + +  // static  void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)  { @@ -1642,9 +1719,21 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3  			height = max_value ;  		} -		//round to nearest power of 2 -		width = get_nearest_power_two(width, MAX_TEXTURE_SIZE) ; -		height = get_nearest_power_two(height, MAX_TEXTURE_SIZE) ; +		//round to nearest power of 2 based on the direction of movement +		// i.e. higher power of two if increasing texture resolution +		if(gSavedSettings.getS32("LastSnapshotWidth") < width || +			gSavedSettings.getS32("LastSnapshotHeight") < height) +		{ +			// Up arrow pressed +			width = get_next_power_two(width, MAX_TEXTURE_SIZE) ; +			height = get_next_power_two(height, MAX_TEXTURE_SIZE) ; +		} +		else +		{ +			// Down or no change +			width = get_lower_power_two(width, MAX_TEXTURE_SIZE) ; +			height = get_lower_power_two(height, MAX_TEXTURE_SIZE) ; +		}  	}  	else if(previewp && previewp->mKeepAspectRatio)  	{ @@ -1716,9 +1805,6 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat  		S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());  		S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal()); -		gSavedSettings.setS32("LastSnapshotWidth", w); -		gSavedSettings.setS32("LastSnapshotHeight", h); -  		LLSnapshotLivePreview* previewp = getPreviewView(view);  		if (previewp)  		{ @@ -1750,7 +1836,10 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat  				}  				previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ; -				if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) || update_) +				 +				// Check image size changes the value of height and width +				if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) +					|| update_)  				{  					resetSnapshotSizeOnUI(view, w, h) ;  				} @@ -1762,6 +1851,10 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat  				comboSetCustom(view, "local_size_combo");  			}  		} + +		gSavedSettings.setS32("LastSnapshotWidth", w); +		gSavedSettings.setS32("LastSnapshotHeight", h); +  	}  } @@ -1800,6 +1893,7 @@ LLFloaterSnapshot::~LLFloaterSnapshot()  BOOL LLFloaterSnapshot::postBuild()  {  	childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this); +	childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this);  	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); @@ -1813,7 +1907,7 @@ BOOL LLFloaterSnapshot::postBuild()  	childSetAction("upload_btn", Impl::onClickKeep, this);  	childSetAction("send_btn", Impl::onClickKeep, this); -	childSetAction("save_btn", Impl::onClickKeep, this); +	childSetCommitCallback("save_btn", Impl::onCommitSave, this);  	childSetAction("discard_btn", Impl::onClickDiscard, this);  	childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this); @@ -1860,7 +1954,7 @@ BOOL LLFloaterSnapshot::postBuild()  	impl.updateControls(this); -    return TRUE; +	return TRUE;  }  void LLFloaterSnapshot::draw() @@ -1922,45 +2016,6 @@ void LLFloaterSnapshot::draw()  	LLFloater::draw(); -	// draw snapshot thumbnail if not in fullscreen preview mode -	/*if (previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate()) -	{ -		F32 aspect = previewp->getImageAspect(); -		// UI size for thumbnail -		S32 max_width = getRect().getWidth() - 20; -		S32 max_height = 90; - -		S32 img_render_width = 0; -		S32 img_render_height = 0; -		if (aspect > max_width / max_height) -		{ -			// image too wide, shrink to width -			img_render_width = max_width; -			img_render_height = llround((F32)max_width / aspect); -		} -		else -		{ -			// image too tall, shrink to height -			img_render_height = max_height; -			img_render_width = llround((F32)max_height * aspect); -		} -		S32 image_width, image_height; -		previewp->getSize(image_width, image_height); -		glMatrixMode(GL_TEXTURE); -		glPushMatrix(); -		{ -			// handle case where image is only a portion of image buffer -			if (!previewp->isImageScaled()) -			{ -				glScalef(llmin(1.f, (F32)image_width / (F32)previewp->getCurrentImage()->getWidth()), llmin(1.f, (F32)image_height / (F32)previewp->getCurrentImage()->getHeight()), 1.f); -			} -			glMatrixMode(GL_MODELVIEW); -			gl_draw_scaled_image((getRect().getWidth() - img_render_width) / 2, getRect().getHeight() - 205 + (max_height - img_render_height) / 2, img_render_width, img_render_height, previewp->getCurrentImage(), LLColor4::white); -		} -		glMatrixMode(GL_TEXTURE); -		glPopMatrix(); -		glMatrixMode(GL_MODELVIEW); -	}*/  	if (previewp)  	{		  		if(previewp->getThumbnailImage()) @@ -1990,7 +2045,6 @@ void LLFloaterSnapshot::show(void*)  	if (!sInstance)  	{  		sInstance = new LLFloaterSnapshot(); -  		LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE);  		//move snapshot floater to special purpose snapshotfloaterview  		gFloaterView->removeChild(sInstance); @@ -1998,6 +2052,14 @@ void LLFloaterSnapshot::show(void*)  		sInstance->impl.updateLayout(sInstance);  	} +	else // just refresh the snapshot in the existing floater instance (DEV-12255) +	{ +		LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(sInstance); +		if(preview) +		{ +			preview->updateSnapshot(TRUE); +		} +	}  	sInstance->open();		/* Flawfinder: ignore */  	sInstance->focusFirstItem(FALSE); @@ -2023,7 +2085,10 @@ void LLFloaterSnapshot::update()  	}  } -//============================================================================ + +///---------------------------------------------------------------------------- +/// Class LLSnapshotFloaterView +///----------------------------------------------------------------------------  LLSnapshotFloaterView::LLSnapshotFloaterView( const std::string& name, const LLRect& rect ) : LLFloaterView(name, rect)  { diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index a7aee1143c..bbf5c9e40b 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -38,15 +38,23 @@  #include "llimagegl.h"  #include "llcharacter.h" +  class LLFloaterSnapshot : public LLFloater  {  public: +	typedef enum e_snapshot_format +	{ +		SNAPSHOT_FORMAT_PNG, +		SNAPSHOT_FORMAT_JPEG, +		SNAPSHOT_FORMAT_BMP +	} ESnapshotFormat; +      LLFloaterSnapshot();  	virtual ~LLFloaterSnapshot(); -	virtual BOOL postBuild(); -	virtual void draw(); -	virtual void onClose(bool app_quitting); +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void draw(); +	/*virtual*/ void onClose(bool app_quitting);  	static void show(void*);  	static void hide(void*); @@ -79,4 +87,5 @@ public:  };  extern LLSnapshotFloaterView* gSnapshotFloaterView; +  #endif // LL_LLFLOATERSNAPSHOT_H diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index a8192e544c..d193685432 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -54,6 +54,7 @@  #include "llpanelvolume.h"  #include "llpanelpermissions.h"  #include "llselectmgr.h" +#include "llslider.h"  #include "llstatusbar.h"  #include "lltabcontainer.h"  #include "lltextbox.h" @@ -106,6 +107,7 @@ void click_popup_rotate_reset(void*);  void click_popup_rotate_right(void*);  void click_popup_dozer_mode(LLUICtrl *, void *user);  void click_popup_dozer_size(LLUICtrl *, void *user); +void commit_slider_dozer_force(LLUICtrl *, void*);  void click_dozer_size(LLUICtrl *, void*);  void click_apply_to_selection(void*);  void commit_radio_zoom(LLUICtrl *, void*); @@ -308,6 +310,12 @@ BOOL	LLFloaterTools::postBuild()  	childSetAction("button apply to selection",click_apply_to_selection,  (void*)0);  	mCheckShowOwners = getChild<LLCheckBoxCtrl>("checkbox show owners");  	childSetValue("checkbox show owners",gSavedSettings.getBOOL("ShowParcelOwners")); + +	mSliderDozerForce = getChild<LLSlider>("slider force"); +	childSetCommitCallback("slider force",commit_slider_dozer_force,  (void*)0); +	// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here +	childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce"))); +  	childSetAction("button more", click_show_more, this);  	childSetAction("button less", click_show_more, this);  	mTab = getChild<LLTabContainer>("Object Info Tabs"); @@ -741,6 +749,11 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  	{  		mCheckShowOwners	->setVisible( land_visible );  	} +	if (mSliderDozerForce) +	{ +		mSliderDozerForce	->setVisible( land_visible ); +		childSetVisible("Strength:", land_visible); +	}  	//  	// More panel visibility @@ -939,6 +952,16 @@ void click_dozer_size(LLUICtrl *ctrl, void *user)  	gSavedSettings.setS32("RadioLandBrushSize", size);  } +void commit_slider_dozer_force(LLUICtrl *ctrl, void*) +{ +	// the slider is logarithmic, so we exponentiate to get the actual force multiplier +	F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal()); +	gSavedSettings.setF32("LandBrushForce", dozer_force); +} + + + +  void click_apply_to_selection(void* user)  {  	LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal(); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index a6fdc76d9f..81e40c0408 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -48,6 +48,7 @@ class LLPanelContents;  class LLPanelFace;  class LLPanelLandInfo;  class LLComboBox; +class LLSlider;  class LLParcelSelection;  class LLObjectSelection; @@ -167,6 +168,7 @@ public:  	LLCheckBoxCtrl	*mRadioDozerSmooth;  	LLCheckBoxCtrl	*mRadioDozerNoise;  	LLCheckBoxCtrl	*mRadioDozerRevert; +	LLSlider		*mSliderDozerForce;  	LLComboBox		*mComboDozerSize;  	LLButton		*mBtnApplyToSelection; diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 93622ed94e..3c1b89d04b 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -44,6 +44,7 @@  #include "lllineeditor.h"  #include "lltextbox.h"  #include "lltracker.h" +#include "llviewermessage.h"  #include "llviewerparcelmgr.h"  #include "llviewerregion.h"  #include "lluictrlfactory.h" @@ -51,6 +52,8 @@  LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; +// Globals +// const U32 TIME_STR_LENGTH = 30;  // static  void LLFloaterTopObjects::show() @@ -161,6 +164,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)  	for (S32 block = 0; block < block_count; ++block)  	{  		U32 task_local_id; +		U32 time_stamp = 0;  		LLUUID task_id;  		F32 location_x, location_y, location_z;  		F32 score; @@ -175,7 +179,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)  		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);  		msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);  		msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block); -		 +		if(msg->getNumberOfBlocks("DataExtended")) +		{ +			msg->getU32("DataExtended", "TimeStamp", time_stamp, block); +		} +  		LLSD element;  		element["id"] = task_id; @@ -193,7 +201,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)  		element["columns"][3]["column"] = "location";  		element["columns"][3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);  		element["columns"][3]["font"] = "SANSSERIF"; - +		element["columns"][3]["column"] = "time"; +		element["columns"][3]["value"] = formatted_time((time_t)time_stamp); +		element["columns"][3]["font"] = "SANSSERIF"; +		  		list->addElement(element);  		mObjectListData.append(element); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 9d8641eb2f..a88a6bbffe 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1644,12 +1644,13 @@ BOOL LLFloaterIMPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  					if(drop)  					{  						LLToolDragAndDrop::giveInventory(mOtherParticipantUUID, inv_item); +						LLStringUtil::format_map_t args; +						gIMMgr->addSystemMessage(mSessionUUID, "inventory_item_offered", args);  					}  				}  			}  			break;  		} -		  	default:  		break;  	} diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ada8ab5fdc..60e6197bf7 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -209,8 +209,8 @@ static LLHost gAgentSimHost;  static BOOL gSkipOptionalUpdate = FALSE;  static bool gGotUseCircuitCodeAck = false; -std::string gInitialOutfit; -std::string gInitialOutfitGender;	// "male" or "female" +static std::string sInitialOutfit; +static std::string sInitialOutfitGender;	// "male" or "female"  static bool gUseCircuitCallbackCalled = false; @@ -348,8 +348,6 @@ BOOL idle_startup()  	static BOOL samename = FALSE; -	BOOL do_normal_idle = FALSE; -  	// HACK: These are things from the main loop that usually aren't done  	// until initialization is complete, but need to be done here for things  	// to work. @@ -634,34 +632,26 @@ BOOL idle_startup()  		// Go to the next startup state -		LLStartUp::setStartupState( STATE_MEDIA_INIT ); -		return do_normal_idle; +		LLStartUp::setStartupState( STATE_BROWSER_INIT ); +		return FALSE;  	} -	//--------------------------------------------------------------------- -	// LLMediaEngine Init -	//--------------------------------------------------------------------- -	if (STATE_MEDIA_INIT == LLStartUp::getStartupState()) +	if (STATE_BROWSER_INIT == LLStartUp::getStartupState())  	{ -		LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL; -		set_startup_status(0.03f, "Initializing Multimedia...", gAgent.mMOTD); +		LL_DEBUGS("AppInit") << "STATE_BROWSER_INIT" << LL_ENDL; +		std::string msg = LLTrans::getString("LoginInitializingBrowser"); +		set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());  		display_startup(); -		LLViewerMedia::initClass(); -		LLViewerParcelMedia::initClass(); - -		if (gViewerWindow) -		{ -			audio_update_volume(true); -		} +		LLViewerMedia::initBrowser();  		LLStartUp::setStartupState( STATE_LOGIN_SHOW ); -		return do_normal_idle; +		return FALSE;  	} -	if (STATE_LOGIN_SHOW == LLStartUp::getStartupState()) -	{		 +	if (STATE_LOGIN_SHOW == LLStartUp::getStartupState()) +	{  		LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL;  		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); @@ -723,7 +713,7 @@ BOOL idle_startup()  		gLoginMenuBarView->setEnabled( TRUE );  		timeout.reset(); -		return do_normal_idle; +		return FALSE;  	}  	if (STATE_LOGIN_WAIT == LLStartUp::getStartupState()) @@ -733,7 +723,7 @@ BOOL idle_startup()  		// Sleep so we don't spin the CPU  		ms_sleep(1); -		return do_normal_idle; +		return FALSE;  	}  	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) @@ -894,13 +884,13 @@ BOOL idle_startup()  		// skipping over STATE_UPDATE_CHECK because that just waits for input  		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); -		return do_normal_idle; +		return FALSE;  	}  	if (STATE_UPDATE_CHECK == LLStartUp::getStartupState())  	{  		// wait for user to give input via dialog box -		return do_normal_idle; +		return FALSE;  	}  	if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState()) @@ -1015,7 +1005,7 @@ BOOL idle_startup()  		gAcceptTOS = FALSE;  		gAcceptCriticalMessage = FALSE;  		LLStartUp::setStartupState( STATE_LOGIN_NO_DATA_YET ); -		return do_normal_idle; +		return FALSE;  	}  	if(STATE_LOGIN_NO_DATA_YET == LLStartUp::getStartupState()) @@ -1035,12 +1025,12 @@ BOOL idle_startup()  		if(LLUserAuth::E_NO_RESPONSE_YET == error)  		{  			LL_DEBUGS("AppInit") << "waiting..." << LL_ENDL; -			return do_normal_idle; +			return FALSE;  		}  		LLStartUp::setStartupState( STATE_LOGIN_DOWNLOADING );  		progress += 0.01f;  		set_startup_status(progress, auth_desc, auth_message); -		return do_normal_idle; +		return FALSE;  	}  	if(STATE_LOGIN_DOWNLOADING == LLStartUp::getStartupState()) @@ -1056,12 +1046,12 @@ BOOL idle_startup()  		if(LLUserAuth::E_DOWNLOADING == error)  		{  			LL_DEBUGS("AppInit") << "downloading..." << LL_ENDL; -			return do_normal_idle; +			return FALSE;  		}  		LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );  		progress += 0.01f;  		set_startup_status(progress, LLTrans::getString("LoginProcessingResponse"), auth_message); -		return do_normal_idle; +		return FALSE;  	}  	if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState()) @@ -1104,7 +1094,7 @@ BOOL idle_startup()  				// ignoring the duration & options array for now.  				// Go back to authenticate.  				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); -				return do_normal_idle; +				return FALSE;  			}  			else  			{ @@ -1216,7 +1206,7 @@ BOOL idle_startup()  				args["[NUMBER]"] = llformat("%d", sAuthUriNum + 1);  				auth_desc = LLTrans::getString("LoginAttempt", args);  				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); -				return do_normal_idle; +				return FALSE;  			}  			break;  		} @@ -1391,12 +1381,14 @@ BOOL idle_startup()  				it = options[0].find("folder_name");  				if(it != it_end)  				{ -					gInitialOutfit = (*it).second; +					// Initial outfit is a folder in your inventory, +					// must be an exact folder-name match. +					sInitialOutfit = (*it).second;  				}  				it = options[0].find("gender");  				if (it != it_end)  				{ -					gInitialOutfitGender = (*it).second; +					sInitialOutfitGender = (*it).second;  				}  			} @@ -1475,7 +1467,7 @@ BOOL idle_startup()  			// Don't save an incorrect password to disk.  			save_password_to_disk(NULL);  		} -		return do_normal_idle; +		return FALSE;  	}  	//--------------------------------------------------------------------- @@ -1533,7 +1525,6 @@ BOOL idle_startup()  		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle);  		LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL; -		LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );  		regionp->setSeedCapability(first_sim_seed_cap);  		LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL; @@ -1545,16 +1536,28 @@ BOOL idle_startup()  		gAgent.setPositionAgent(agent_start_position_region);  		display_startup(); -		return do_normal_idle; +		LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT ); +		return FALSE;  	}  	//--------------------------------------------------------------------- +	// Load QuickTime/GStreamer and other multimedia engines, can be slow. +	// Do it while we're waiting on the network for our seed capability. JC +	//--------------------------------------------------------------------- +	if (STATE_MULTIMEDIA_INIT == LLStartUp::getStartupState()) +	{ +		LLStartUp::multimediaInit(); +		LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT ); +		return FALSE; +	} + +	//---------------------------------------------------------------------  	// Wait for Seed Cap Grant  	//---------------------------------------------------------------------  	if(STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())  	{ -		return do_normal_idle; +		return FALSE;  	} @@ -1733,7 +1736,7 @@ BOOL idle_startup()  		timeout.reset(); -		return do_normal_idle; +		return FALSE;  	}  	//--------------------------------------------------------------------- @@ -1752,7 +1755,7 @@ BOOL idle_startup()  		{  		}  		msg->processAcks(); -		return do_normal_idle; +		return FALSE;  	}  	//--------------------------------------------------------------------- @@ -1791,7 +1794,7 @@ BOOL idle_startup()  		LLStartUp::setStartupState( STATE_AGENT_WAIT );		// Go to STATE_AGENT_WAIT  		timeout.reset(); -		return do_normal_idle; +		return FALSE;  	}  	//--------------------------------------------------------------------- @@ -1823,7 +1826,7 @@ BOOL idle_startup()  			LLStartUp::setStartupState( STATE_INVENTORY_SEND );  		} -		return do_normal_idle; +		return FALSE;  	}  	//--------------------------------------------------------------------- @@ -2011,7 +2014,7 @@ BOOL idle_startup()  		}  		LLStartUp::setStartupState( STATE_MISC ); -		return do_normal_idle; +		return FALSE;  	} @@ -2202,26 +2205,27 @@ BOOL idle_startup()  		LLStartUp::setStartupState( STATE_PRECACHE );  		timeout.reset(); -		return do_normal_idle; +		return FALSE;  	}  	if (STATE_PRECACHE == LLStartUp::getStartupState())  	{ -		do_normal_idle = TRUE; -		 -		// Avoid generic Ruth avatar in Orientation Island by starting -		// our outfit load as soon as possible.  This will be replaced -		// with a more definitive patch from featurettes-4 later. JC +		F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY; + +		// We now have an inventory skeleton, so if this is a user's first +		// login, we can start setting up their clothing and avatar  +		// appearance.  This helps to avoid the generic "Ruth" avatar in +		// the orientation island tutorial experience. JC  		if (gAgent.isFirstLogin() -			&& !gInitialOutfit.empty()  // registration set up an outfit -			&& gAgent.getAvatarObject()	// can't wear clothes until have obj -			&& !gAgent.isGenderChosen() ) // nothing already loaded +			&& !sInitialOutfit.empty()    // registration set up an outfit +			&& !sInitialOutfitGender.empty() // and a gender +			&& gAgent.getAvatarObject()	  // can't wear clothes without object +			&& !gAgent.isGenderChosen() ) // nothing already loading  		{ -			llinfos << "Wearing initial outfit " << gInitialOutfit << llendl; -			callback_choose_gender(-1, NULL); +			// Start loading the wearables, textures, gestures +			LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );  		} -		F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;  		// wait precache-delay and for agent's avatar or a lot longer.  		if(((timeout_frac > 1.f) && gAgent.getAvatarObject())  		   || (timeout_frac > 3.f)) @@ -2231,49 +2235,80 @@ BOOL idle_startup()  		else  		{  			update_texture_fetch(); -			set_startup_status(0.60f + 0.20f * timeout_frac, +			set_startup_status(0.60f + 0.30f * timeout_frac,  				"Loading world...",  					gAgent.mMOTD);  		} -		return do_normal_idle; +		return TRUE;  	}  	if (STATE_WEARABLES_WAIT == LLStartUp::getStartupState())  	{ -		do_normal_idle = TRUE; -  		static LLFrameTimer wearables_timer;  		const F32 wearables_time = wearables_timer.getElapsedTimeF32();  		const F32 MAX_WEARABLES_TIME = 10.f; -		if(gAgent.getWearablesLoaded() || !gAgent.isGenderChosen()) +		if (!gAgent.isGenderChosen())  		{ +			// No point in waiting for clothing, we don't even +			// know what gender we are.  Pop a dialog to ask and +			// proceed to draw the world. JC +			// +			// *NOTE: We might hit this case even if we have an +			// initial outfit, but if the load hasn't started +			// already then something is wrong so fall back +			// to generic outfits. JC +			gViewerWindow->alertXml("WelcomeChooseSex", +				callback_choose_gender, NULL);  			LLStartUp::setStartupState( STATE_CLEANUP ); +			return TRUE;  		} -		else if (wearables_time > MAX_WEARABLES_TIME) +		 +		if (wearables_time > MAX_WEARABLES_TIME)  		{ +			// It's taken too long to load, show the world  			gViewerWindow->alertXml("ClothingLoading");  			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);  			LLStartUp::setStartupState( STATE_CLEANUP ); +			return TRUE; +		} + +		if (gAgent.isFirstLogin()) +		{ +			// wait for avatar to be completely loaded +			if (gAgent.getAvatarObject() +				&& gAgent.getAvatarObject()->isFullyLoaded()) +			{ +				//llinfos << "avatar fully loaded" << llendl; +				LLStartUp::setStartupState( STATE_CLEANUP ); +				return TRUE; +			}  		}  		else  		{ -			update_texture_fetch(); -			set_startup_status(0.80f + 0.20f * wearables_time / MAX_WEARABLES_TIME, -							 LLTrans::getString("LoginDownloadingClothing"), -							 gAgent.mMOTD); +			// OK to just get the wearables +			if ( gAgent.getWearablesLoaded() ) +			{ +				// We have our clothing, proceed. +				//llinfos << "wearables loaded" << llendl; +				LLStartUp::setStartupState( STATE_CLEANUP ); +				return TRUE; +			}  		} -		return do_normal_idle; + +		update_texture_fetch(); +		set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME, +						 LLTrans::getString("LoginDownloadingClothing").c_str(), +						 gAgent.mMOTD.c_str()); +		return TRUE;  	}  	if (STATE_CLEANUP == LLStartUp::getStartupState())  	{  		set_startup_status(1.0, "", ""); -		do_normal_idle = TRUE; -  		// Let the map know about the inventory.  		if(gFloaterWorldMap)  		{ @@ -2299,9 +2334,6 @@ BOOL idle_startup()  			gAgent.requestEnterGodMode();  		} -		// On first start, ask user for gender -		dialog_choose_gender_first_start(); -  		// Start automatic replay if the flag is set.  		if (gSavedSettings.getBOOL("StatsAutoRun"))  		{ @@ -2335,11 +2367,11 @@ BOOL idle_startup()  		LLAppViewer::instance()->initMainloopTimeout("Mainloop Init"); -		return do_normal_idle; +		return TRUE;  	}  	LL_WARNS("AppInit") << "Reached end of idle_startup for state " << LLStartUp::getStartupState() << LL_ENDL; -	return do_normal_idle; +	return TRUE;  }  // @@ -3548,55 +3580,47 @@ const std::string MALE_GESTURES_FOLDER = "Male Gestures";  const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";  const std::string MALE_OUTFIT_FOLDER = "Male Shape & Outfit";  const std::string FEMALE_OUTFIT_FOLDER = "Female Shape & Outfit"; -const S32 OPT_USE_INITIAL_OUTFIT = -2;  const S32 OPT_CLOSED_WINDOW = -1;  const S32 OPT_MALE = 0;  const S32 OPT_FEMALE = 1;  void callback_choose_gender(S32 option, void* userdata)  { -	S32 gender = OPT_FEMALE; -	std::string outfit; +	switch(option) +	{ +	case OPT_MALE: +		LLStartUp::loadInitialOutfit( MALE_OUTFIT_FOLDER, "male" ); +		break; + +	case OPT_FEMALE: +	case OPT_CLOSED_WINDOW: +	default: +		LLStartUp::loadInitialOutfit( FEMALE_OUTFIT_FOLDER, "female" ); +		break; +	} +} + +void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, +								   const std::string& gender_name ) +{ +	S32 gender = 0;  	std::string gestures; -	if (!gInitialOutfit.empty()) +	if (gender_name == "male")  	{ -		outfit = gInitialOutfit; -		if (gInitialOutfitGender == "male") -		{ -			gender = OPT_MALE; -			gestures = MALE_GESTURES_FOLDER; -		} -		else -		{ -			gender = OPT_FEMALE; -			gestures = FEMALE_GESTURES_FOLDER; -		} +		gender = OPT_MALE; +		gestures = MALE_GESTURES_FOLDER;  	}  	else  	{ -		switch(option) -		{ -		case OPT_MALE: -			gender = OPT_MALE; -			outfit = MALE_OUTFIT_FOLDER; -			gestures = MALE_GESTURES_FOLDER; -			break; - -		case OPT_FEMALE: -		case OPT_CLOSED_WINDOW: -		default: -			gender = OPT_FEMALE; -			outfit = FEMALE_OUTFIT_FOLDER; -			gestures = FEMALE_GESTURES_FOLDER; -			break; -		} +		gender = OPT_FEMALE; +		gestures = FEMALE_GESTURES_FOLDER;  	}  	// try to find the outfit - if not there, create some default  	// wearables.  	LLInventoryModel::cat_array_t cat_array;  	LLInventoryModel::item_array_t item_array; -	LLNameCategoryCollector has_name(outfit); +	LLNameCategoryCollector has_name(outfit_folder_name);  	gInventory.collectDescendentsIf(LLUUID::null,  									cat_array,  									item_array, @@ -3608,36 +3632,16 @@ void callback_choose_gender(S32 option, void* userdata)  	}  	else  	{ -		wear_outfit_by_name(outfit); +		wear_outfit_by_name(outfit_folder_name);  	}  	wear_outfit_by_name(gestures);  	wear_outfit_by_name(COMMON_GESTURES_FOLDER); -	typedef std::map<LLUUID, LLMultiGesture*> item_map_t; -	item_map_t::iterator gestureIterator; - -	// Must be here so they aren't invisible if they close the window. +	// This is really misnamed -- it means we have started loading +	// an outfit/shape that will give the avatar a gender eventually. JC  	gAgent.setGenderChosen(TRUE);  } - -void dialog_choose_gender_first_start() -{ -	if (!gNoRender -		&& (!gAgent.isGenderChosen())) -	{ -		if (!gInitialOutfit.empty()) -		{ -			gViewerWindow->alertXml("WelcomeNoClothes", -				callback_choose_gender, NULL); -		} -		else -		{	 -			gViewerWindow->alertXml("WelcomeChooseSex", -				callback_choose_gender, NULL); -		} -	} -}  // Loads a bitmap to display during load  // location_id = 0 => last position @@ -3736,6 +3740,19 @@ bool LLStartUp::canGoFullscreen()  	return gStartupState >= STATE_WORLD_INIT;  } +// Initialize all plug-ins except the web browser (which was initialized +// early, before the login screen). JC +void LLStartUp::multimediaInit() +{ +	LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL; +	std::string msg = LLTrans::getString("LoginInitializingMultimedia"); +	set_startup_status(0.50f, msg.c_str(), gAgent.mMOTD.c_str()); +	display_startup(); + +	LLViewerMedia::initClass(); +	LLViewerParcelMedia::initClass(); +} +  bool LLStartUp::dispatchURL()  {  	// ok, if we've gotten this far and have a startup URL diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 38319c8d8a..ea568395d4 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -46,7 +46,7 @@ extern std::string SCREEN_LAST_FILENAME;  enum EStartupState{  	STATE_FIRST,					// Initial startup -	STATE_MEDIA_INIT,               // Initialzie media library +	STATE_BROWSER_INIT,             // Initialize web browser for login screen  	STATE_LOGIN_SHOW,				// Show login screen  	STATE_LOGIN_WAIT,				// Wait for user input at login screen  	STATE_LOGIN_CLEANUP,			// Get rid of login screen and start login @@ -57,6 +57,7 @@ enum EStartupState{  	STATE_LOGIN_DOWNLOADING,		// Waiting for authentication replies to download  	STATE_LOGIN_PROCESS_RESPONSE,	// Check authentication reply  	STATE_WORLD_INIT,				// Start building the world +	STATE_MULTIMEDIA_INIT,			// Init the rest of multimedia library  	STATE_SEED_GRANTED_WAIT,		// Wait for seed cap grant  	STATE_SEED_CAP_GRANTED,			// Have seed cap grant   	STATE_WORLD_WAIT,				// Waiting for simulator @@ -87,6 +88,15 @@ public:  	static void	setStartupState( S32 state );  	static S32	getStartupState()				{ return gStartupState;		}; +	static void multimediaInit(); +		// Initialize LLViewerMedia multimedia engine. + +	// outfit_folder_name can be a folder anywhere in your inventory,  +	// but the name must be a case-sensitive exact match. +	// gender_name is either "male" or "female" +	static void loadInitialOutfit( const std::string& outfit_folder_name, +								   const std::string& gender_name ); +  	static bool dispatchURL();  		// if we have a SLURL or sim string ("Ahern/123/45") that started  		// the viewer, dispatch it diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 421f0196e3..c522bd0697 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -910,7 +910,7 @@ LLTextureCtrl::LLTextureCtrl(  	mNeedsRawImageData( FALSE ),  	mValid( TRUE ),  	mDirty( FALSE ), -	mShowLoadingPlaceholder( FALSE ) +	mShowLoadingPlaceholder( TRUE )  {  	mCaption = new LLTextBox( label,   		LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ), @@ -1327,6 +1327,10 @@ void LLTextureCtrl::draw()  	mTentativeLabel->setVisible( !mTexturep.isNull() && getTentative() ); +	 +	// Show "Loading..." string on the top left corner while this texture is loading. +	// Using the discard level, do not show the string if the texture is almost but not  +	// fully loaded.  	if ( mTexturep.notNull() &&  		 (mShowLoadingPlaceholder == TRUE) &&   		 (mTexturep->getDiscardLevel() != 1) && diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index 1b006822c1..b644e43a64 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -154,7 +154,7 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global,  		regionp->forceUpdate();  		// tell the simulator what we've done -		F32 seconds = 1.0f / gFPSClamped; +		F32 seconds = (1.0f / gFPSClamped) * gSavedSettings.getF32("LandBrushForce");  		F32 x_pos = (F32)pos_region.mV[VX];  		F32 y_pos = (F32)pos_region.mV[VY];  		U8 brush_size = (U8)mBrushIndex; @@ -242,7 +242,7 @@ void LLToolBrushLand::modifyLandInSelectionGlobal()  		min_region.clamp(0.f, regionp->getWidth());  		max_region.clamp(0.f, regionp->getWidth()); -		F32 seconds = 1.0f; +		F32 seconds = gSavedSettings.getF32("LandBrushForce");  		LLSurface &land = regionp->getLand();  		char action = E_LAND_LEVEL; @@ -251,21 +251,23 @@ void LLToolBrushLand::modifyLandInSelectionGlobal()  		case 0:  		//	// average toward mStartingZ  			action = E_LAND_LEVEL; -			seconds = 1.f; +			seconds *= 0.25f;  			break;  		case 1:  			action = E_LAND_RAISE; +			seconds *= 0.25f;  			break;  		case 2:  			action = E_LAND_LOWER; +			seconds *= 0.25f;  			break;  		case 3:  			action = E_LAND_SMOOTH; -			seconds = 10.f; +			seconds *= 5.0f;  			break;  		case 4:  			action = E_LAND_NOISE; -			seconds = 0.5f; +			seconds *= 0.5f;  			break;  		case 5:  			action = E_LAND_REVERT; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index f803ef3a3e..f80eb6e486 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -415,12 +415,44 @@ LLUUID LLViewerMediaImpl::getMediaTextureID()  // Wrapper class  ////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////// +// The viewer takes a long time to load the start screen.  Part of the problem +// is media initialization -- in particular, QuickTime loads many DLLs and +// hits the disk heavily.  So we initialize only the browser component before +// the login screen, then do the rest later when we have a progress bar. JC +// static +void LLViewerMedia::initBrowser() +{ +	LLMediaManagerData* init_data = new LLMediaManagerData; +	buildMediaManagerData( init_data ); +	LLMediaManager::initBrowser( init_data ); +	delete init_data; +} +  //////////////////////////////////////////////////////////////////////////////////////////  // static  void LLViewerMedia::initClass()  {  	LLMediaManagerData* init_data = new LLMediaManagerData; +	buildMediaManagerData( init_data ); +	LLMediaManager::initClass( init_data ); +	delete init_data; + +	LLMediaManager* mm = LLMediaManager::getInstance(); +	LLMIMETypes::mime_info_map_t::const_iterator it; +	for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it) +	{ +		const std::string& mime_type = it->first; +		const LLMIMETypes::LLMIMEInfo& info = it->second; +		mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); +	} +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::buildMediaManagerData( LLMediaManagerData* init_data ) +{  //	std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") );  //	std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") );  //	component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); @@ -467,17 +499,6 @@ void LLViewerMedia::initClass()  	std::string profile_name("Second Life");  	init_data->setBrowserProfileName( profile_name );  	init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() ); - -	LLMediaManager::initClass( init_data ); - -	LLMediaManager* mm = LLMediaManager::getInstance(); -	LLMIMETypes::mime_info_map_t::const_iterator it; -	for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it) -	{ -		const std::string& mime_type = it->first; -		const LLMIMETypes::LLMIMEInfo& info = it->second; -		mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); -	}  }  ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 67a75c7b0f..3f012fef76 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -34,11 +34,16 @@  #include "llmediabase.h"	// for status codes +class LLMediaManagerData;  class LLUUID;  class LLViewerMedia  {  	public: +		// Special case early init for just web browser component +		// so we can show login screen.  See .cpp file for details. JC +		static void initBrowser(); +  		static void initClass();  		static void cleanupClass(); @@ -67,6 +72,10 @@ class LLViewerMedia  		static void setMimeType(std::string mime_type);  		static void updateImagesMediaStreams(); + +	private: +		// Fill in initialization data for LLMediaManager::initClass() +		static void buildMediaManagerData( LLMediaManagerData* init_data );  };  #endif	// LLVIEWERMEDIA_H diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 00cc94c3d3..7db03c9db4 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -436,9 +436,29 @@ class LLFileTakeSnapshotToDisk : public view_listener_t  			{  				gViewerWindow->playSnapshotAnimAndSound();  			} +			  			LLImageBase::setSizeOverride(TRUE); -			gViewerWindow->saveImageNumbered(raw); +			LLPointer<LLImageFormatted> formatted; +			switch(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))) +			{ +			  case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: +				formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality")); +				break; +			  case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: +				formatted = new LLImagePNG; +				break; +			  case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:  +				formatted = new LLImageBMP; +				break; +			  default:  +				llwarns << "Unknown Local Snapshot format" << llendl; +				LLImageBase::setSizeOverride(FALSE); +				return true; +			} + +			formatted->encode(raw, 0);  			LLImageBase::setSizeOverride(FALSE); +			gViewerWindow->saveImageNumbered(formatted);  		}  		return true;  	} diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 114707791b..a082d6f1b5 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1175,8 +1175,17 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)  		return;  	} +	// Strip any SLURL from the message display. (DEV-2754) +	std::string msg = info->mDesc; +	int indx = msg.find(" ( http://slurl.com/secondlife/"); +	if(indx >= 0) +	{ +		LLStringUtil::truncate(msg, indx); +	} +	  	LLStringUtil::format_map_t args; -	args["[OBJECTNAME]"] = info->mDesc; +	args["[OBJECTNAME]"] = msg; +  	// must protect against a NULL return from lookupHumanReadable()  	std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));  	if (!typestr.empty()) diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index ce0fe2c836..4ab0508fba 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -122,6 +122,7 @@  //#include "llblockencoder.h"  #include "llimage.h"  #include "llimagebmp.h" +#include "llimagepng.h"  #include "llimagej2c.h"  #include "llimagejpeg.h"  #include "llimagetga.h" diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b37b66effa..be9e9d4d68 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1517,7 +1517,6 @@ LLViewerWindow::LLViewerWindow(  	LLViewerWindow::sMovieBaseName = "SLmovie";  	LLViewerWindow::sSnapshotDir.clear(); -  	// create window  	mWindow = LLWindowManager::createWindow(  		title, name, x, y, width, height, 0, @@ -4049,14 +4048,14 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d  }  // Saves an image to the harddrive as "SnapshotX" where X >= 1. -BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const std::string& extension_in) +BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)  { -	if (! raw) +	if (!image)  	{  		return FALSE;  	} -	std::string extension(extension_in); +	std::string extension("." + image->getExtension());  	if (extension.empty())  	{  		extension = (gSavedSettings.getBOOL("CompressSnapshotsToDisk")) ? ".j2c" : ".bmp"; @@ -4067,6 +4066,10 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const std::string& exten  		pick_type = LLFilePicker::FFSAVE_J2C;  	else if (extension == ".bmp")  		pick_type = LLFilePicker::FFSAVE_BMP; +	else if (extension == ".jpg") +		pick_type = LLFilePicker::FFSAVE_JPEG; +	else if (extension == ".png") +		pick_type = LLFilePicker::FFSAVE_PNG;  	else if (extension == ".tga")  		pick_type = LLFilePicker::FFSAVE_TGA;  	else @@ -4112,22 +4115,13 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const std::string& exten  	}  	while( -1 != err );  // search until the file is not found (i.e., stat() gives an error). -	LLPointer<LLImageFormatted> formatted_image = LLImageFormatted::createFromExtension(extension); -	LLImageBase::setSizeOverride(TRUE); -	BOOL success = formatted_image->encode(raw, 0.0f); -	if( success ) -	{ -		success = formatted_image->save(filepath); -	} -	else -	{ -		llwarns << "Unable to encode bmp snapshot" << llendl; -	} -	LLImageBase::setSizeOverride(FALSE); - -	return success; +	return image->save(filepath);  } +void LLViewerWindow::resetSnapshotLoc() +{ +	sSnapshotDir.clear(); +}  static S32 BORDERHEIGHT = 0;  static S32 BORDERWIDTH = 0; @@ -4430,7 +4424,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  		image_buffer_x = llfloor(snapshot_width*scale_factor) ;  		image_buffer_y = llfloor(snapshot_height *scale_factor) ;  	} -	raw->resize(image_buffer_x, image_buffer_y, type == SNAPSHOT_TYPE_DEPTH ? 4 : 3); +	raw->resize(image_buffer_x, image_buffer_y, 3);  	if(raw->isBufferInvalid())  	{  		return FALSE ; @@ -4476,7 +4470,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  			}  			else  			{ -				display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), use_fbo); +				display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), TRUE); +				// Required for showing the GUI in snapshots?  See DEV-16350 for details. JC +				render_ui_and_swap();  			}  			S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); @@ -4485,49 +4481,43 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  									llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));  			for(U32 out_y = 0; out_y < read_height ; out_y++)  			{ +				S32 output_buffer_offset = (  +							(out_y * (raw->getWidth())) // ...plus iterated y... +							+ (window_width * subimage_x) // ...plus subimage start in x... +							+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... +							- output_buffer_offset_x // ...minus buffer padding x... +							- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... +						) * raw->getComponents();  				if (type == SNAPSHOT_TYPE_OBJECT_ID || type == SNAPSHOT_TYPE_COLOR)  				{  					glReadPixels(  						subimage_x_offset, out_y + subimage_y_offset,  						read_width, 1,  						GL_RGB, GL_UNSIGNED_BYTE, -						raw->getData() + // current output pixel is beginning of buffer... -							(  -								(out_y * (raw->getWidth())) // ...plus iterated y... -								+ (window_width * subimage_x) // ...plus subimage start in x... -								+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... -								- output_buffer_offset_x // ...minus buffer padding x... -								- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... -							) * 3 // times 3 bytes per pixel +						raw->getData() + output_buffer_offset  					);  				}  				else // SNAPSHOT_TYPE_DEPTH  				{ -					S32 output_buffer_offset = (  -								(out_y * (raw->getWidth())) // ...plus iterated y... -								+ (window_width * subimage_x) // ...plus subimage start in x... -								+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... -								- output_buffer_offset_x // ...minus buffer padding x... -								- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... -							) * 4; // times 4 bytes per pixel - +					LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values  					glReadPixels(  						subimage_x_offset, out_y + subimage_y_offset,  						read_width, 1,  						GL_DEPTH_COMPONENT, GL_FLOAT, -						raw->getData() + output_buffer_offset// current output pixel is beginning of buffer... +						depth_line_buffer->getData()// current output pixel is beginning of buffer...  					); -					for (S32 i = output_buffer_offset; i < output_buffer_offset + (S32)read_width * 4; i += 4) +					for (S32 i = 0; i < (S32)read_width; i++)  					{ -						F32 depth_float = *(F32*)(raw->getData() + i); +						F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));  						F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));  						U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); -						*(raw->getData() + i + 0) = depth_byte; -						*(raw->getData() + i + 1) = depth_byte; -						*(raw->getData() + i + 2) = depth_byte; -						*(raw->getData() + i + 3) = 255; +						//write converted scanline out to result image +						for(S32 j = 0; j < raw->getComponents(); j++) +						{ +							*(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; +						}  					}  				}  			} @@ -4565,7 +4555,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	// Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding)  	// Note: this formula depends on the number of components being 3.  Not obvious, but it's correct.	 -	image_width += (image_width * (type == SNAPSHOT_TYPE_DEPTH ? 4 : 3)) % 4 ;	 +	image_width += (image_width * 3) % 4;  	// Resize image  	if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 997ac21dfd..5c0eae61be 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -192,7 +192,7 @@ public:  	// Hide normal UI when a logon fails, re-show everything when logon is attempted again  	void			setNormalControlsVisible( BOOL visible ); -    void            setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false); +	void			setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);  	// Handle the application becoming active (frontmost) or inactive  	//BOOL			handleActivate(BOOL activate); @@ -219,18 +219,24 @@ public:  	static void		movieSize(S32 new_width, S32 new_height); +	// snapshot functionality. +	// perhaps some of this should move to llfloatershapshot?  -MG  	typedef enum e_snapshot_type  	{  		SNAPSHOT_TYPE_COLOR,  		SNAPSHOT_TYPE_DEPTH,  		SNAPSHOT_TYPE_OBJECT_ID  	} ESnapshotType; -  	BOOL			saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR);  	BOOL			rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,  								BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_IMAGE_SIZE ); -	BOOL            thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ; -	BOOL		    saveImageNumbered(LLImageRaw *raw, const std::string& extension = std::string()); + +	BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ; +	BOOL		    saveImageNumbered(LLImageFormatted *image); + +	// Reset the directory where snapshots are saved. +	// Client will open directory picker on next snapshot save. +	void resetSnapshotLoc();  	void			playSnapshotAnimAndSound(); | 
