Commits

dessie linden committed 4600208 Merge

Merge from viewer-public

Comments (0)

Files changed (65)

doc/contributions.txt

 	VWR-8885
 	VWR-9256
 	VWR-9966
+Kitty Barnett
+	VWR-19699
 Kunnis Basiat
 	VWR-82
 	VWR-102

indra/llcommon/llstring.h

 	/////////////////////////////////////////////////////////////////////////////////////////
 	// Static Utility functions that operate on std::strings
 
-	static std::basic_string<T> null;
+	static const std::basic_string<T> null;
 	
 	typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
 	LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
 	LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
 };
 
-template<class T> std::basic_string<T> LLStringUtilBase<T>::null;
+template<class T> const std::basic_string<T> LLStringUtilBase<T>::null;
 template<class T> std::string LLStringUtilBase<T>::sLocale;
 
 typedef LLStringUtilBase<char> LLStringUtil;

indra/llmessage/llcurl.cpp

 		responseReason = strerror(code) + " : " + mErrorBuffer;
 	}
 		
+	if(responseCode >= 300 && responseCode < 400) //redirect
+	{
+		char new_url[512] ;
+		curl_easy_getinfo(mCurlEasyHandle, CURLINFO_REDIRECT_URL, new_url);
+		responseReason = new_url ; //get the new URL.
+	}
+
 	if (mResponder)
 	{	
 		mResponder->completedRaw(responseCode, responseReason, mChannels, mOutput);

indra/llui/lltextbase.cpp

 	case LLFontGL::LEFT:
 		return mHPad;
 	case LLFontGL::HCENTER:
-		return mHPad + (mVisibleTextRect.getWidth() - width - mHPad) / 2;
+		return mHPad + llmax(0, (mVisibleTextRect.getWidth() - width - mHPad) / 2);
 	case LLFontGL::RIGHT:
 		return mVisibleTextRect.getWidth() - width;
 	default:
 			// grow line height as necessary based on reported height of this segment
 			line_height = llmax(line_height, segment_height);
 			remaining_pixels -= segment_width;
-			if (remaining_pixels < 0)
-			{
-				// getNumChars() and getDimensions() should return consistent results
-				remaining_pixels = 0;
-			}
 
 			seg_offset += character_count;
 
 {
 	// Figure out which line we're nearest to.
 	LLRect visible_region = getVisibleDocumentRect();
-
+	
 	// binary search for line that starts before local_y
 	line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mVisibleTextRect.mBottom + visible_region.mBottom, compare_bottom());
 
 	}
 	
 	S32 pos = getLength();
-	S32 start_x = mVisibleTextRect.mLeft + line_iter->mRect.mLeft;
+	S32 start_x = mVisibleTextRect.mLeft + line_iter->mRect.mLeft - visible_region.mLeft;
 
 	segment_set_t::iterator line_seg_iter;
 	S32 line_seg_offset;

indra/newview/app_settings/settings.xml

       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>InBandwidth</key>
     <map>

indra/newview/gpu_table.txt

 NVIDIA GeForce 7300				.*NVIDIA.*GeForce 73.*				1		1
 NVIDIA GeForce 7500				.*NVIDIA.*GeForce 75.*				1		1
 NVIDIA GeForce 7600				.*NVIDIA.*GeForce 76.*				1		1
-NVIDIA GeForce 7800				.*NVIDIA.*GeForce.*78.*				1		1
-NVIDIA GeForce 7900				.*NVIDIA.*GeForce.*79.*				1		1
+NVIDIA GeForce 7800				.*NVIDIA.*GeForce 78.*				1		1
+NVIDIA GeForce 7900				.*NVIDIA.*GeForce 79.*				1		1
 NVIDIA GeForce 8100				.*NVIDIA.*GeForce 81.*				1		1
 NVIDIA GeForce 8200				.*NVIDIA.*GeForce 82.*				1		1
 NVIDIA GeForce 8300				.*NVIDIA.*GeForce 83.*				1		1
 NVIDIA G92						.*G92.*								3		1
 NVIDIA G94						.*G94.*								3		1
 NVIDIA GeForce Go 6				.*GeForce Go 6.*					1		1
+NVIDIA ION						.*NVIDIA ION.*						1		1
 NVIDIA NB9M						.*GeForce NB9M.*					1		1
 NVIDIA NB9P						.*GeForce NB9P.*					1		1
 NVIDIA GeForce PCX				.*GeForce PCX.*						0		1

indra/newview/llagentcamera.cpp

 				mAnimationDuration = gSavedSettings.getF32("ZoomTime");
 			}
 		}
-		setFocusGlobal(LLVector3d::zero);
 	}
 	else
 	{

indra/newview/llappearancemgr.cpp

 {
 	if (item_id_to_wear.isNull()) return false;
 
-	//only the item from a user's inventory is allowed
-	if (!gInventory.isObjectDescendentOf(item_id_to_wear, gInventory.getRootFolderID())) return false;
-
 	LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear);
 	if (!item_to_wear) return false;
 
+	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
+	{
+		LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(replace);
+		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);
+		return false;
+	} 
+	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID()))
+	{
+		return false; // not in library and not in agent's inventory
+	}
+	else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH)))
+	{
+		LLNotificationsUtil::add("CannotWearTrash");
+		return false;
+	}
+
 	switch (item_to_wear->getType())
 	{
 	case LLAssetType::AT_CLOTHING:
+		if (gAgentWearables.areWearablesLoaded())
+		{
+			S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType());
+			if ((replace && wearable_count != 0) ||
+				(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
+			{
+				removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false);
+			}
+		} 
 	case LLAssetType::AT_BODYPART:
 		// Don't wear anything until initial wearables are loaded, can
 		// destroy clothing items.
 
 		// Remove the existing wearables of the same type.
 		// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
-		if (replace || item_to_wear->getType() == LLAssetType::AT_BODYPART)
+		if (item_to_wear->getType() == LLAssetType::AT_BODYPART)
 		{
 			removeCOFLinksOfType(item_to_wear->getWearableType(), false);
 		}
 								  item_array,
 								  LLInventoryModel::EXCLUDE_TRASH);
 	bool linked_already = false;
+	U32 count = 0;
 	for (S32 i=0; i<item_array.count(); i++)
 	{
 		// Are these links to the same object?
 		}
 		// Are these links to different items of the same body part
 		// type? If so, new item will replace old.
-		// TODO: MULTI-WEARABLE: check for wearable limit for clothing types
-		else if (is_body_part && (vitem->isWearableType()) && (vitem->getWearableType() == wearable_type))
+		else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type))
 		{
-			if (inv_item->getIsLinkType()  && (vitem->getWearableType() == wearable_type))
+			++count;
+			if (is_body_part && inv_item->getIsLinkType()  && (vitem->getWearableType() == wearable_type))
 			{
 				gInventory.purgeObject(inv_item->getUUID());
 			}
+			else if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE)
+			{
+				// MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE
+				gInventory.purgeObject(inv_item->getUUID());
+			}
 		}
 	}
