diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llcompilequeue.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/lllocalbitmaps.cpp | 925 | ||||
| -rw-r--r-- | indra/newview/lllocalbitmaps.h | 130 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.cpp | 172 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.h | 2 | ||||
| -rw-r--r-- | indra/newview/lltoastnotifypanel.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.h | 1 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llwearable.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llwearable.h | 1 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_image_preview.xml | 6 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_texture_ctrl.xml | 192 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_window_size.xml | 60 | 
15 files changed, 1454 insertions, 90 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f85b943c70..54134fb610 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -303,6 +303,7 @@ set(viewer_SOURCE_FILES      lllistbrowser.cpp      lllistcontextmenu.cpp      lllistview.cpp +    lllocalbitmaps.cpp      lllocaltextureobject.cpp      lllocationhistory.cpp      lllocationinputctrl.cpp @@ -859,6 +860,7 @@ set(viewer_HEADER_FILES      lllistbrowser.h      lllistcontextmenu.h      lllistview.h +    lllocalbitmaps.h      lllocaltextureobject.h      lllocationhistory.h      lllocationinputctrl.h diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index a42677845e..91cf630932 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -100,6 +100,7 @@ BOOL LLFloaterScriptQueue::postBuild()  {  	childSetAction("close",onCloseBtn,this);  	getChildView("close")->setEnabled(FALSE); +	setVisible(true);  	return TRUE;  } @@ -178,7 +179,7 @@ BOOL LLFloaterScriptQueue::start()  	args["[COUNT]"] = llformat ("%d", mObjectIDs.count());  	buffer = getString ("Starting", args); -	getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer); +	getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);  	return nextObject();  } @@ -211,7 +212,7 @@ BOOL LLFloaterScriptQueue::nextObject()  	if(isDone() && !mDone)  	{  		mDone = true; -		getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("Done")); +		getChild<LLScrollListCtrl>("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM);  		getChildView("close")->setEnabled(TRUE);  	}  	return successful_start; @@ -277,7 +278,7 @@ public:  			return;  		} -		queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(message); +		queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM);  	}  private: @@ -464,7 +465,7 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,  	}  	if(queue && (buffer.size() > 0))   	{ -		queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer); +		queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);  	}  	delete data;  } @@ -637,7 +638,7 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,  				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));  				std::string buffer;  				buffer = getString("Resetting") + (": ") + item->getName(); -				getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer); +				getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);  				LLMessageSystem* msg = gMessageSystem;  				msg->newMessageFast(_PREHASH_ScriptReset);  				msg->nextBlockFast(_PREHASH_AgentData); @@ -690,7 +691,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,  				LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");  				std::string buffer;  				buffer = getString("Running") + (": ") + item->getName(); -				list->setCommentText(buffer); +				list->addSimpleElement(buffer, ADD_BOTTOM);  				LLMessageSystem* msg = gMessageSystem;  				msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -745,7 +746,7 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj,  				LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");  				std::string buffer;  				buffer = getString("NotRunning") + (": ") +item->getName(); -				list->setCommentText(buffer); +				list->addSimpleElement(buffer, ADD_BOTTOM);  				LLMessageSystem* msg = gMessageSystem;  				msg->newMessageFast(_PREHASH_SetScriptRunning); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp new file mode 100644 index 0000000000..b96fc06226 --- /dev/null +++ b/indra/newview/lllocalbitmaps.cpp @@ -0,0 +1,925 @@ +/**  + * @file lllocalbitmaps.cpp + * @author Vaalith Jinn + * @brief Local Bitmaps source + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/* precompiled headers */ +#include "llviewerprecompiledheaders.h" + +/* own header */ +#include "lllocalbitmaps.h" + +/* boost: will not compile unless equivalent is undef'd, beware. */ +#ifdef equivalent +#undef equivalent +#endif  +#include <boost/filesystem.hpp> + +/* image compression headers. */ +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +/* time headers */ +#include <time.h> +#include <ctime> + +/* misc headers */ +#include "llscrolllistctrl.h" +#include "llfilepicker.h" +#include "llviewertexturelist.h" +#include "llviewerobjectlist.h" +#include "llviewerobject.h" +#include "llface.h" +#include "llvoavatarself.h" +#include "llwearable.h" +#include "llagentwearables.h" +#include "lltexlayerparams.h" +#include "llvovolume.h" + +/*=======================================*/ +/*  Formal declarations, constants, etc. */ +/*=======================================*/  +std::list<LLLocalBitmap*>   LLLocalBitmapMgr::sBitmapList; +LLLocalBitmapTimer          LLLocalBitmapMgr::sTimer; +bool                        LLLocalBitmapMgr::sNeedsRebake; + +static const F32 LL_LOCAL_TIMER_HEARTBEAT   = 3.0; +static const BOOL LL_LOCAL_USE_MIPMAPS      = true; +static const S32 LL_LOCAL_DISCARD_LEVEL     = 0; +static const U32 LL_LOCAL_TEXLAYER_FOR_IDX  = 0; +static const bool LL_LOCAL_SLAM_FOR_DEBUG   = true; +static const bool LL_LOCAL_REPLACE_ON_DEL   = true; +static const S32 LL_LOCAL_UPDATE_RETRIES    = 5; + +/*=======================================*/ +/*  LLLocalBitmap: unit class            */ +/*=======================================*/  +LLLocalBitmap::LLLocalBitmap(std::string filename) +	: mFilename(filename) +	, mShortName(gDirUtilp->getBaseFileName(filename, true)) +	, mValid(false) +	, mLastModified() +	, mLinkStatus(LS_ON) +	, mUpdateRetries(LL_LOCAL_UPDATE_RETRIES) +{ +	mTrackingID.generate(); + +	/* extension */ +	std::string temp_exten = gDirUtilp->getExtension(mFilename); + +	if (temp_exten == "bmp") +	{  +		mExtension = ET_IMG_BMP; +	} +	else if (temp_exten == "tga") +	{ +		mExtension = ET_IMG_TGA; +	} +	else if (temp_exten == "jpg" || temp_exten == "jpeg") +	{ +		mExtension = ET_IMG_JPG; +	} +	else if (temp_exten == "png") +	{ +		mExtension = ET_IMG_PNG; +	} +	else +	{ +		llwarns << "File of no valid extension given, local bitmap creation aborted." << "\n" +			    << "Filename: " << mFilename << llendl; +		return; // no valid extension. +	} + +	/* next phase of unit creation is nearly the same as an update cycle. +	   true means the unit's update is running for the first time so it will not check  +	   for current usage nor will it attempt to replace the old, non existent image */ +	mValid = updateSelf(true); +} + +LLLocalBitmap::~LLLocalBitmap() +{ +	// replace IDs with defaults, if set to do so. +	if(LL_LOCAL_REPLACE_ON_DEL) +	{ +		replaceIDs(mWorldID, IMG_DEFAULT); +		LLLocalBitmapMgr::doRebake(); +	} + +	// delete self from gimagelist +	LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID); +	gTextureList.deleteImage(image); + +	if (image) +	{ +		image->unref(); +	} +} + +/* accessors */ +std::string LLLocalBitmap::getFilename() +{ +	return mFilename; +} + +std::string LLLocalBitmap::getShortName() +{ +	return mShortName; +} + +LLUUID LLLocalBitmap::getTrackingID() +{ +	return mTrackingID; +} + +LLUUID LLLocalBitmap::getWorldID() +{ +	return mWorldID; +} + +bool LLLocalBitmap::getValid() +{ +	return mValid; +} + +/* update functions */ +bool LLLocalBitmap::updateSelf(bool first_update) +{ +	bool updated = false; +	 +	if (mLinkStatus == LS_ON) +	{ +		// verifying that the file exists +		if (gDirUtilp->fileExists(mFilename)) +		{ +			// verifying that the file has indeed been modified +			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename)); +			LLSD new_last_modified = asctime(localtime(&temp_time)); + +			if (mLastModified.asString() != new_last_modified.asString()) +			{ +				/* loading the image file and decoding it, here is a critical point which, +				   if fails, invalidates the whole update (or unit creation) process. */ +				LLPointer<LLImageRaw> raw_image = new LLImageRaw(); +				if (decodeBitmap(raw_image)) +				{ +					// decode is successful, we can safely proceed. +					LLUUID old_id = LLUUID::null; +					if (!first_update && !mWorldID.isNull()) +					{ +						old_id = mWorldID; +					} +					mWorldID.generate(); +					mLastModified = new_last_modified; + +					LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture +						("file://"+mFilename, mWorldID, LL_LOCAL_USE_MIPMAPS); + +					texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image); +					texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image); +					texture->ref();  + +					gTextureList.addImage(texture); +			 +					if (!first_update) +					{ +						// seek out everything old_id uses and replace it with mWorldID +						replaceIDs(old_id, mWorldID); + +						// remove old_id from gimagelist +						LLViewerFetchedTexture* image = gTextureList.findImage(old_id); +						gTextureList.deleteImage(image); +						image->unref(); +					} + +					mUpdateRetries = LL_LOCAL_UPDATE_RETRIES; +					updated = true; +				} + +				// if decoding failed, we get here and it will attempt to decode it in the next cycles +				// until mUpdateRetries runs out. this is done because some software lock the bitmap while writing to it +				else +				{ +					if (mUpdateRetries) +					{ +						mUpdateRetries--; +					} +					else +					{ +						llwarns << "During the update process the following file was found" << "\n" +							    << "but could not be opened or decoded for " << LL_LOCAL_UPDATE_RETRIES << " attempts." << "\n" +								<< "Filename: " << mFilename << "\n" +								<< "Disabling further update attempts for this file." << llendl; + +						mLinkStatus = LS_BROKEN; +					} +				}		 +			} +			 +		} // end if file exists + +		else +		{ +			llwarns << "During the update process, the following file was not found." << "\n"  +			        << "Filename: " << mFilename << "\n" +				    << "Disabling further update attempts for this file." << llendl; + +			mLinkStatus = LS_BROKEN; +		} +	} + +	return updated; +} + +bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg) +{ +	bool decode_successful = false; + +	switch (mExtension) +	{ +		case ET_IMG_BMP: +		{ +			LLPointer<LLImageBMP> bmp_image = new LLImageBMP; +			if (bmp_image->load(mFilename) && bmp_image->decode(rawimg, 0.0f)) +			{ +				rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +				decode_successful = true; +			} +			break; +		} + +		case ET_IMG_TGA: +		{ +			LLPointer<LLImageTGA> tga_image = new LLImageTGA; +			if ((tga_image->load(mFilename) && tga_image->decode(rawimg)) +			&& ((tga_image->getComponents() == 3) || (tga_image->getComponents() == 4))) +			{ +				rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +				decode_successful = true; +			} +			break; +		} + +		case ET_IMG_JPG: +		{ +			LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG; +			if (jpeg_image->load(mFilename) && jpeg_image->decode(rawimg, 0.0f)) +			{ +				rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +				decode_successful = true; +			} +			break; +		} + +		case ET_IMG_PNG: +		{ +			LLPointer<LLImagePNG> png_image = new LLImagePNG; +			if (png_image->load(mFilename) && png_image->decode(rawimg, 0.0f)) +			{ +				rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +				decode_successful = true; +			} +			break; +		} + +		default: +		{ +			// separating this into -several- llwarns calls because in the extremely unlikely case that this happens +			// accessing mFilename and any other object properties might very well crash the viewer. +			// getting here should be impossible, or there's been a pretty serious bug. + +			llwarns << "During a decode attempt, the following local bitmap had no properly assigned extension." << llendl; +			llwarns << "Filename: " << mFilename << llendl; +		    llwarns << "Disabling further update attempts for this file." << llendl; +			mLinkStatus = LS_BROKEN; +		} +	} + +	return decode_successful; +} + +void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) +{ +	// checking for misuse. +	if (old_id == new_id) +	{ +		llinfos << "An attempt was made to replace a texture with itself. (matching UUIDs)" << "\n" +			    << "Texture UUID: " << old_id.asString() << llendl; +		return; +	} + +	updateUserPrims(old_id, new_id); +	updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something? +	 +	// default safeguard image for layers +	if( new_id == IMG_DEFAULT ) +	{ +		new_id = IMG_DEFAULT_AVATAR; +	} + +	/* It doesn't actually update all of those, it merely checks if any of them +		contain the referenced ID and if so, updates. */ +	updateUserLayers(old_id, new_id, LLWearableType::WT_ALPHA); +	updateUserLayers(old_id, new_id, LLWearableType::WT_EYES); +	updateUserLayers(old_id, new_id, LLWearableType::WT_GLOVES); +	updateUserLayers(old_id, new_id, LLWearableType::WT_JACKET); +	updateUserLayers(old_id, new_id, LLWearableType::WT_PANTS); +	updateUserLayers(old_id, new_id, LLWearableType::WT_SHIRT); +	updateUserLayers(old_id, new_id, LLWearableType::WT_SHOES); +	updateUserLayers(old_id, new_id, LLWearableType::WT_SKIN); +	updateUserLayers(old_id, new_id, LLWearableType::WT_SKIRT); +	updateUserLayers(old_id, new_id, LLWearableType::WT_SOCKS); +	updateUserLayers(old_id, new_id, LLWearableType::WT_TATTOO); +	updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS); +	updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); +} + +// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects +// in order to prevent multiple sendTEUpdate calls per object during updateUserPrims +std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id) +{ +	std::vector<LLViewerObject*> obj_list; +	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); + +	for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++) +	{ +		// getting an object from a face +		LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator]; + +		if(face_to_object) +		{ +			LLViewerObject* affected_object = face_to_object->getViewerObject(); + +			if(affected_object) +			{ + +				// we have an object, we'll take it's UUID and compare it to +				// whatever we already have in the returnable object list. +				// if there is a match - we do not add (to prevent duplicates) +				LLUUID mainlist_obj_id = affected_object->getID(); +				bool add_object = true; + +				// begin looking for duplicates +				std::vector<LLViewerObject*>::iterator objlist_iter = obj_list.begin(); +				for(; (objlist_iter != obj_list.end()) && add_object; objlist_iter++) +				{ +					LLViewerObject* obj = *objlist_iter; +					if (obj->getID() == mainlist_obj_id) +					{ +						add_object = false; // duplicate found. +					} +				} +				// end looking for duplicates + +				if(add_object) +				{ +					obj_list.push_back(affected_object); +				} + +			} + +		} +		 +	} // end of face-iterating for() + +	return obj_list; +} + +void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id) +{ +	std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id); + +	for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin(); +		object_iterator != objectlist.end(); object_iterator++) +	{ +		LLViewerObject* object = *object_iterator; + +		if(object) +		{ +			bool update_obj = false; +			S32 num_faces = object->getNumFaces(); + +			for (U8 face_iter = 0; face_iter < num_faces; face_iter++) +			{ +				if (object->mDrawable) +				{ +					LLFace* face = object->mDrawable->getFace(face_iter); +					if (face && face->getTexture() && face->getTexture()->getID() == old_id) +					{ +						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture +							(new_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + +						update_obj = true; +					} +				} +			} +			 +			if (update_obj) +			{ +				object->sendTEUpdate(); +			} +		} +	} +	 +} + +void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id) +{ +	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); +	for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++) +	{ +		LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter]; +		LLViewerObject* object = (LLViewerObject*)volume_to_object; +	 +		if(object) +		{ +			if (object->isSculpted() && object->getVolume() && +				object->getVolume()->getParams().getSculptID() == old_id) +			{ +				LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); +				LLSculptParams new_params(*old_params); +				new_params.setSculptTexture(new_id); +				object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE); +			} +		} +	} +} + +void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type) +{ +	U32 count = gAgentWearables.getWearableCount(type); +	for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++) +	{ +		LLWearable* wearable = gAgentWearables.getWearable(type, wearable_iter); +		if (wearable) +		{ +			std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq(); +			for(std::vector<LLLocalTextureObject*>::iterator texture_iter = texture_list.begin(); +				texture_iter != texture_list.end(); texture_iter++) +			{ +				LLLocalTextureObject* lto = *texture_iter; + +				if (lto && lto->getID() == old_id) +				{ +					U32 local_texlayer_index = 0; /* can't keep that as static const, gives errors, so i'm leaving this var here */ +					LLVOAvatarDefines::EBakedTextureIndex baked_texind = +						lto->getTexLayer(local_texlayer_index)->getTexLayerSet()->getBakedTexIndex(); +				 +					LLVOAvatarDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind); +					if (reg_texind != LLVOAvatarDefines::TEX_NUM_INDICES) +					{ +						U32 index = gAgentWearables.getWearableIndex(wearable); +						gAgentAvatarp->setLocalTexture(reg_texind, gTextureList.getImage(new_id), FALSE, index); +						gAgentAvatarp->wearableUpdated(type, FALSE); + +						/* telling the manager to rebake once update cycle is fully done */ +						LLLocalBitmapMgr::setNeedsRebake(); +					} + +				} +			} +		} +	} +} + +LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex( +	LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind) +{ +	LLVOAvatarDefines::ETextureIndex result = LLVOAvatarDefines::TEX_NUM_INDICES; // using as a default/fail return. + +	switch(type) +	{ +		case LLWearableType::WT_ALPHA: +		{ +			switch(baked_texind) +			{ +				case LLVOAvatarDefines::BAKED_EYES: +				{ +					result = LLVOAvatarDefines::TEX_EYES_ALPHA; +					break; +				} + +				case LLVOAvatarDefines::BAKED_HAIR: +				{ +					result = LLVOAvatarDefines::TEX_HAIR_ALPHA; +					break; +				} + +				case LLVOAvatarDefines::BAKED_HEAD: +				{ +					result = LLVOAvatarDefines::TEX_HEAD_ALPHA; +					break; +				} + +				case LLVOAvatarDefines::BAKED_LOWER: +				{ +					result = LLVOAvatarDefines::TEX_LOWER_ALPHA; +					break; +				} +				case LLVOAvatarDefines::BAKED_UPPER: +				{ +					result = LLVOAvatarDefines::TEX_UPPER_ALPHA; +					break; +				} + +				default: +				{ +					break; +				} + +			} +			break; + +		} + +		case LLWearableType::WT_EYES: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_EYES) +			{ +				result = LLVOAvatarDefines::TEX_EYES_IRIS; +			} + +			break; +		} + +		case LLWearableType::WT_GLOVES: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			{ +				result = LLVOAvatarDefines::TEX_UPPER_GLOVES; +			} + +			break; +		} + +		case LLWearableType::WT_JACKET: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			{ +				result = LLVOAvatarDefines::TEX_LOWER_JACKET; +			} +			else if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			{ +				result = LLVOAvatarDefines::TEX_UPPER_JACKET; +			} + +			break; +		} + +		case LLWearableType::WT_PANTS: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			{ +				result = LLVOAvatarDefines::TEX_LOWER_PANTS; +			} + +			break; +		} + +		case LLWearableType::WT_SHIRT: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			{ +				result = LLVOAvatarDefines::TEX_UPPER_SHIRT; +			} + +			break; +		} + +		case LLWearableType::WT_SHOES: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			{ +				result = LLVOAvatarDefines::TEX_LOWER_SHOES; +			} + +			break; +		} + +		case LLWearableType::WT_SKIN: +		{ +			switch(baked_texind) +			{ +				case LLVOAvatarDefines::BAKED_HEAD: +				{ +					result = LLVOAvatarDefines::TEX_HEAD_BODYPAINT; +					break; +				} + +				case LLVOAvatarDefines::BAKED_LOWER: +				{ +					result = LLVOAvatarDefines::TEX_LOWER_BODYPAINT; +					break; +				} +				case LLVOAvatarDefines::BAKED_UPPER: +				{ +					result = LLVOAvatarDefines::TEX_UPPER_BODYPAINT; +					break; +				} + +				default: +				{ +					break; +				} + +			} +			break; +		} + +		case LLWearableType::WT_SKIRT: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_SKIRT) +			{ +				result = LLVOAvatarDefines::TEX_SKIRT; +			} + +			break; +		} + +		case LLWearableType::WT_SOCKS: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			{ +				result = LLVOAvatarDefines::TEX_LOWER_SOCKS; +			} + +			break; +		} + +		case LLWearableType::WT_TATTOO: +		{ +			switch(baked_texind) +			{ +				case LLVOAvatarDefines::BAKED_HEAD: +				{ +					result = LLVOAvatarDefines::TEX_HEAD_TATTOO; +					break; +				} + +				case LLVOAvatarDefines::BAKED_LOWER: +				{ +					result = LLVOAvatarDefines::TEX_LOWER_TATTOO; +					break; +				} +				case LLVOAvatarDefines::BAKED_UPPER: +				{ +					result = LLVOAvatarDefines::TEX_UPPER_TATTOO; +					break; +				} + +				default: +				{ +					break; +				} + +			} +			break; +		} + +		case LLWearableType::WT_UNDERPANTS: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			{ +				result = LLVOAvatarDefines::TEX_LOWER_UNDERPANTS; +			} + +			break; +		} + +		case LLWearableType::WT_UNDERSHIRT: +		{ +			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			{ +				result = LLVOAvatarDefines::TEX_UPPER_UNDERSHIRT; +			} + +			break; +		} + +		default: +		{ +			llwarns << "Unknown wearable type: " << (int)type << "\n" +				    << "Baked Texture Index: " << (int)baked_texind << "\n" +					<< "Filename: " << mFilename << "\n" +					<< "TrackingID: " << mTrackingID << "\n" +					<< "InworldID: " << mWorldID << llendl; +		} + +	} +	return result; +} + +/*=======================================*/ +/*  LLLocalBitmapTimer: timer class      */ +/*=======================================*/  +LLLocalBitmapTimer::LLLocalBitmapTimer() : LLEventTimer(LL_LOCAL_TIMER_HEARTBEAT) +{ +} + +LLLocalBitmapTimer::~LLLocalBitmapTimer() +{ +} + +void LLLocalBitmapTimer::startTimer() +{ +	mEventTimer.start(); +} + +void LLLocalBitmapTimer::stopTimer() +{ +	mEventTimer.stop(); +} + +bool LLLocalBitmapTimer::isRunning() +{ +	return mEventTimer.getStarted(); +} + +BOOL LLLocalBitmapTimer::tick() +{ +	LLLocalBitmapMgr::doUpdates(); +	return FALSE; +} + +/*=======================================*/ +/*  LLLocalBitmapMgr: manager class      */ +/*=======================================*/  +LLLocalBitmapMgr::LLLocalBitmapMgr() +{ +	// The class is all made of static members, should i even bother instantiating? +} + +LLLocalBitmapMgr::~LLLocalBitmapMgr() +{ +} + +bool LLLocalBitmapMgr::addUnit() +{ +	bool add_successful = false; + +	LLFilePicker& picker = LLFilePicker::instance(); +	if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE)) +	{ +		sTimer.stopTimer(); + +		std::string filename = picker.getFirstFile(); +		while(!filename.empty()) +		{ +			LLLocalBitmap* unit = new LLLocalBitmap(filename); + +			if (unit->getValid()) +			{ +				sBitmapList.push_back(unit); +				add_successful = true; +			} +			else +			{ +				delete unit; +				unit = NULL; +			} + +			filename = picker.getNextFile(); +		} +		 +		sTimer.startTimer(); +	} + +	return add_successful; +} + +void LLLocalBitmapMgr::delUnit(LLUUID tracking_id) +{ +	if (!sBitmapList.empty()) +	{	 +		std::vector<LLLocalBitmap*> to_delete; +		for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) +		{   /* finding which ones we want deleted and making a separate list */ +			LLLocalBitmap* unit = *iter; +			if (unit->getTrackingID() == tracking_id) +			{ +				to_delete.push_back(unit); +			} +		} + +		for(std::vector<LLLocalBitmap*>::iterator del_iter = to_delete.begin(); +			del_iter != to_delete.end(); del_iter++) +		{   /* iterating over a temporary list, hence preserving the iterator validity while deleting. */ +			LLLocalBitmap* unit = *del_iter; +			sBitmapList.remove(unit); +			delete unit; +			unit = NULL; +		} +	} +} + +LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id) +{ +	LLUUID world_id = LLUUID::null; + +	for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) +	{ +		LLLocalBitmap* unit = *iter; +		if (unit->getTrackingID() == tracking_id) +		{ +			world_id = unit->getWorldID(); +		} +	} + +	return world_id; +} + +std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id) +{ +	std::string filename = ""; + +	for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) +	{ +		LLLocalBitmap* unit = *iter; +		if (unit->getTrackingID() == tracking_id) +		{ +			filename = unit->getFilename(); +		} +	} + +	return filename; +} + +void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl) +{ +	if (ctrl) +	{ +		ctrl->clearRows(); + +		if (!sBitmapList.empty()) +		{ +			for (local_list_iter iter = sBitmapList.begin(); +				 iter != sBitmapList.end(); iter++) +			{ +				LLSD element; +				element["columns"][0]["column"] = "unit_name"; +				element["columns"][0]["type"]   = "text"; +				element["columns"][0]["value"]  = (*iter)->getShortName(); + +				element["columns"][1]["column"] = "unit_id_HIDDEN"; +				element["columns"][1]["type"]   = "text"; +				element["columns"][1]["value"]  = (*iter)->getTrackingID(); + +				ctrl->addElement(element); +			} +		} +	} + +} + +void LLLocalBitmapMgr::doUpdates() +{ +	// preventing theoretical overlap in cases with huge number of loaded images. +	sTimer.stopTimer(); +	sNeedsRebake = false; + +	for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) +	{ +		(*iter)->updateSelf(); +	} + +	doRebake(); +	sTimer.startTimer(); +} + +void LLLocalBitmapMgr::setNeedsRebake() +{ +	sNeedsRebake = true; +} + +void LLLocalBitmapMgr::doRebake() +{ /* separated that from doUpdates to insure a rebake can be called separately during deletion */ +	if (sNeedsRebake) +	{ +		gAgentAvatarp->forceBakeAllTextures(LL_LOCAL_SLAM_FOR_DEBUG); +		sNeedsRebake = false; +	} +} + diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h new file mode 100644 index 0000000000..c6d05c1763 --- /dev/null +++ b/indra/newview/lllocalbitmaps.h @@ -0,0 +1,130 @@ +/**  + * @file lllocalbitmaps.h + * @author Vaalith Jinn + * @brief Local Bitmaps header + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LOCALBITMAPS_H +#define LL_LOCALBITMAPS_H + +#include "lleventtimer.h" +#include "llwearabletype.h" +#include "llvoavatardefines.h" + +class LLScrollListCtrl; + +class LLLocalBitmap +{ +	public: /* main */ +		LLLocalBitmap(std::string filename); +		~LLLocalBitmap(); +		bool updateSelf(bool first_update = false); + +	public: /* accessors */ +		std::string	getFilename(); +		std::string	getShortName(); +		LLUUID		getTrackingID(); +		LLUUID		getWorldID(); +		bool		getValid(); + +	private: /* maintenance */ +		bool decodeBitmap(LLPointer<LLImageRaw> raw); +		void replaceIDs(LLUUID old_id, LLUUID new_id); + +	private: /* id replacement */ +		std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id); +		void updateUserPrims(LLUUID old_id, LLUUID new_id); +		void updateUserSculpts(LLUUID old_id, LLUUID new_id); +		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type); +		LLVOAvatarDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind); + +	private: /* enums */ +		enum ELinkStatus +		{ +			LS_ON, +			LS_BROKEN, +		}; + +		enum EExtension +		{ +			ET_IMG_BMP, +			ET_IMG_TGA, +			ET_IMG_JPG, +			ET_IMG_PNG +		}; + +	private: /* members */ +		std::string mFilename; +		std::string mShortName; +		LLUUID      mTrackingID; +		LLUUID      mWorldID; +		bool        mValid; +		LLSD        mLastModified; +		EExtension  mExtension; +		ELinkStatus mLinkStatus; +		S32         mUpdateRetries; + +}; + +class LLLocalBitmapTimer : public LLEventTimer +{ +	public: +		LLLocalBitmapTimer(); +		~LLLocalBitmapTimer(); + +	public: +		void startTimer(); +		void stopTimer(); +		bool isRunning(); +		BOOL tick(); + +}; + +class LLLocalBitmapMgr +{ +	public: +		LLLocalBitmapMgr(); +		~LLLocalBitmapMgr(); + +	public: +		static bool         addUnit(); +		static void         delUnit(LLUUID tracking_id); + +		static LLUUID       getWorldID(LLUUID tracking_id); +		static std::string  getFilename(LLUUID tracking_id); +		 +		static void         feedScrollList(LLScrollListCtrl* ctrl); +		static void         doUpdates(); +		static void         setNeedsRebake(); +		static void         doRebake(); +		 +	private: +		static std::list<LLLocalBitmap*>    sBitmapList; +		static LLLocalBitmapTimer           sTimer; +		static bool                         sNeedsRebake; +		typedef std::list<LLLocalBitmap*>::iterator local_list_iter; +}; + +#endif + diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index de22f2ae6b..6a64e6d76a 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -67,6 +67,9 @@  #include "lluictrlfactory.h"  #include "lltrans.h" +#include "llradiogroup.h" +#include "llfloaterreg.h" +#include "lllocalbitmaps.h"  static const S32 HPAD = 4;  static const S32 VPAD = 4; @@ -78,6 +81,8 @@ static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;  static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;  static const F32 CONTEXT_FADE_TIME = 0.08f; +static const S32 LOCAL_TRACKING_ID_COLUMN = 1; +  //static const char CURRENT_IMAGE_NAME[] = "Current Texture";  //static const char WHITE_IMAGE_NAME[] = "Blank Texture";  //static const char NO_IMAGE_NAME[] = "None"; @@ -142,6 +147,12 @@ public:  	static void		onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);  		   void		onTextureSelect( const LLTextureEntry& te ); +	static void		onModeSelect(LLUICtrl* ctrl, void *userdata); +	static void		onBtnAdd(void* userdata); +	static void		onBtnRemove(void* userdata); +	static void		onBtnUpload(void* userdata); +	static void		onLocalScrollCommit(LLUICtrl* ctrl, void* userdata); +  protected:  	LLPointer<LLViewerTexture> mTexturep;  	LLTextureCtrl*		mOwner; @@ -169,8 +180,10 @@ protected:  	BOOL				mNoCopyTextureSelected;  	F32					mContextConeOpacity;  	LLSaveFolderState	mSavedFolderState; -  	BOOL				mSelectedItemPinned; +	 +	LLRadioGroup*		mModeSelector; +	LLScrollListCtrl*	mLocalScrollCtrl;  };  LLFloaterTexturePicker::LLFloaterTexturePicker(	 @@ -437,6 +450,17 @@ BOOL LLFloaterTexturePicker::postBuild()  		mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);  	} +	mModeSelector = getChild<LLRadioGroup>("mode_selection"); +	mModeSelector->setCommitCallback(onModeSelect, this); +	mModeSelector->setSelectedIndex(0, 0); + +	childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this); +	childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this); +	childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this); + +	mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list"); +	mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this); +	LLLocalBitmapMgr::feedScrollList(mLocalScrollCtrl);  	mNoCopyTextureSelected = FALSE; @@ -464,7 +488,6 @@ BOOL LLFloaterTexturePicker::postBuild()  // virtual  void LLFloaterTexturePicker::draw()  { -	S32 floater_header_size = getHeaderHeight();  	if (mOwner)  	{  		// draw cone of context pointing back to texture swatch	 @@ -554,10 +577,7 @@ void LLFloaterTexturePicker::draw()  		}  		// Border -		LLRect border( BORDER_PAD,  -					   getRect().getHeight() - floater_header_size - BORDER_PAD,  -					   ((getMinWidth() / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD, -					   BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - getMinHeight())); +		LLRect border = getChildView("preview_widget")->getRect();  		gl_rect_2d( border, LLColor4::black, FALSE ); @@ -748,7 +768,15 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata)  	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;  	if (self->mOwner)  	{ -		self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT); +		LLUUID local_id = LLUUID::null; + +		if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty()) +		{ +			LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID(); +			local_id = LLLocalBitmapMgr::getWorldID(temp_id); +		} + +		self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT, local_id);  	}  	self->closeFloater();  } @@ -792,6 +820,112 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem  }  // static +void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) +{ +	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +	bool mode = (self->mModeSelector->getSelectedIndex() == 0); + +	self->getChild<LLButton>("Default")->setVisible(mode); +	self->getChild<LLButton>("Blank")->setVisible(mode); +	self->getChild<LLButton>("None")->setVisible(mode); +	self->getChild<LLButton>("Pipette")->setVisible(mode); +	self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode); +	self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode); + +	/*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode); +	  no idea under which conditions the above is even shown, needs testing. */ + +	self->getChild<LLButton>("l_add_btn")->setVisible(!mode); +	self->getChild<LLButton>("l_rem_btn")->setVisible(!mode); +	self->getChild<LLButton>("l_upl_btn")->setVisible(!mode); +	self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(!mode); +} + +// static +void LLFloaterTexturePicker::onBtnAdd(void* userdata) +{ +	if (LLLocalBitmapMgr::addUnit() == true) +	{ +		LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +		LLLocalBitmapMgr::feedScrollList(self->mLocalScrollCtrl); +	} +} + +// static +void LLFloaterTexturePicker::onBtnRemove(void* userdata) +{ +	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +	std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected(); + +	if (!selected_items.empty()) +	{ +		for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin(); +			iter != selected_items.end(); iter++) +		{ +			LLScrollListItem* list_item = *iter; +			if (list_item) +			{ +				LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID(); +				LLLocalBitmapMgr::delUnit(tracking_id); +			} +		} + +		self->getChild<LLButton>("l_rem_btn")->setEnabled(false); +		self->getChild<LLButton>("l_upl_btn")->setEnabled(false); +		LLLocalBitmapMgr::feedScrollList(self->mLocalScrollCtrl); +	} + +} + +// static +void LLFloaterTexturePicker::onBtnUpload(void* userdata) +{ +	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +	std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected(); + +	if (selected_items.empty()) +	{ +		return; +	} + +	/* currently only allows uploading one by one, picks the first item from the selection list.  (not the vector!) +	   in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */ +	 +	LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN); +	std::string filename = LLLocalBitmapMgr::getFilename(tracking_id); + +	if (!filename.empty()) +	{ +		LLFloaterReg::showInstance("upload_image", LLSD(filename)); +	} + +} + +//static +void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) +{ +	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +	std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected(); +	bool has_selection = !selected_items.empty(); + +	self->getChild<LLButton>("l_rem_btn")->setEnabled(has_selection); +	self->getChild<LLButton>("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2)); +	/* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */ + +	if (has_selection) +	{ +		LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);  +		LLUUID inworld_id = LLLocalBitmapMgr::getWorldID(tracking_id); +		self->mOwner->setImageAssetID(inworld_id); + +		if (self->childGetValue("apply_immediate_check").asBoolean()) +		{ +			self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, inworld_id); +		} +	} +} + +// static  void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data)  {  	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; @@ -1126,7 +1260,7 @@ void LLTextureCtrl::onFloaterClose()  	mFloaterHandle.markDead();  } -void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)  {  	LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); @@ -1139,14 +1273,24 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)  		// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.  		else if (mCommitOnSelection || op == TEXTURE_SELECT)  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? -			 -		if( floaterp->isDirty() ) + +		if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.  		{  			setTentative( FALSE ); -			mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE); -			lldebugs << "mImageItemID: " << mImageItemID << llendl; -			mImageAssetID = floaterp->getAssetID(); -			lldebugs << "mImageAssetID: " << mImageAssetID << llendl; + +			if (id.notNull()) +			{ +				mImageItemID = id; +				mImageAssetID = id; +			} +			else +			{ +				mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE); +				lldebugs << "mImageItemID: " << mImageItemID << llendl; +				mImageAssetID = floaterp->getAssetID(); +				lldebugs << "mImageAssetID: " << mImageAssetID << llendl; +			} +  			if (op == TEXTURE_SELECT && mOnSelectCallback)  			{  				mOnSelectCallback( this, LLSD() ); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index b1312d641f..3abe84dcc3 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -157,7 +157,7 @@ public:  	void			closeDependentFloater();  	void			onFloaterClose(); -	void			onFloaterCommit(ETexturePickOp op); +	void			onFloaterCommit(ETexturePickOp op, LLUUID id = LLUUID::null);  	// This call is returned when a drag is detected. Your callback  	// should return TRUE if the drag is acceptable. diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index de305bf3d9..a8060649ba 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -243,8 +243,8 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt  	mBtnCallbackData.push_back(userdata);  	LLButton::Params p; -	bool is_ignore_btn = form_element["index"].asInteger() == -1; -	const LLFontGL* font = is_ignore_btn ? sFontSmall: sFont; // for ignore button in script dialog +	bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2; +	const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog  	p.name(form_element["name"].asString());  	p.label(form_element["text"].asString());  	p.font(font); @@ -264,7 +264,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt  		p.rect.width = 1;  		p.auto_resize = true;  	} -	else if (mIsScriptDialog && is_ignore_btn) +	else if (mIsScriptDialog && make_small_btn)  	{  		// this is ignore button, make it smaller  		p.rect.height = BTN_HEIGHT_SMALL; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 99540ccce9..5087930dba 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6513,31 +6513,37 @@ class LLToolsSelectedScriptAction : public view_listener_t  		std::string action = userdata.asString();  		bool mono = false;  		std::string msg, name; +		std::string title;  		if (action == "compile mono")  		{  			name = "compile_queue";  			mono = true;  			msg = "Recompile"; +			title = LLTrans::getString("CompileQueueTitle");  		}  		if (action == "compile lsl")  		{  			name = "compile_queue";  			msg = "Recompile"; +			title = LLTrans::getString("CompileQueueTitle");  		}  		else if (action == "reset")  		{  			name = "reset_queue";  			msg = "Reset"; +			title = LLTrans::getString("ResetQueueTitle");  		}  		else if (action == "start")  		{  			name = "start_queue";  			msg = "SetRunning"; +			title = LLTrans::getString("RunQueueTitle");  		}  		else if (action == "stop")  		{  			name = "stop_queue";  			msg = "SetRunningNot"; +			title = LLTrans::getString("NotRunQueueTitle");  		}  		LLUUID id; id.generate(); @@ -6546,6 +6552,7 @@ class LLToolsSelectedScriptAction : public view_listener_t  		{  			queue->setMono(mono);  			queue_actions(queue, msg); +			queue->setTitle(title);  		}  		else  		{ diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e0a362596d..b386c73d2a 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -65,6 +65,7 @@ class LLViewerTextureList  	friend class LLTextureView;  	friend class LLViewerTextureManager; +	friend class LLLocalBitmap;  public:  	static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index bc7f5a9744..f46cedfc4b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7533,11 +7533,15 @@ void LLVOAvatar::dumpArchetypeXML( void* )  {  	LLAPRFile outfile;  	outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB ); -	apr_file_t* file = outfile.getFileHandle() ; +	apr_file_t* file = outfile.getFileHandle();  	if (!file)  	{  		return;  	} +	else +	{ +		llinfos << "xmlfile write handle obtained : " << gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml") << llendl; +	}  	apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );  	apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); @@ -7577,6 +7581,11 @@ void LLVOAvatar::dumpArchetypeXML( void* )  	}  	apr_file_printf( file, "\t</archetype>\n" );  	apr_file_printf( file, "\n</linden_genepool>\n" ); +	//explictly close the file if it is still open which it should be +	if (file) +	{ +		outfile.close(); +	}  } diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 0f7f63061b..402504933c 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -810,6 +810,20 @@ const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const  	return NULL;  } +std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq() +{ +	std::vector<LLLocalTextureObject*> result; + +	for(te_map_t::const_iterator iter = mTEMap.begin(); +		iter != mTEMap.end(); iter++) +	{ +		LLLocalTextureObject* lto = iter->second; +		result.push_back(lto); +	} + +	return result; +} +  void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject <o)  {  	if( mTEMap.find(index) != mTEMap.end() ) diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index fd614ade64..3d8c53a755 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -106,6 +106,7 @@ public:  	LLLocalTextureObject* getLocalTextureObject(S32 index);  	const LLLocalTextureObject* getLocalTextureObject(S32 index) const; +	std::vector<LLLocalTextureObject*> getLocalTextureListSeq();  	void				setLocalTextureObject(S32 index, LLLocalTextureObject <o);  	void				addVisualParam(LLVisualParam *param); diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml index 86232de1a4..44d2c14cc8 100644 --- a/indra/newview/skins/default/xui/en/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml @@ -2,7 +2,7 @@  <floater   legacy_header_height="18"   can_minimize="false" - height="440" + height="460"   layout="topleft"   name="Image Preview"   help_topic="image_preview" @@ -108,7 +108,7 @@      <text       type="string"       length="1" -     bottom="225" +     bottom="250"       height="45"       word_wrap="true"       follows="top|left" @@ -137,7 +137,7 @@ Try saving image as 24 bit Targa (.tga).       layout="topleft"       left="165"       name="cancel_btn" -     top="410" +     top="430"       width="125" />      <button       follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index cad7d72ed7..ffb8b842f0 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -3,15 +3,17 @@   legacy_header_height="18"   can_minimize="false"   can_resize="true" - height="290" + height="330"   layout="topleft" - min_height="290" + min_height="330"   min_width="410"   name="texture picker"   help_topic="texture_picker"   title="PICK: TEXTURE"   width="410"> -    <floater.string +  +<!--  top static --> + <floater.string       name="choose_picture">          Click to choose a picture      </floater.string> @@ -19,6 +21,16 @@       name="pick title">          Pick:      </floater.string> + +    <view +     left="4" +     top="20" +     name="preview_widget" +     height="165" +     width="165" +     follows="left|top" +    /> +        <text       type="string"       length="1" @@ -34,70 +46,94 @@       width="163">          Multiple textures      </text> +	 +	<!-- mode selector --> +	   <radio_group +     control_name="mode_selection" +     height="20" +     layout="topleft" +     left="18" +     top_pad="80" +     name="mode_selection" +     follows="left|top"> +        <radio_item +         label="Inventory" +         name="inventory" +         top_delta="20"  +         layout="topleft" +         height="16"  +         left="0"  +         value="0" +         width="80" /> +        <radio_item +         label="Local" +         left_pad="0" +         layout="topleft" +         top_delta="0"  +         height="16"  +         name="local" +         value="1" +         width="75" /> +    </radio_group> +	<!-- --> +	      <text       type="string"       length="1"       follows="left|top"       height="14"       layout="topleft" -     left_delta="0" +     left_delta="-12"       name="unknown" -     top_pad="80" -     width="163"> +     top_pad="4" +     width="">          Size: [DIMENSIONS]      </text> +     +<!--  middle: inventory mode --> +      <button       enabled="false" -     follows="left|bottom" -     height="20" +     follows="left|top" +     height="18"       label="Default"       label_selected="Default"       layout="topleft" -     left_delta="0"       name="Default" -     top_pad="4" -     width="80" /> +     width="73" +	 left="94" +     top="215"/>      <button +     follows="left|top" +     height="20" +     label="Blank" +     label_selected="Blank" +     layout="topleft" +     left_delta="0" +     name="Blank" +     top_pad="5" +     width="73" /> +     <button       enabled="false" -     follows="left|bottom" +     follows="left|top"       height="20"       label="None"       label_selected="None"       layout="topleft" -     left_pad="4" +     left_delta="0"       name="None" -     top_delta="0" -     width="80" /> -    <button -     follows="left|bottom" -     height="20" -     label="Blank" -     label_selected="Blank" -     layout="topleft" -     left="4" -     name="Blank"       top_pad="5" -     width="80" /> -         <button -     follows="left|bottom" +     width="73" /> +    <button +     follows="left|top"       height="28"       image_selected="eye_button_active.tga"       image_unselected="eye_button_inactive.tga"       layout="topleft" -     left_pad="50" -     top_delta="3" +     left_delta="-80" +     top_delta="-25"       name="Pipette"       width="28" /> -   <check_box -     follows="left|bottom" -     height="20" -     initial_value="true" -     label="Apply now" -     layout="topleft" -     left="4" -     name="apply_immediate_check" -     top="262" -     width="120" />      <filter_editor       follows="left|top|right"       height="23" @@ -113,7 +149,7 @@       bg_alpha_color="DkGray2"       border="false"       follows="all" -     height="200" +     height="233"       layout="topleft"       left_delta="0"       name="inventory panel" @@ -128,23 +164,89 @@       top_pad="0"       left_delta="-3"       width="200" /> -         <button -     follows="right|bottom" + +<!--  middle: local mode --> +    <button +     follows="left|top" +     height="18" +     label="Add" +     label_selected="Add" +     layout="topleft" +     left="94" +     top="215" +     name="l_add_btn" +     width="73" +     visible="false"/> +    <button +     enabled="false" +     follows="left|top" +     height="20" +     label="Remove" +     label_selected="Remove" +     layout="topleft" +     left_delta="0" +     name="l_rem_btn" +     top_pad="5" +     width="73" +     visible="false"/> +    <button +     enabled="false" +     follows="left|top" +     height="20" +     label="Upload" +     label_selected="Upload" +     layout="topleft" +     left_delta="0" +     name="l_upl_btn" +     top_pad="5" +     width="73" +     visible="false"/> +    <scroll_list +     name="l_name_list" +     left="170" +     top="22" +     width="235" +     height="260" +     follows="left|top|right|bottom" +     column_padding="0" +     can_resize="false" +     draw_heading="true" +     multi_select="true" +     search_column="1" +     visible="false"> +        <column name="unit_name" label="Name" dynamicwidth="true" /> +        <column name="unit_id_HIDDEN" label="ID" width="0" /> +    </scroll_list> +      +<!-- bottom static --> +    <button +     follows="bottom"       height="20"       label="OK"       label_selected="OK"       layout="topleft" -     right="-120" +     left="95" +     top="-30"       name="Select"       width="100" />      <button -     follows="right|bottom" +     follows="bottom"       height="20"       label="Cancel"       label_selected="Cancel"       layout="topleft" -     right="-10" -     left_pad="5" +     left_delta="120" +     top_delta="0"       name="Cancel"       width="100" /> +    <check_box +     follows="left|bottom" +     height="20" +     initial_value="true" +     label="Apply now" +     layout="topleft" +     left="6" +     name="apply_immediate_check" +     top_delta="0" +     width="120" />  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_window_size.xml b/indra/newview/skins/default/xui/en/floater_window_size.xml index 355d257785..115fe413f3 100644 --- a/indra/newview/skins/default/xui/en/floater_window_size.xml +++ b/indra/newview/skins/default/xui/en/floater_window_size.xml @@ -28,22 +28,50 @@       tool_tip="width x height"       top_pad="5"       width="179"> -        <combo_box.item -         label="1000 x 700 (default)" -         name="item0" -         value="1000 x 700" /> -        <combo_box.item -         label="1024 x 768" -         name="item1" -         value="1024 x 768" /> -        <combo_box.item -         label="1280 x 720 (720p)" -         name="item2" -         value="1280 x 720" /> -        <combo_box.item -         label="1920 x 1080 (1080p)" -         name="item3" -         value="1920 x 1080" /> +      <combo_box.item +       label="1000 x 700 (default)" +       name="item1" +       value="1000 x 700" /> +      <combo_box.item +       label="1024 x 768 (4:3 XGA)" +       name="item2" +       value="1024 x 768" /> +      <combo_box.item +       label="1280 x 720 (16:9 HDTV)" +       name="item3" +       value="1280 x 720" /> +      <combo_box.item +       label="1280 x 800 (5:8 WXGA)" +       name="item4" +       value="1280 x 800" /> +      <combo_box.item +       label="1280 x 1024 (5:4 SXGA)" +       name="item5" +       value="1280 x 1024" /> +      <combo_box.item +       label="1440 x 900 (8:5 WSXGA)" +       name="item7" +       value="1440 x 900" /> +      <combo_box.item +       label="1600 x 900 (16:9 HD+)" +       name="item8" +       value="1600 x 900" /> +      <combo_box.item +       label="1600 x 1200 (4:3 UXGA)" +       name="item9" +       value="1600 x 1200" /> +      <combo_box.item +       label="1680 x 1050 (8:5 WSXGA+)" +       name="item10" +       value="1680 x 1050" /> +      <combo_box.item +       label="1920 x 1080 (16:9 HDTV)" +       name="item11" +       value="1920 x 1080" /> +      <combo_box.item +       label="1920 x 1200 (8:5 WUXGA)" +       name="item12" +       value="1920 x 1200" />      </combo_box>      <button       follows="right|bottom"  | 