+
 	if (linked_already)
 	{
 		if (do_update)

indra/newview/llinventorybridge.cpp

 }
 
 // Function declarations
-void wear_add_inventory_item_on_avatar(LLInventoryItem* item);
 void remove_inventory_category_from_avatar(LLInventoryCategory* category);
 void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
 bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
 	mInvType = inv_type;
 }
 
-// *NOTE: hack to get from avatar inventory to avatar
-void wear_inventory_item_on_avatar( LLInventoryItem* item )
-{
-	if(item)
-	{
-		lldebugs << "wear_inventory_item_on_avatar( " << item->getName()
-				 << " )" << llendl;
-
-		LLAppearanceMgr::getInstance()->wearItemOnAvatar(item->getUUID(), true, false);
-	}
-}
-
-void wear_add_inventory_item_on_avatar( LLInventoryItem* item )
-{
-	if(item)
-	{
-		lldebugs << "wear_add_inventory_item_on_avatar( " << item->getName()
-				 << " )" << llendl;
-
-		LLWearableList::instance().getAsset(item->getAssetUUID(),
-											item->getName(),
-											item->getType(),
-											LLWearableBridge::onWearAddOnAvatarArrived,
-											new LLUUID(item->getUUID()));
-	}
-}
-
 void remove_inventory_category_from_avatar( LLInventoryCategory* category )
 {
 	if(!category) return;
 	LLViewerInventoryItem* item = getItem();
 	if(item)
 	{
-		if(!isAgentInventory())
-		{
-			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
-			copy_inventory_item(
-				gAgent.getID(),
-				item->getPermissions().getOwner(),
-				item->getUUID(),
-				LLUUID::null,
-				std::string(),
-				cb);
-		}
-		else
-		{
-			wear_inventory_item_on_avatar(item);
-		}
+		LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true);
 	}
 }
 
 	LLViewerInventoryItem* item = getItem();
 	if(item)
 	{
-		if(!isAgentInventory())
-		{
-			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
-			copy_inventory_item(
-				gAgent.getID(),
-				item->getPermissions().getOwner(),
-				item->getUUID(),
-				LLUUID::null,
-				std::string(),
-				cb);
-		}
-		else
-		{
-			wear_add_inventory_item_on_avatar(item);
-		}
+		LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, false);
 	}
 }
 
 public:
 	virtual void doIt()
 	{
-		if(isItemInTrash())
-		{
-			LLNotificationsUtil::add("CannotWearTrash");
-		}
-		else if(isAgentInventory())
-		{
-			if(!get_is_item_worn(mUUID))
-			{
-				wearOnAvatar();
-			}
-		}
-		else
-		{
-			// must be in the inventory library. copy it to our inventory
-			// and put it on right away.
-			LLViewerInventoryItem* item = getItem();
-			if(item && item->isFinished())
-			{
-				LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
-				copy_inventory_item(
-					gAgent.getID(),
-					item->getPermissions().getOwner(),
-					item->getUUID(),
-					LLUUID::null,
-					std::string(),
-					cb);
-			}
-			else if(item)
-			{
-				// *TODO: We should fetch the item details, and then do
-				// the operation above.
-				LLNotificationsUtil::add("CannotWearInfoNotComplete");
-			}
-		}
-		LLInvFVBridgeAction::doIt();
+		wearOnAvatar();
 	}
 	virtual ~LLWearableBridgeAction(){}
 protected:
 	LLViewerInventoryItem* item = getItem();
 	if(item)
 	{
-		if(!isAgentInventory())
-		{
-			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
-			copy_inventory_item(
-				gAgent.getID(),
-				item->getPermissions().getOwner(),
-				item->getUUID(),
-				LLUUID::null,
-				std::string(),
-				cb);
-		}
-		else
-		{
-			wear_inventory_item_on_avatar(item);
-		}
+		LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true);
 	}
 }
 

indra/newview/llinventorybridge.h

 		U32 flags = 0x00) const;
 };
 
-void wear_inventory_item_on_avatar(LLInventoryItem* item);
-
 void rez_attachment(LLViewerInventoryItem* item, 
 					LLViewerJointAttachment* attachment);
 

indra/newview/llinventorymodel.cpp

 
 #include "llagent.h"
 #include "llagentwearables.h"
+#include "llappearancemgr.h"
 #include "llinventorypanel.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 		{
 			LLViewerInventoryItem* wearable_item;
 			wearable_item = gInventory.getItem(wearable_ids[i]);
-			wear_inventory_item_on_avatar(wearable_item);
+			LLAppearanceMgr::instance().wearItemOnAvatar(wearable_item->getUUID(), true, true);
 		}
 	}
 

indra/newview/llnamelistctrl.cpp

 
 // public
 void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
-								 BOOL enabled, std::string& suffix)
+								 BOOL enabled, const std::string& suffix)
 {
 	//llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl;
 
 LLScrollListItem* LLNameListCtrl::addNameItemRow(
 	const LLNameListCtrl::NameItem& name_item,
 	EAddPosition pos,
-	std::string& suffix)
+	const std::string& suffix)
 {
 	LLUUID id = name_item.value().asUUID();
 	LLNameListItem* item = NULL;

indra/newview/llnamelistctrl.h

 	// Add a user to the list by name.  It will be added, the name 
 	// requested from the cache, and updated as necessary.
 	void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
-					 BOOL enabled = TRUE, std::string& suffix = LLStringUtil::null);
+					 BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null);
 	void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
 
 	/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
-	LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, std::string& suffix = LLStringUtil::null);
+	LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null);
 
 	// Add a user to the list by name.  It will be added, the name 
 	// requested from the cache, and updated as necessary.

indra/newview/llpaneleditwearable.cpp

 #include "llagentwearables.h"
 #include "llscrollingpanelparam.h"
 #include "llradiogroup.h"
+#include "llnotificationsutil.h"
 
 #include "llcolorswatch.h"
 #include "lltexturectrl.h"
 	mDescTitle = getChild<LLTextBox>("description_text");
 
 	getChild<LLRadioGroup>("sex_radio")->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange, this));
+	getChild<LLButton>("save_as_button")->setCommitCallback(boost::bind(&LLPanelEditWearable::onSaveAsButtonClicked, this));
 
 	// The following panels will be shown/hidden based on what wearable we're editing
 	// body parts
 	panel->revertChanges();
 }
 
+void LLPanelEditWearable::onSaveAsButtonClicked()
+{
+	LLSD args;
+	args["DESC"] = mTextEditor->getText();
+
+	LLNotificationsUtil::add("SaveWearableAs", args, LLSD(), boost::bind(&LLPanelEditWearable::saveAsCallback, this, _1, _2));
+}
+
+void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (0 == option)
+	{
+		std::string wearable_name = response["message"].asString();
+		LLStringUtil::trim(wearable_name);
+		if( !wearable_name.empty() )
+		{
+			mTextEditor->setText(wearable_name);
+			saveChanges();
+		}
+	}
+}
 
 void LLPanelEditWearable::onCommitSexChange()
 {
 			// storage for ordered list of visual params
 			value_map_t sorted_params;
 			getSortedParams(sorted_params, edit_group);
-	
-			buildParamList(panel_list, sorted_params, tab);
+
+			LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint );
+			if (!jointp)
+			{
+				jointp = gAgentAvatarp->getJoint("mHead");
+			}
+
+			buildParamList(panel_list, sorted_params, tab, jointp);
 	
 			updateScrollingPanelUI();
 		}
 	}
 }
 
-void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params, LLAccordionCtrlTab *tab)
+void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params, LLAccordionCtrlTab *tab, LLJoint* jointp)
 {
 	// sorted_params is sorted according to magnitude of effect from
 	// least to greatest.  Adding to the front of the child list
 		{
 			LLPanel::Params p;
 			p.name("LLScrollingPanelParam");
-			LLScrollingPanelParam* panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable());
+			LLScrollingPanelParam* panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable(), jointp);
 			height = panel_list->addPanel( panel_param );
 		}
 	}

indra/newview/llpaneleditwearable.h

 class LLVisualParamHint;
 class LLViewerJointMesh;
 class LLAccordionCtrlTab;
+class LLJoint;
 
 class LLPanelEditWearable : public LLPanel
 {
 
 	static void			onRevertButtonClicked(void* userdata);
 	void				onCommitSexChange();
+	void				onSaveAsButtonClicked();
+	void				saveAsCallback(const LLSD& notification, const LLSD& response);
 
 
 private:
 	void				updateScrollingPanelUI();
 	LLPanel*			getPanel(LLWearableType::EType type);
 	void				getSortedParams(value_map_t &sorted_params, const std::string &edit_group);
-	void				buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params, LLAccordionCtrlTab *tab);
+	void				buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params, LLAccordionCtrlTab *tab, LLJoint* jointp);
 	// update bottom bar buttons ("Save", "Revert", etc)
 	void				updateVerbs();
 

indra/newview/llscrollingpanelparam.cpp

 S32 LLScrollingPanelParam::sUpdateDelayFrames = 0;
 
 LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_params,
-											  LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable )
+											  LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable, LLJoint* jointp )
 	: LLScrollingPanel( panel_params ),
 	  mParam(param),
 	  mAllowModify(allow_modify),
 	F32 min_weight = param->getMinWeight();
 	F32 max_weight = param->getMaxWeight();
 
-	mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable,  min_weight);
+	mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable,  min_weight, jointp);
 	pos_x = getChild<LLViewBorder>("right_border")->getRect().mLeft + left_border->getBorderWidth();
-	mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable, max_weight );
+	mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable, max_weight, jointp );
 	
 	mHintMin->setAllowsUpdates( FALSE );
 	mHintMax->setAllowsUpdates( FALSE );

indra/newview/llscrollingpanelparam.h

 class LLWearable;
 class LLVisualParamHint;
 class LLViewerVisualParam;
+class LLJoint;
 
 class LLScrollingPanelParam : public LLScrollingPanel
 {
 public:
 	LLScrollingPanelParam( const LLPanel::Params& panel_params,
-						   LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable );
+						   LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable, LLJoint* jointp );
 	virtual ~LLScrollingPanelParam();
 
 	virtual void		draw();

indra/newview/llsidepanelappearance.cpp

 	{
 		if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible()))
 		{
-			if (!gAgentCamera.cameraCustomizeAvatar())
+			if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))
 			{
 				gAgentCamera.changeCameraToCustomizeAvatar();
 			}
 	}
 	else
 	{
-		if (gAgentCamera.cameraCustomizeAvatar())
+		if (gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))
 		{
 			gAgentCamera.changeCameraToDefault();
+			gAgentCamera.resetView();
 		}
 	}
 }
 	else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
 	{
 		gAgentCamera.changeCameraToDefault();
+		gAgentCamera.resetView();
 	}
 }
 
 		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
 		{
 			gAgentCamera.changeCameraToDefault();
+			gAgentCamera.resetView();
 		}
 	}
 }

indra/newview/llstatusbar.cpp

 {
 	std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance );
 
-	LLButton* btn_buy_currency = getChild<LLButton>("buycurrency");
+	LLTextBox* balance_box = getChild<LLTextBox>("balance");
 	LLStringUtil::format_map_t string_args;
 	string_args["[AMT]"] = llformat("%s", money_str.c_str());
 	std::string label_str = getString("buycurrencylabel", string_args);
-	btn_buy_currency->setLabel(label_str);
+	balance_box->setValue(label_str);
 
-	// Resize the balance button so that the label fits it, and the button expands to the left.
-	// *TODO: LLButton should have an option where to expand.
+	// Resize the L$ balance background to be wide enough for your balance plus the buy button
 	{
-		S32 saved_right = btn_buy_currency->getRect().mRight;
-		btn_buy_currency->autoResize();
-		btn_buy_currency->translate(saved_right - btn_buy_currency->getRect().mRight, 0);
+		const S32 HPAD = 24;
+		LLRect balance_rect = balance_box->getTextBoundingRect();
+		LLRect buy_rect = getChildView("buyL")->getRect();
+		LLView* balance_bg_view = getChildView("balance_bg");
+		LLRect balance_bg_rect = balance_bg_view->getRect();
+		balance_bg_rect.mLeft = balance_bg_rect.mRight - (buy_rect.getWidth() + balance_rect.getWidth() + HPAD);
+		balance_bg_view->setShape(balance_bg_rect);
 	}
 
 	if (mBalance && (fabs((F32)(mBalance - balance)) > gSavedSettings.getF32("UISndMoneyChangeThreshold")))

indra/newview/lltexlayer.cpp

 
 void LLTexLayerSetBuffer::requestUpdate()
 {
+	conditionalRestartUploadTimer();
 	mNeedsUpdate = TRUE;
 	// If we're in the middle of uploading a baked texture, we don't care about it any more.
 	// When it's downloaded, ignore it.
 
 void LLTexLayerSetBuffer::requestUpload()
 {
+	conditionalRestartUploadTimer();
+	mNeedsUpload = TRUE;
+	mNumLowresUploads = 0;
+	mUploadPending = TRUE;
+}
+
+void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
+{
 	// If we requested a new upload but haven't even uploaded
 	// a low res version of our last upload request, then
 	// keep the timer ticking instead of resetting it.
 	if (mNeedsUpload && (mNumLowresUploads == 0))
 	{
+		mNeedsUploadTimer.unpause();
+	}
+	else
+	{
 		mNeedsUploadTimer.reset();
+		mNeedsUploadTimer.start();
 	}
-	mNeedsUpload = TRUE;
-	mNumLowresUploads = 0;
-	mUploadPending = TRUE;
-	mNeedsUploadTimer.unpause();
 }
 
 void LLTexLayerSetBuffer::cancelUpload()
 	return success;
 }
 
-bool LLTexLayerSetBuffer::isInitialized(void) const
+BOOL LLTexLayerSetBuffer::isInitialized(void) const
 {
 	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
 }
 
+BOOL LLTexLayerSetBuffer::uploadPending() const
+{
+	return mUploadPending;
+}
+
+BOOL LLTexLayerSetBuffer::uploadNeeded() const
+{
+	return mNeedsUpload;
+}
+
+BOOL LLTexLayerSetBuffer::uploadInProgress() const
+{
+	return !mUploadID.isNull();
+}
+
 BOOL LLTexLayerSetBuffer::isReadyToUpload() const
 {
 	if (!mNeedsUpload) return FALSE; // Don't need to upload if we haven't requested one.
 
 void LLTexLayerSetBuffer::readBackAndUpload()
 {
-	// pointers for storing data to upload
+	llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
+
+	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
+	// until this image is sent to the server and the Avatar Appearance message is received.)
+	mTexLayerSet->deleteCaches();
+
+	// Get the COLOR information from our texture
 	U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
-	
 	glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
 	stop_glerror();
 
-	llinfos << "Baked " << mTexLayerSet->getBodyRegionName() << llendl;
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
-
-	// We won't need our caches since we're baked now.  (Techically, we won't 
-	// really be baked until this image is sent to the server and the Avatar
-	// Appearance message is received.)
-	mTexLayerSet->deleteCaches();
-
+	// Get the MASK information from our texture
 	LLGLSUIDefault gls_ui;
-
 	LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
 	U8* baked_mask_data = baked_mask_image->getData(); 
-	
 	mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
 
-	// writes into baked_color_data
-	const char* comment_text = NULL;
 
-	S32 baked_image_components = 5; // red green blue [bump] clothing
+	// Create the baked image from our color and mask information
+	const S32 baked_image_components = 5; // red green blue [bump] clothing
 	LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
 	U8* baked_image_data = baked_image->getData();
-	
-	comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask
-
 	S32 i = 0;
-	for( S32 u = 0; u < mFullWidth; u++ )
+	for (S32 u=0; u < mFullWidth; u++)
 	{
-		for( S32 v = 0; v < mFullHeight; v++ )
+		for (S32 v=0; v < mFullHeight; v++)
 		{
 			baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
 			baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
 	
 	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
 	compressedImage->setRate(0.f);
-	LLTransactionID tid;
-	LLAssetID asset_id;
-	tid.generate();
-	asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
-	BOOL res = false;
-	if( compressedImage->encode(baked_image, comment_text))
+	const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
+	if (compressedImage->encode(baked_image, comment_text))
 	{
-		res = LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
-								 gVFS, asset_id, LLAssetType::AT_TEXTURE);
-		if (res)
+		LLTransactionID tid;
+		tid.generate();
+		const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+		if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
+							   gVFS, asset_id, LLAssetType::AT_TEXTURE))
 		{
+			// Read back the file and validate.
+			BOOL valid = FALSE;
 			LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
-			BOOL valid = FALSE;
-			S32 file_size;
+			S32 file_size = 0;
 			U8* data = LLVFile::readFile(gVFS, asset_id, LLAssetType::AT_TEXTURE, &file_size);
 			if (data)
 			{
 				integrity_test->setLastError("Unable to read entire file");
 			}
 			
-			if( valid )
+			if (valid)
 			{
-				// baked_upload_data is owned by the responder and deleted after the request completes
+				// Baked_upload_data is owned by the responder and deleted after the request completes.
 				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
 																			 this->mTexLayerSet, 
 																			 asset_id);
 				mUploadID = asset_id;
-				const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();	
 
-				// upload the image
-				std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
-
+				// Upload the image
+				const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
 				if(!url.empty()
-					&& !LLPipeline::sForceOldBakedUpload) // Toggle the debug setting UploadBakedTexOld to change between the new caps method and old method
+					&& !LLPipeline::sForceOldBakedUpload) // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
 				{
+					LLSD body = LLSD::emptyMap();
+					// The responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
+					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
 					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
-
-					LLSD body = LLSD::emptyMap();
-					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
-					// Responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
 				} 
 				else
 				{
-					llinfos << "Baked texture upload via Asset Store." <<  llendl;
-					// gAssetStorage->storeAssetData(mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)this, FALSE);
 					gAssetStorage->storeAssetData(tid,
 												  LLAssetType::AT_TEXTURE,
 												  LLTexLayerSetBuffer::onTextureUploadComplete,
 												  TRUE,		// temp_file
 												  TRUE,		// is_priority
 												  TRUE);	// store_local
+					llinfos << "Baked texture upload via Asset Store." <<  llendl;
 				}
 
+				const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();	
+				if (highest_lod)
+				{
+					// Sending the final LOD for the baked texture.  All done, pause 
+					// the upload timer so we know how long it took.
+					mNeedsUpload = FALSE;
+					mNeedsUploadTimer.pause();
+				}
+				else
+				{
+					// Sending a lower level LOD for the baked texture.  Restart the upload timer.
+					mNumLowresUploads++;
+					mNeedsUploadTimer.unpause();
+					mNeedsUploadTimer.reset();
+				}
+
+				// Print out notification that we uploaded this texture.
 				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
 				{
 					std::string lod_str = highest_lod ? "HighRes" : "LowRes";
 					LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args);
 					llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;
 				}
-
-				if (highest_lod)
-				{
-					// Sending the final LOD for the baked texture.
-					// All done, pause the upload timer so we know how long it took.
-					mNeedsUpload = FALSE;
-					mNeedsUploadTimer.pause();
-				}
-				else
-				{
-					// Sending a lower level LOD for the baked texture.
-					// Restart the upload timer.
-					mNumLowresUploads++;
-					mNeedsUploadTimer.unpause();
-					mNeedsUploadTimer.reset();
-				}
 			}
 			else
 			{
+				// The read back and validate operation failed.  Remove the uploaded file.
 				mUploadPending = FALSE;
-				llinfos << "unable to create baked upload file: corrupted" << llendl;
 				LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
 				file.remove();
+				llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
 			}
 		}
 	}
-	if (!res)
+	else
 	{
+		// The VFS write file operation failed.
 		mUploadPending = FALSE;
-		llinfos << "unable to create baked upload file" << llendl;
+		llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
 	}
 
 	delete [] baked_color_data;
 	const BOOL is_high_res = !mNeedsUpload;
 	const U32 num_low_res = mNumLowresUploads;
 	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
-	const BOOL is_uploaded = !mUploadPending;
 	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
-	std::string text = llformat("[ HiRes:%d LoRes:%d Uploaded:%d ] [ Timer:%d ] %s",
-								is_high_res, num_low_res, is_uploaded,
+
+	std::string status 				= "CREATING ";
+	if (!uploadNeeded()) status 	= "DONE     ";
+	if (uploadInProgress()) status 	= "UPLOADING";
+
+	std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
+								status.c_str(),
+								is_high_res, num_low_res,
 								upload_time, 
 								local_texture_info.c_str());
 	return text;

indra/newview/lltexlayer.h

 	virtual void			postRender(BOOL success);
 	virtual BOOL			render();
 	BOOL					updateImmediate();
-	bool					isInitialized(void) const;
+
+	BOOL					isInitialized(void) const;
+	BOOL					uploadPending() const; // We are expecting a new texture to be uploaded at some point
+	BOOL					uploadNeeded() const; // We need to upload a new texture
+	BOOL					uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
+
 	/*virtual*/ BOOL		needsRender();
 	void					requestUpdate();
 	void					requestUpload();
 	void					cancelUpload();
-	BOOL					uploadPending() const { return mUploadPending; }
 	BOOL					render(S32 x, S32 y, S32 width, S32 height);
 	void					readBackAndUpload();
 	static void				onTextureUploadComplete(const LLUUID& uuid,
 	const std::string		dumpTextureInfo() const;
 	virtual void 			restoreGLTexture();
 	virtual void 			destroyGLTexture();
+
+
 protected:
 	void					pushProjection() const;
 	void					popProjection() const;
 	BOOL					isReadyToUpload() const;
+	void					conditionalRestartUploadTimer();
+	
 private:
 	LLTexLayerSet* const    mTexLayerSet;
 	BOOL					mNeedsUpdate; // whether we need to update our baked textures
 	BOOL					mNeedsUpload; // whether we need to send our baked textures to the server
-	U32						mNumLowresUploads; // mumber of times we've sent a lowres version of our baked textures to the server
+	U32						mNumLowresUploads; // number of times we've sent a lowres version of our baked textures to the server
 	BOOL					mUploadPending; // whether we have received back the new baked textures
 	LLUUID					mUploadID; // the current upload process (null if none).  Used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
 	static S32				sGLByteCount;

indra/newview/lltexturefetch.cpp

 					partial = true;
 				}
 			}
-			else
-			{
-				worker->setGetStatus(status, reason);
-// 				llwarns << status << ": " << reason << llendl;
-			}
+
 			if (!success)
 			{
 				worker->setGetStatus(status, reason);
 
 			if (region)
 			{
-				std::string http_url = region->getCapability("GetTexture");
+				std::string http_url = region->getHttpUrl() ;
 				if (!http_url.empty())
 				{
 					mUrl = http_url + "/?texture_id=" + mID.asString().c_str();
 					mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
 				}
+				else
+				{
+					mCanUseHTTP = false ;
+				}
 			}
 			else
 			{
 				// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
 				//llwarns << "Region not found for host: " << mHost << llendl;
+				mCanUseHTTP = false;
 			}
 		}
 		if (mCanUseHTTP && !mUrl.empty())
 				if (mGetStatus == HTTP_NOT_FOUND)
 				{
 					mHTTPFailCount = max_attempts = 1; // Don't retry
-					//llwarns << "Texture missing from server (404): " << mUrl << llendl;
+					llwarns << "Texture missing from server (404): " << mUrl << llendl;
 
 					//roll back to try UDP
 					if(mCanUseNET)
 					max_attempts = mHTTPFailCount+1; // Keep retrying
 					LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
 				}
+				else if(mGetStatus >= HTTP_MULTIPLE_CHOICES && mGetStatus < HTTP_BAD_REQUEST) //http re-direct
+				{
+					++mHTTPFailCount;
+					max_attempts = 5 ; //try at most 5 times to avoid infinite redirection loop.
+
+					llwarns << "HTTP GET failed because of redirection: "  << mUrl
+							<< " Status: " << mGetStatus << " Reason: '" << mGetReason << llendl ;
+
+					//assign to the new url
+					mUrl = mGetReason ;
+				}
 				else
 				{
 					const S32 HTTP_MAX_RETRY_COUNT = 3;
 							<< " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"
 							<< " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl;
 				}
+
 				if (mHTTPFailCount >= max_attempts)
 				{
 					if (cur_size > 0)

indra/newview/lltextureview.cpp

 
 	const S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
 	const S32 v_offset = 0;
+	const S32 l_offset = 3;
 
 	//----------------------------------------------------------------------------
 	LLGLSUIDefault gls_ui;
-	LLColor4 text_color(1.f, 1.f, 1.f, 1.f);
 	LLColor4 color;
 	
 	U32 line_num = 1;
 		if (!layerset) continue;
 		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
 		if (!layerset_buffer) continue;
+
+		LLColor4 text_color = LLColor4::white;
+		
+		if (layerset_buffer->uploadNeeded())
+		{
+			text_color = LLColor4::red;
+		}
+ 		if (layerset_buffer->uploadInProgress())
+		{
+			text_color = LLColor4::magenta;
+		}
 		std::string text = layerset_buffer->dumpTextureInfo();
-		LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*line_num,
+		LLFontGL::getFontMonospace()->renderUTF8(text, 0, l_offset, v_offset + line_height*line_num,
 												 text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
 		line_num++;
 	}
 	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout");
 	const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
 	
+	LLColor4 header_color(1.f, 1.f, 1.f, 0.9f);
+
 	const std::string texture_timeout_str = texture_timeout ? llformat("%d",texture_timeout) : "Disabled";
 	const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled";
 	std::string header_text = llformat("[ Timeout('AvatarBakedTextureTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());
-	LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, 0, v_offset + line_height*line_num,
-											 text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
+	LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, l_offset, v_offset + line_height*line_num,
+											 header_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
+	line_num++;
+	std::string section_text = "Avatar Textures Information:";
+	LLFontGL::getFontMonospace()->renderUTF8(section_text, 0, 0, v_offset + line_height*line_num,
+											 header_color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
 }
 
 BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask)
 LLRect LLAvatarTexBar::getRequiredRect()
 {
 	LLRect rect;
-	rect.mTop = 85;
+	rect.mTop = 100;
 	if (!gSavedSettings.getBOOL("DebugAvatarRezTime")) rect.mTop = 0;
 	return rect;
 }

indra/newview/lltooldraganddrop.cpp

 				LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
 				return ACCEPT_NO;
 			}
-
-			if (mSource == SOURCE_LIBRARY)
-			{
-				// create item based on that one, and put it on if that
-				// was a success.
-				LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
-				copy_inventory_item(
-					gAgent.getID(),
-					item->getPermissions().getOwner(),
-					item->getUUID(),
-					LLUUID::null,
-					std::string(),
-					cb);
-			}
-			else
-			{
-				wear_inventory_item_on_avatar( item );
-			}
+			LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL));
 		}
 		return ACCEPT_YES_MULTI;
 	}

indra/newview/lltoolmorph.cpp

 	LLViewerJointMesh *mesh, 
 	LLViewerVisualParam *param,
 	LLWearable *wearable,
-	F32 param_weight)
+	F32 param_weight,
+	LLJoint* jointp)
 	:
 	LLViewerDynamicTexture(width, height, 3, LLViewerDynamicTexture::ORDER_MIDDLE, TRUE ),
 	mNeedsUpdate( TRUE ),
 	mAllowsUpdates( TRUE ),
 	mDelayFrames( 0 ),
 	mRect( pos_x, pos_y + height, pos_x + width, pos_y ),
-	mLastParamWeight(0.f)
+	mLastParamWeight(0.f),
+	mCamTargetJoint(jointp)
 {
 	LLVisualParamHint::sInstances.insert( this );
 	mBackgroundp = LLUI::getUIImage("avatar_thumb_bkgrnd.j2c");
 
-
 	llassert(width != 0);
 	llassert(height != 0);
 }
 	mNeedsUpdate = FALSE;
 	mIsVisible = TRUE;
 
-	LLViewerJointMesh* cam_target_joint = NULL;
-	const std::string& cam_target_mesh_name = mVisualParam->getCameraTargetName();
-	if( !cam_target_mesh_name.empty() )
-	{
-		cam_target_joint = (LLViewerJointMesh*)gAgentAvatarp->getJoint( cam_target_mesh_name );
-	}
-	if( !cam_target_joint )
-	{
-		cam_target_joint = (LLViewerJointMesh*)gMorphView->getCameraTargetJoint();
-	}
-	if( !cam_target_joint )
-	{
-		cam_target_joint = (LLViewerJointMesh*)gAgentAvatarp->getJoint("mHead");
-	}
-
 	LLQuaternion avatar_rotation;
 	LLJoint* root_joint = gAgentAvatarp->getRootJoint();
 	if( root_joint )
 		avatar_rotation = root_joint->getWorldRotation();
 	}
 
-	LLVector3 target_joint_pos = cam_target_joint->getWorldPosition();
+	LLVector3 target_joint_pos = mCamTargetJoint->getWorldPosition();
 
 	LLVector3 target_offset( 0, 0, mVisualParam->getCameraElevation() );
 	LLVector3 target_pos = target_joint_pos + (target_offset * avatar_rotation);
 	
 	LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight);
 	LLViewerCamera::getInstance()->setOriginAndLookAt(
-		camera_pos,		// camera
-		LLVector3(0.f, 0.f, 1.f),						// up
-		target_pos );	// point of interest
+		camera_pos,			// camera
+		LLVector3::z_axis,	// up
+		target_pos );		// point of interest
 
 	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
 

indra/newview/lltoolmorph.h

 class LLViewerJointMesh;
 class LLPolyMesh;
 class LLViewerObject;
+class LLJoint;
 
 //-----------------------------------------------------------------------------
 // LLVisualParamHint
 		LLViewerJointMesh *mesh, 
 		LLViewerVisualParam *param,
 		LLWearable *wearable,
-		F32 param_weight);	
+		F32 param_weight, 
+		LLJoint* jointp);	
 
 	/*virtual*/ S8 getType() const ;
 
 	S32						mDelayFrames;		// updates are blocked for this many frames
 	LLRect					mRect;
 	F32						mLastParamWeight;
+	LLJoint*				mCamTargetJoint;	// joint to target with preview camera
 
 	LLUIImagePtr mBackgroundp;
 

indra/newview/llviewerinventory.cpp

 	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
 	if (item)
 	{
-		wear_inventory_item_on_avatar(item);
+		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace);
 	}
 }
 

indra/newview/llviewerinventory.h

 
 class WearOnAvatarCallback : public LLInventoryCallback
 {
+public:
+	WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {}
+	
 	void fire(const LLUUID& inv_item);
+
+protected:
+	bool mReplace;
 };
 
 class ModifiedCOFCallback : public LLInventoryCallback

indra/newview/llviewermenu.cpp

 		else
 		{
 			LLWearableType::EType type = LLWearableType::typeNameToType(clothing);
-			if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT)
+			if (type >= LLWearableType::WT_SHAPE 
+				&& type < LLWearableType::WT_COUNT
+				&& (gAgentWearables.getWearableCount(type) > 0))
 			{
-				// MULTI-WEARABLES
-				LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,0));
+				// MULTI-WEARABLES: assuming user wanted to remove top shirt.
+				U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
+				LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index));
 				LLWearableBridge::removeItemFromAvatar(item);
 			}
 				

indra/newview/llviewerregion.cpp

 	mColoName("unknown"),
 	mProductSKU("unknown"),
 	mProductName("unknown"),
+	mHttpUrl(""),
 	mCacheLoaded(FALSE),
 	mCacheEntriesCount(0),
 	mCacheID(),
 	else
 	{
 		mCapabilities[name] = url;
+		if(name == "GetTexture")
+		{
+			mHttpUrl = url ;
+		}
 	}
 }
 

indra/newview/llviewerregion.h

 	friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region);
     /// implements LLCapabilityProvider
     virtual std::string getDescription() const;
+	std::string getHttpUrl() const { return mHttpUrl ;}
 
 	LLSpatialPartition* getSpatialPartition(U32 type);
 public:
 	std::string mColoName;
 	std::string mProductSKU;
 	std::string mProductName;
+	std::string mHttpUrl ;
 	
 	
 	// Maps local ids to cache entries.

indra/newview/llviewertexture.cpp

 //virtual
 void LLViewerFetchedTexture::processTextureStats()
 {
-	if(mFullyLoaded)//already loaded
+	if(mFullyLoaded)
 	{
+		if(mDesiredDiscardLevel <= mMinDesiredDiscardLevel)//already loaded
+		{
+			return ;
+		}
+		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
+		mFullyLoaded = FALSE ;
 		return ;
 	}
 
 			mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, 
 					                             log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
 			mDesiredDiscardLevel = 	llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
+			mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
 		}
 		mKnownDrawSizeChanged = FALSE ;
 		
 	}
 	if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture
 	{
-		return -4.0f ; //alreay fetched
+		return -1.0f ; //alreay fetched
 	}
 
 	S32 cur_discard = getCurrentDiscardLevelForFetching();
 	}
 	else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
 	{
-		priority = -1.0f ;
+		priority = -2.0f ;
 	}
 	else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
 	{
-		priority = -1.0f;
+		priority = -3.0f;
 	}
 	else if (mDesiredDiscardLevel > getMaxDiscardLevel())
 	{
 		// Don't decode anything we don't need
-		priority = -1.0f;
+		priority = -4.0f;
 	}
 	else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
 	{
 			// Always want high boosted images
 			priority = 1.f;
 		}
+		else if(mForceToSaveRawImage)
+		{
+			//force to fetch the raw image.
+			priority = 1.f;
+		}
 		else
 		{
-			priority = -1.f; //stop fetching
+			priority = -5.f; //stop fetching
 		}
 	}
 	else if (cur_discard < 0)
 	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
 	{
 		// larger mips are corrupted
-		priority = -3.0f;
+		priority = -6.0f;
 	}
 	else
 	{
 	bool run_raw_callbacks = false;
 	bool need_readback = false;
 
+	mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
 	for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
 		iter != mLoadedCallbackList.end(); )
 	{
 		LLLoadedCallbackEntry *entryp = *iter++;
+		mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)entryp->mDesiredDiscard) ;
+
 		if (entryp->mNeedsImageRaw)
 		{
 			if (mNeedsAux)
 	if (mLoadedCallbackList.empty())
 	{
 		gTextureList.mCallbackList.erase(this);
+		mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
 	}
 
 	// Done with any raw image data at this point (will be re-created if we still have callbacks)

indra/newview/llviewervisualparam.cpp

 	node->getFastAttributeF32( camera_angle_string, mCamAngle );	// in degrees
 	static LLStdStringHandle camera_elevation_string = LLXmlTree::addAttributeString("camera_elevation");
 	node->getFastAttributeF32( camera_elevation_string, mCamElevation );
-	static LLStdStringHandle camera_target_string = LLXmlTree::addAttributeString("camera_target");
-	node->getFastAttributeString( camera_target_string, mCamTargetName );
 
 	mCamAngle += 180;
 

indra/newview/llviewervisualparam.h

 	F32			mCamDist;
 	F32			mCamAngle;		// degrees
 	F32			mCamElevation;
-	std::string	mCamTargetName;
 	F32			mEditGroupDisplayOrder;
 	BOOL		mShowSimple;	// show edit controls when in "simple ui" mode?
 	F32			mSimpleMin;		// when in simple UI, apply this minimum, range 0.f to 100.f
 	F32					getCameraDistance()	const	{ return getInfo()->mCamDist; } 
 	F32					getCameraAngle() const		{ return getInfo()->mCamAngle; }  // degrees
 	F32					getCameraElevation() const	{ return getInfo()->mCamElevation; } 
-	const std::string&	getCameraTargetName() const { return getInfo()->mCamTargetName; }
 	
 	BOOL				getShowSimple() const		{ return getInfo()->mShowSimple; }
 	F32					getSimpleMin() const		{ return getInfo()->mSimpleMin; }

indra/newview/llvoavatarself.cpp

 		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
 		{
 			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
-			text += llformat("[%d] '%s' ( ",baked_index, baked_dict->mName.c_str());
+			text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str());
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 		 ++iter)
 	{
 		const ETextureIndex t_index = (*iter);
-		lldebugs << "Checking index " << (U32) t_index << llendl;
-		// MULTI-WEARABLE: old method. replace.
-		const LLUUID& texture_id = getTEImage( t_index )->getID();
-		if (texture_id != IMG_DEFAULT_AVATAR)
+		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(t_index);
+		U32 count = gAgentWearables.getWearableCount(wearable_type);
+		lldebugs << "Checking index " << (U32) t_index << " count: " << count << llendl;
+		
+		for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)
 		{
-			// Search inventory for this texture.
-			LLViewerInventoryCategory::cat_array_t cats;
-			LLViewerInventoryItem::item_array_t items;
-			LLAssetIDMatches asset_id_matches(texture_id);
-			gInventory.collectDescendentsIf(LLUUID::null,
-											cats,
-											items,
-											LLInventoryModel::INCLUDE_TRASH,
-											asset_id_matches);
+			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index);
+			if (wearable)
+			{
+				const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index);
+				const LLUUID& texture_id = texture->getID();
+				if (texture_id != IMG_DEFAULT_AVATAR)
+				{
+					// Search inventory for this texture.
+					LLViewerInventoryCategory::cat_array_t cats;
+					LLViewerInventoryItem::item_array_t items;
+					LLAssetIDMatches asset_id_matches(texture_id);
+					gInventory.collectDescendentsIf(LLUUID::null,
+													cats,
+													items,
+													LLInventoryModel::INCLUDE_TRASH,
+													asset_id_matches);
 
-			BOOL can_grab = FALSE;
-			lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl;
-			if (items.count())
-			{
-				// search for full permissions version
-				for (S32 i = 0; i < items.count(); i++)
-				{
-					LLViewerInventoryItem* itemp = items[i];
-                                        if (itemp->getIsFullPerm())
+					BOOL can_grab = FALSE;
+					lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl;
+					if (items.count())
 					{
-						can_grab = TRUE;
-						break;
+						// search for full permissions version
+						for (S32 i = 0; i < items.count(); i++)
+						{
+							LLViewerInventoryItem* itemp = items[i];
+												if (itemp->getIsFullPerm())
+							{
+								can_grab = TRUE;
+								break;
+							}
+						}
 					}
+					if (!can_grab) return FALSE;
 				}
 			}
-			if (!can_grab) return FALSE;
 		}
 	}
 

indra/newview/llwearable.cpp

 				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
 			}
 			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
-			// MULTI-WEARABLE: replace hard-coded 0
+			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
 			gAgentAvatarp->setLocalTextureTE(te, image, 0);
 		}
 	}

indra/newview/llwearableitemslist.cpp

 	const uuid_vec_t& ids = mUUIDs;		// selected items IDs
 	LLUUID selected_id = ids.front();	// ID of the first selected item
 
-	functor_t wear = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, false);
+	functor_t wear = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, true);
+	functor_t add = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, false);
 	functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
 
 	// Register handlers common for all wearable types.
 	registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids));
+	registrar.add("Wearable.Add", boost::bind(handleMultiple, add, ids));
 	registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
 	registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
 	registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));

indra/newview/skins/default/textures/map_infohub.tga

Old
Old image
New
New image

indra/newview/skins/default/textures/textures.xml

   <texture name="Progress_11" file_name="icons/Progress_11.png" preload="true" />
   <texture name="Progress_12" file_name="icons/Progress_12.png" preload="true" />
 
-  <texture name="bevel_background" file_name="widgets/bevel_background.png" preload="true" scale.left="12" scale.top="15" scale.right="120" scale.bottom="2"/>
+  <texture name="bevel_background" file_name="widgets/bevel_background.png" preload="true" scale.left="12" scale.top="15" scale.right="108" scale.bottom="2"/>
   <texture name="buy_off" file_name="widgets/buy_off.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/>
   <texture name="buy_over" file_name="widgets/buy_over.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/>
   <texture name="buy_press" file_name="widgets/buy_press.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/>

indra/newview/skins/default/textures/widgets/buy_off.png

Old
Old image
New
New image

indra/newview/skins/default/textures/widgets/buy_over.png

Old
Old image
New
New image

indra/newview/skins/default/textures/widgets/buy_press.png

Old
Old image
New
New image

indra/newview/skins/default/xui/da/floater_buy_land.xml

 	<floater.string name="no_parcel_selected">
 		(intet parcel er valgt)
 	</floater.string>
-	<floater.string name="icon_PG" value="Parcel_PG_Dark"/>
-	<floater.string name="icon_M" value="Parcel_M_Dark"/>
-	<floater.string name="icon_R" value="Parcel_R_Dark"/>
 	<text name="region_name_label">
 		Region:
 	</text>

indra/newview/skins/default/xui/de/floater_buy_land.xml

 	<floater.string name="no_parcel_selected">
 		(keine Parzelle ausgewählt)
 	</floater.string>
-	<floater.string name="icon_PG" value="Parcel_PG_Dark"/>
-	<floater.string name="icon_M" value="Parcel_M_Dark"/>
-	<floater.string name="icon_R" value="Parcel_R_Dark"/>
 	<text name="region_name_label">
 		Region:
 	</text>

indra/newview/skins/default/xui/de/panel_landmark_info.xml

 	<string name="acquired_date">
 		[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
 	</string>
-	<string name="icon_PG" value="parcel_drk_PG"/>
-	<string name="icon_M" value="parcel_drk_M"/>
-	<string name="icon_R" value="parcel_drk_R"/>
 	<button name="back_btn" tool_tip="Hinten"/>
 	<text name="title" value="Ortsprofil"/>
 	<scroll_container name="place_scroll">

indra/newview/skins/default/xui/de/panel_place_profile.xml

 	<string name="acquired_date">
 		[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
 	</string>
-	<string name="icon_PG" value="parcel_drk_PG"/>
-	<string name="icon_M" value="parcel_drk_M"/>
-	<string name="icon_R" value="parcel_drk_R"/>
-	<string name="icon_Voice" value="parcel_drk_Voice"/>
-	<string name="icon_VoiceNo" value="parcel_drk_VoiceNo"/>
-	<string name="icon_Fly" value="parcel_drk_Fly"/>
-	<string name="icon_FlyNo" value="parcel_drk_FlyNo"/>
-	<string name="icon_Push" value="parcel_drk_Push"/>
-	<string name="icon_PushNo" value="parcel_drk_PushNo"/>
-	<string name="icon_Build" value="parcel_drk_Build"/>
-	<string name="icon_BuildNo" value="parcel_drk_BuildNo"/>
-	<string name="icon_Scripts" value="parcel_drk_Scripts"/>
-	<string name="icon_ScriptsNo" value="parcel_drk_ScriptsNo"/>
-	<string name="icon_Damage" value="parcel_drk_Damage"/>
-	<string name="icon_DamageNo" value="parcel_drk_DamageNo"/>
 	<button name="back_btn" tool_tip="Hinten"/>
 	<text name="title" value="Ortsprofil"/>
 	<scroll_container name="place_scroll">

indra/newview/skins/default/xui/en/floater_buy_land.xml

     </floater.string>
     <floater.string
      name="icon_PG"
+     translate="false"
      value="Parcel_PG_Dark"/>
     <floater.string
      name="icon_M"
+     translate="false"
      value="Parcel_M_Dark"/>
     <floater.string
      name="icon_R"
+     translate="false"
      value="Parcel_R_Dark"/>
     <text
      type="string"

indra/newview/skins/default/xui/en/menu_inventory.xml

          parameter="wear" />
     </menu_item_call>
     <menu_item_call
+     label="Add"
+     layout="topleft"
+     name="Wearable Add">
+        <menu_item_call.on_click
+         function="Inventory.DoToSelected"
+         parameter="wear_add" />
+    </menu_item_call>
+    <menu_item_call
      label="Take Off"
      layout="topleft"
      name="Take Off">

indra/newview/skins/default/xui/en/menu_wearable_list_item.xml

          function="Wearable.Wear" />
     </menu_item_call>
     <menu_item_call
+     label="Add"
+     layout="topleft"
+     name="wear_add">
+        <on_click
+         function="Wearable.Add" />
+    </menu_item_call>
+    <menu_item_call
      label="Take Off / Detach"
      layout="topleft"
      name="take_off_or_detach">

indra/newview/skins/default/xui/en/notifications.xml

   </notification>
 
   <notification
+ icon="alertmodal.tga"
+ label="Save Wearable"
+ name="SaveWearableAs"
+ type="alertmodal">
+    Save item to my inventory as:
+    <form name="form">
+      <input name="message" type="text">
+        [DESC] (new)
+      </input>
+      <button
+       default="true"
+       index="0"
+       name="Offer"
+       text="OK"/>
+      <button
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+    </form>
+  </notification>
+
+
+  <notification
    icon="alertmodal.tga"
    label="Rename Outfit"
    name="RenameOutfit"

indra/newview/skins/default/xui/en/panel_landmark_info.xml

     <!-- Texture names for rating icons -->
     <string
      name="icon_PG"
+     translate="false"
      value="Parcel_PG_Dark" />
     <string
      name="icon_M"
+     translate="false"
      value="Parcel_M_Dark" />
     <string
      name="icon_R"
+     translate="false"
      value="Parcel_R_Dark" />
     <button
      follows="top|right"

indra/newview/skins/default/xui/en/panel_place_profile.xml

     <!-- Texture names for parcel permissions icons -->
     <string
      name="icon_PG"
+     translate="false"
      value="Parcel_PG_Dark" />
     <string
      name="icon_M"
+     translate="false"
      value="Parcel_M_Dark" />
     <string
      name="icon_R"
+     translate="false"
      value="Parcel_R_Dark" />
     <string
      name="icon_Voice"
+     translate="false"
      value="Parcel_Voice_Dark" />
     <string
      name="icon_VoiceNo"
+     translate="false"
      value="Parcel_VoiceNo_Dark" />
     <string
      name="icon_Fly"
+     translate="false"
      value="Parcel_Fly_Dark" />
     <string
      name="icon_FlyNo"
+     translate="false"
      value="Parcel_FlyNo_Dark" />
     <string
      name="icon_Push"
+     translate="false"
      value="Parcel_Push_Dark" />
     <string
      name="icon_PushNo"
+     translate="false"
      value="Parcel_PushNo_Dark" />
     <string
      name="icon_Build"
+     translate="false"
      value="Parcel_Build_Dark" />
     <string
      name="icon_BuildNo"
+     translate="false"
      value="Parcel_BuildNo_Dark" />
     <string
      name="icon_Scripts"
+     translate="false"
      value="Parcel_Scripts_Dark" />
     <string
      name="icon_ScriptsNo"
+     translate="false"
      value="Parcel_ScriptsNo_Dark" />
     <string
      name="icon_Damage"
+     translate="false"
      value="Parcel_Damage_Dark" />
     <string
      name="icon_DamageNo"
+     translate="false"
      value="Parcel_DamageNo_Dark" />
     <button
      follows="top|right"

indra/newview/skins/default/xui/en/panel_status_bar.xml

      name="buycurrencylabel">
         L$ [AMT]
     </panel.string>
-    <button
+  <panel
+    height="18"
+    left="-315"
+    width="95"
+    top="1"
+    follows="right|top" 
+    name="balance_bg" 
+    bg_visible="true"
+    background_opaque="true" 
+    bg_opaque_image="bevel_background">
+    <text
      auto_resize="true"
      halign="center"
-	 enabled="false"
      font="SansSerifSmall"
-     follows="right|top"
-     image_overlay=""
-     image_selected="bevel_background"
-     image_unselected="bevel_background"
-     image_pressed="bevel_background"
+     follows="all"