diff options
Diffstat (limited to 'indra/newview')
149 files changed, 1828 insertions, 741 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d51498f6d1..c2236233dc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -585,7 +585,7 @@        <key>Value</key>        <integer>2</integer>      </map> -    <key>AvatarBakedTextureTimeout</key> +    <key>AvatarBakedTextureUploadTimeout</key>      <map>        <key>Comment</key>        <string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance.  Set to 0 to disable and wait until all baked textures are at highest resolution.</string> @@ -594,8 +594,20 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>120</integer> +      <integer>60</integer>      </map> +    <key>AvatarBakedLocalTextureUpdateTimeout</key> +    <map> +      <key>Comment</key> +      <string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>U32</string> +      <key>Value</key> +      <integer>10</integer> +    </map> +      <key>AvatarSex</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 4e5fdb1219..7c92a5a756 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3075,7 +3075,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *  		return;  	} -	if (gAgentCamera.cameraCustomizeAvatar()) +	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  	{  		// ignore baked textures when in customize mode  		return; @@ -3541,7 +3541,7 @@ void LLAgent::sendAgentSetAppearance()  {  	if (!isAgentAvatarValid()) return; -	if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgentCamera.cameraCustomizeAvatar())  +	if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))   	{  		return;  	} diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 1ef9e34f87..4dc78e9a1d 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -941,7 +941,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)  		*/  	} -	if( cameraCustomizeAvatar() ) +	if(cameraCustomizeAvatar())  	{  		new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );  	} diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp index e97f136489..3d4e34a549 100644 --- a/indra/newview/llagentlanguage.cpp +++ b/indra/newview/llagentlanguage.cpp @@ -39,21 +39,35 @@  // library includes  #include "llui.h"					// getLanguage() -LLAgentLanguage::LLAgentLanguage() +// static +void LLAgentLanguage::init()  { -	gSavedSettings.getControl("Language")->getSignal()->connect(boost::bind(&update)); -	gSavedSettings.getControl("InstallLanguage")->getSignal()->connect(boost::bind(&update)); -	gSavedSettings.getControl("SystemLanguage")->getSignal()->connect(boost::bind(&update)); -	gSavedSettings.getControl("LanguageIsPublic")->getSignal()->connect(boost::bind(&update)); +	gSavedSettings.getControl("Language")->getSignal()->connect(boost::bind(&onChange)); +	gSavedSettings.getControl("InstallLanguage")->getSignal()->connect(boost::bind(&onChange)); +	gSavedSettings.getControl("SystemLanguage")->getSignal()->connect(boost::bind(&onChange)); +	gSavedSettings.getControl("LanguageIsPublic")->getSignal()->connect(boost::bind(&onChange));  } +// static +void LLAgentLanguage::onChange() +{ +	// Clear inventory cache so that default names of inventory items +	// appear retranslated (EXT-8308). +	gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE); +}  // send language settings to the sim  // static  bool LLAgentLanguage::update()  {  	LLSD body; -	std::string url = gAgent.getRegion()->getCapability("UpdateAgentLanguage"); +	std::string url; + +	if (gAgent.getRegion()) +	{ +		url = gAgent.getRegion()->getCapability("UpdateAgentLanguage"); +	} +  	if (!url.empty())  	{  		std::string language = LLUI::getLanguage(); diff --git a/indra/newview/llagentlanguage.h b/indra/newview/llagentlanguage.h index 45348a1e50..d7e6f3c6c7 100644 --- a/indra/newview/llagentlanguage.h +++ b/indra/newview/llagentlanguage.h @@ -33,14 +33,14 @@  #ifndef LL_LLAGENTLANGUAGE_H  #define LL_LLAGENTLANGUAGE_H -#include "llsingleton.h"	// LLSingleton<> -#include "llevent.h" - -class LLAgentLanguage: public LLSingleton<LLAgentLanguage>, public LLOldEvents::LLSimpleListener +class LLAgentLanguage  {   public: -	LLAgentLanguage(); +	static void init();  	static bool update(); + + private: +	static void onChange();  };  #endif // LL_LLAGENTLANGUAGE_H diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index efa5eca217..6ee5a8b279 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -384,7 +384,8 @@ void LLAgentWearables::sendAgentWearablesUpdate()  	gAgent.sendReliableMessage();  } -void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update) +void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update, +									const std::string new_name)  {  	LLWearable* old_wearable = getWearable(type, index);  	if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion())) @@ -402,6 +403,14 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32  		LLInventoryItem* item = gInventory.getItem(old_item_id);  		if (item)  		{ +			std::string item_name = item->getName(); +			bool name_changed = false; +			if (!new_name.empty() && (new_name != item->getName())) +			{ +				llinfos << "saveWearable changing name from "  << item->getName() << " to " << new_name << llendl; +				item_name = new_name; +				name_changed = true; +			}  			// Update existing inventory item  			LLPointer<LLViewerInventoryItem> template_item =  				new LLViewerInventoryItem(item->getUUID(), @@ -410,7 +419,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32  										  new_wearable->getAssetID(),  										  new_wearable->getAssetType(),  										  item->getInventoryType(), -										  item->getName(), +										  item_name,  										  item->getDescription(),  										  item->getSaleInfo(),  										  item->getFlags(), @@ -418,6 +427,10 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32  			template_item->setTransactionID(new_wearable->getTransactionID());  			template_item->updateServer(FALSE);  			gInventory.updateItem(template_item); +			if (name_changed) +			{ +				gInventory.notifyObservers(); +			}  		}  		else  		{ diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 8122971db6..f3457363a0 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -206,7 +206,8 @@ private:  	//--------------------------------------------------------------------  public:	  	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found); -	void			saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE); +	void			saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE, +								 const std::string new_name = "");  	void			saveAllWearables();  	void			revertWearable(const LLWearableType::EType type, const U32 index); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 43f6be42b6..e1635461db 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -983,6 +983,10 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up  		LLNotificationsUtil::add("CannotWearTrash");  		return false;  	} +	else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), LLAppearanceMgr::instance().getCOF())) // EXT-84911 +	{ +		return false; +	}  	switch (item_to_wear->getType())  	{ @@ -1801,9 +1805,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  	llinfos << "wearInventoryCategory( " << category->getName()  			 << " )" << llendl; -	callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, -														   &LLAppearanceMgr::instance(), -														   category->getUUID(), copy, append)); +	callAfterCategoryFetch(category->getUUID(), boost::bind(&LLAppearanceMgr::wearCategoryFinal, +															&LLAppearanceMgr::instance(), +															category->getUUID(), copy, append));  }  void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append) @@ -2217,6 +2221,7 @@ void LLAppearanceMgr::updateIsDirty()  			LLViewerInventoryItem *item2 = outfit_items.get(i);  			if (item1->getLinkedUUID() != item2->getLinkedUUID() ||  +				item1->getName() != item2->getName() ||  				item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription())  			{  				mOutfitIsDirty = true; @@ -2706,6 +2711,21 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const  	return gInventory.isObjectDescendentOf(obj_id, getCOF());  } +// static +bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id) +{ +	 LLInventoryModel::cat_array_t cats; +	 LLInventoryModel::item_array_t items; +	 LLLinkedItemIDMatches find_links(gInventory.getLinkedItemID(obj_id)); +	 gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), +	 cats, +	 items, +	 LLInventoryModel::EXCLUDE_TRASH, +	 find_links); + +	 return !items.empty(); +} +  BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const  {  	if (!getIsInCOF(obj_id)) return FALSE; @@ -2733,3 +2753,192 @@ BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const  	return FALSE;  	*/  } + +// Shim class to allow arbitrary boost::bind +// expressions to be run as one-time idle callbacks. +// +// TODO: rework idle function spec to take a boost::function in the first place. +class OnIdleCallbackOneTime +{ +public: +	OnIdleCallbackOneTime(nullary_func_t callable): +		mCallable(callable) +	{ +	} +	static void onIdle(void *data) +	{ +		gIdleCallbacks.deleteFunction(onIdle, data); +		OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data); +		self->call(); +		delete self; +	} +	void call() +	{ +		mCallable(); +	} +private: +	nullary_func_t mCallable; +}; + +void doOnIdleOneTime(nullary_func_t callable) +{ +	OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); +	gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); +} + +// Shim class to allow generic boost functions to be run as +// recurring idle callbacks.  Callable should return true when done, +// false to continue getting called. +// +// TODO: rework idle function spec to take a boost::function in the first place. +class OnIdleCallbackRepeating +{ +public: +	OnIdleCallbackRepeating(bool_func_t callable): +		mCallable(callable) +	{ +	} +	// Will keep getting called until the callable returns true. +	static void onIdle(void *data) +	{ +		OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data); +		bool done = self->call(); +		if (done) +		{ +			gIdleCallbacks.deleteFunction(onIdle, data); +			delete self; +		} +	} +	bool call() +	{ +		return mCallable(); +	} +private: +	bool_func_t mCallable; +}; + +void doOnIdleRepeating(bool_func_t callable) +{ +	OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); +	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); +} + +class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver +{ +public: +	CallAfterCategoryFetchStage2(const uuid_vec_t& ids, +								 nullary_func_t callable) : +		LLInventoryFetchItemsObserver(ids), +		mCallable(callable) +	{ +	} +	~CallAfterCategoryFetchStage2() +	{ +	} +	virtual void done() +	{ +		llinfos << this << " done with incomplete " << mIncomplete.size() +				<< " complete " << mComplete.size() <<  " calling callable" << llendl; + +		gInventory.removeObserver(this); +		doOnIdleOneTime(mCallable); +		delete this; +	} +protected: +	nullary_func_t mCallable; +}; + +class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: +	CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) : +		LLInventoryFetchDescendentsObserver(cat_id), +		mCallable(callable) +	{ +	} +	~CallAfterCategoryFetchStage1() +	{ +	} +	virtual void done() +	{ +		// What we do here is get the complete information on the items in +		// the library, and set up an observer that will wait for that to +		// happen. +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t item_array; +		gInventory.collectDescendents(mComplete.front(), +									  cat_array, +									  item_array, +									  LLInventoryModel::EXCLUDE_TRASH); +		S32 count = item_array.count(); +		if(!count) +		{ +			llwarns << "Nothing fetched in category " << mComplete.front() +					<< llendl; +			//dec_busy_count(); +			gInventory.removeObserver(this); + +			// lets notify observers that loading is finished. +			gAgentWearables.notifyLoadingFinished(); +			delete this; +			return; +		} + +		llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl; +		uuid_vec_t ids; +		for(S32 i = 0; i < count; ++i) +		{ +			ids.push_back(item_array.get(i)->getUUID()); +		} +		 +		gInventory.removeObserver(this); +		 +		// do the fetch +		CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable); +		stage2->startFetch(); +		if(stage2->isFinished()) +		{ +			// everything is already here - call done. +			stage2->done(); +		} +		else +		{ +			// it's all on it's way - add an observer, and the inventory +			// will call done for us when everything is here. +			gInventory.addObserver(stage2); +		} +		delete this; +	} +protected: +	nullary_func_t mCallable; +}; + +void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb) +{ +	CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb); +	stage1->startFetch(); +	if (stage1->isFinished()) +	{ +		stage1->done(); +	} +	else +	{ +		gInventory.addObserver(stage1); +	} +} + +void wear_multiple(const uuid_vec_t& ids, bool replace) +{ +	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy; +	 +	bool first = true; +	uuid_vec_t::const_iterator it; +	for (it = ids.begin(); it != ids.end(); ++it) +	{ +		// if replace is requested, the first item worn will replace the current top +		// item, and others will be added. +		LLAppearanceMgr::instance().wearItemOnAvatar(*it,false,first && replace,cb); +		first = false; +	} +} + diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 84c911c038..9f554dbdef 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -223,6 +223,11 @@ public:  	BOOL getIsInCOF(const LLUUID& obj_id) const;  	// Is this in the COF and can the user delete it from the COF?  	BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; + +	/** +	 * Checks if COF contains link to specified object. +	 */ +	static bool isLinkInCOF(const LLUUID& obj_id);  };  class LLUpdateAppearanceOnDestroy: public LLInventoryCallback @@ -242,180 +247,19 @@ private:  LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); -// Shim class and template function to allow arbitrary boost::bind -// expressions to be run as one-time idle callbacks. -template <typename T> -class OnIdleCallbackOneTime -{ -public: -	OnIdleCallbackOneTime(T callable): -		mCallable(callable) -	{ -	} -	static void onIdle(void *data) -	{ -		gIdleCallbacks.deleteFunction(onIdle, data); -		OnIdleCallbackOneTime<T>* self = reinterpret_cast<OnIdleCallbackOneTime<T>*>(data); -		self->call(); -		delete self; -	} -	void call() -	{ -		mCallable(); -	} -private: -	T mCallable; -}; +typedef boost::function<void ()> nullary_func_t; +typedef boost::function<bool ()> bool_func_t; -template <typename T> -void doOnIdleOneTime(T callable) -{ -	OnIdleCallbackOneTime<T>* cb_functor = new OnIdleCallbackOneTime<T>(callable); -	gIdleCallbacks.addFunction(&OnIdleCallbackOneTime<T>::onIdle,cb_functor); -} - -// Shim class and template function to allow arbitrary boost::bind -// expressions to be run as recurring idle callbacks. -// Callable should return true when done, false to continue getting called. -template <typename T> -class OnIdleCallbackRepeating -{ -public: -	OnIdleCallbackRepeating(T callable): -		mCallable(callable) -	{ -	} -	// Will keep getting called until the callable returns true. -	static void onIdle(void *data) -	{ -		OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data); -		bool done = self->call(); -		if (done) -		{ -			gIdleCallbacks.deleteFunction(onIdle, data); -			delete self; -		} -	} -	bool call() -	{ -		return mCallable(); -	} -private: -	T mCallable; -}; +// Call a given callable once in idle loop. +void doOnIdleOneTime(nullary_func_t callable); -template <typename T> -void doOnIdleRepeating(T callable) -{ -	OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable); -	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor); -} +// Repeatedly call a callable in idle loop until it returns true. +void doOnIdleRepeating(bool_func_t callable); -template <class T> -class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver -{ -public: -	CallAfterCategoryFetchStage2(const uuid_vec_t& ids, -								 T callable) : -		LLInventoryFetchItemsObserver(ids), -		mCallable(callable) -	{ -	} -	~CallAfterCategoryFetchStage2() -	{ -	} -	virtual void done() -	{ -		llinfos << this << " done with incomplete " << mIncomplete.size() -				<< " complete " << mComplete.size() <<  " calling callable" << llendl; - -		gInventory.removeObserver(this); -		doOnIdleOneTime(mCallable); -		delete this; -	} -protected: -	T mCallable; -}; +// Invoke a given callable after category contents are fully fetched. +void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); -template <class T> -class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver -{ -public: -	CallAfterCategoryFetchStage1(const LLUUID& cat_id, T callable) : -		LLInventoryFetchDescendentsObserver(cat_id), -		mCallable(callable) -	{ -	} -	~CallAfterCategoryFetchStage1() -	{ -	} -	virtual void done() -	{ -		// What we do here is get the complete information on the items in -		// the library, and set up an observer that will wait for that to -		// happen. -		LLInventoryModel::cat_array_t cat_array; -		LLInventoryModel::item_array_t item_array; -		gInventory.collectDescendents(mComplete.front(), -									  cat_array, -									  item_array, -									  LLInventoryModel::EXCLUDE_TRASH); -		S32 count = item_array.count(); -		if(!count) -		{ -			llwarns << "Nothing fetched in category " << mComplete.front() -					<< llendl; -			//dec_busy_count(); -			gInventory.removeObserver(this); - -			// lets notify observers that loading is finished. -			gAgentWearables.notifyLoadingFinished(); -			delete this; -			return; -		} - -		llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl; -		uuid_vec_t ids; -		for(S32 i = 0; i < count; ++i) -		{ -			ids.push_back(item_array.get(i)->getUUID()); -		} -		 -		gInventory.removeObserver(this); -		 -		// do the fetch -		CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(ids, mCallable); -		stage2->startFetch(); -		if(stage2->isFinished()) -		{ -			// everything is already here - call done. -			stage2->done(); -		} -		else -		{ -			// it's all on it's way - add an observer, and the inventory -			// will call done for us when everything is here. -			gInventory.addObserver(stage2); -		} -		delete this; -	} -protected: -	T mCallable; -}; - -template <class T>  -void callAfterCategoryFetch(const LLUUID& cat_id, T callable) -{ -	CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(cat_id, callable); -	stage1->startFetch(); -	if (stage1->isFinished()) -	{ -		stage1->done(); -	} -	else -	{ -		gInventory.addObserver(stage1); -	} -} +// Wear all items in a uuid vector. +void wear_multiple(const uuid_vec_t& ids, bool replace);  #endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 682e3eb874..58b651ec39 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -45,6 +45,7 @@  #include "llgroupmgr.h"  #include "llagent.h"  #include "llagentcamera.h" +#include "llagentlanguage.h"  #include "llagentwearables.h"  #include "llwindow.h"  #include "llviewerstats.h" @@ -356,7 +357,7 @@ static void ui_audio_callback(const LLUUID& uuid)  bool	create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)  { -	if(!match || !base) +	if(!match || !base || base->getPlainText())  		return false;  	LLUUID match_id = match->getID(); @@ -385,7 +386,7 @@ bool	create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)  	params.view = icon;  	params.left_pad = 4;  	params.right_pad = 4; -	params.top_pad = 2; +	params.top_pad = -2;  	params.bottom_pad = 2;  	base->appendWidget(params," ",false); @@ -946,6 +947,8 @@ bool LLAppViewer::init()  		LLStringOps::sPM = LLTrans::getString("dateTimePM");  	} +	LLAgentLanguage::init(); +  	return true;  } diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 752a2e7504..1e59e5b805 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -550,9 +550,10 @@ namespace action_give_inventory  		}  		LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); -		if (NULL == active_panel) +		if (!active_panel)  		{ -			return; +			active_panel = get_outfit_editor_inventory_panel(); +			if (!active_panel) return;  		}  		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index c0fa910f86..7c33923f04 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -111,6 +111,12 @@ public:  		return pInstance;  	} +	~LLChatHistoryHeader() +	{ +		// Detach the info button so that it doesn't get destroyed (EXT-8463). +		hideInfoCtrl(); +	} +  	BOOL handleMouseUp(S32 x, S32 y, MASK mask)  	{  		return LLPanel::handleMouseUp(x,y,mask); @@ -382,8 +388,18 @@ protected:  		if (!sInfoCtrl)  		{ +			// *TODO: Delete the button at exit.  			sInfoCtrl = LLUICtrlFactory::createFromFile<LLUICtrl>("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance()); -			sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl)); +			if (sInfoCtrl) +			{ +				sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl)); +			} +		} + +		if (!sInfoCtrl) +		{ +			llassert(sInfoCtrl != NULL); +			return;  		}  		LLTextBase* name = getChild<LLTextBase>("user_name"); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 4c0f51056d..629a92db11 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -283,7 +283,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),  	mClothingTab(NULL),  	mAttachmentsTab(NULL),  	mBodyPartsTab(NULL), -	mLastSelectedTab(NULL) +	mLastSelectedTab(NULL), +	mAccordionCtrl(NULL)  {  	mClothingMenu = new CofClothingContextMenu(this);  	mAttachmentMenu = new CofAttachmentContextMenu(this); @@ -335,6 +336,8 @@ BOOL LLCOFWearables::postBuild()  	mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT;  	mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART; +	mAccordionCtrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); +  	return LLPanel::postBuild();  } @@ -633,18 +636,35 @@ LLAssetType::EType LLCOFWearables::getExpandedAccordionAssetType()  	typedef std::map<std::string, LLAssetType::EType> type_map_t;  	static type_map_t type_map; -	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); -	const LLAccordionCtrlTab* expanded_tab = accordion_ctrl->getExpandedTab(); -	return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE); +	if (mAccordionCtrl != NULL) +	{ +		const LLAccordionCtrlTab* expanded_tab = mAccordionCtrl->getExpandedTab(); + +		return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE); +	} + +	return LLAssetType::AT_NONE;  }  LLAssetType::EType LLCOFWearables::getSelectedAccordionAssetType()  { -	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); -	const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab(); +	if (mAccordionCtrl != NULL) +	{ +		const LLAccordionCtrlTab* selected_tab = mAccordionCtrl->getSelectedTab(); -	return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE); +		return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE); +	} + +	return LLAssetType::AT_NONE; +} + +void LLCOFWearables::expandDefaultAccordionTab() +{ +	if (mAccordionCtrl != NULL) +	{ +		mAccordionCtrl->expandDefaultTab(); +	}  }  void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu) diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 0518d59df3..9a259600a9 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -40,6 +40,7 @@  #include "llappearancemgr.h"  #include "llinventorymodel.h" +class LLAccordionCtrl;  class LLAccordionCtrlTab;  class LLListContextMenu;  class LLPanelClothingListItem; @@ -86,6 +87,7 @@ public:  	LLAssetType::EType getExpandedAccordionAssetType();  	LLAssetType::EType getSelectedAccordionAssetType(); +	void expandDefaultAccordionTab();  	LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; } @@ -123,6 +125,8 @@ protected:  	LLListContextMenu* mClothingMenu;  	LLListContextMenu* mAttachmentMenu;  	LLListContextMenu* mBodyPartMenu; + +	LLAccordionCtrl*	mAccordionCtrl;  }; diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index fd3df359bd..7ebcef943e 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -35,6 +35,8 @@  #include "lluictrlfactory.h"  #include "lltextbox.h"  #include "lllineeditor.h" +#include "llresmgr.h" // for LLLocale +#include "lltrans.h"  #include "llviewercontrol.h"  #include "llversioninfo.h" @@ -323,7 +325,12 @@ std::string LLCurrencyUIManager::Impl::getLocalEstimate() const  	if (mUSDCurrencyEstimated)  	{  		// we have the old-style USD-specific value -		return "US$ " + llformat("%#.2f", mUSDCurrencyEstimatedCost / 100.0); +		LLStringUtil::format_map_t args; +		{ +			LLLocale locale_override(LLStringUtil::getLocale()); +			args["[AMOUNT]"] = llformat("%#.2f", mUSDCurrencyEstimatedCost / 100.0); +		} +		return LLTrans::getString("LocalEstimateUSD", args);  	}  	return "";  } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 68809b0926..c206daf89b 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -149,7 +149,7 @@ void LLStandardBumpmap::restoreGL()  										0,   										0);									  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; -		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL, NULL ); +		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );  		LLStandardBumpmap::sStandardBumpmapCount++;  	} @@ -923,7 +923,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText  			// Note: this may create an LLImageGL immediately  			src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; -			src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL, NULL ); +			src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );  			bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image  //			bump_total++; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index c423473740..bb4e6c7a3e 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -167,6 +167,10 @@ void LLViewerDynamicTexture::postRender(BOOL success)  			{  				generateGLTexture() ;  			} +			if(!mGLTexturep->getHasGLTexture()) +			{ +				generateGLTexture() ; +			}  			llcallstacks << "class type: " << (S32)getType() << llcallstacksendl ;  			success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index dbbcb6e7c4..f299518474 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1364,7 +1364,7 @@ F32 LLFace::getTextureVirtualSize()  	F32 cos_angle_to_view_dir;	  	BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius); -	if (mPixelArea < 0.0001f || !in_frustum) +	if (mPixelArea < F_ALMOST_ZERO || !in_frustum)  	{  		setVirtualSize(0.f) ;  		return 0.f; diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index c71764c2e5..3952c54670 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -47,6 +47,7 @@  #include "llbutton.h"  #include "llgroupactions.h"  #include "llscrolllistctrl.h" +#include "llselectmgr.h"  #include "lltextbox.h"  #include "lluictrlfactory.h"  #include "lltrans.h" @@ -89,6 +90,7 @@ BOOL LLFloaterGroupPicker::postBuild()  		list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP);  	} +	LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterGroupPicker::onBtnCancel, this));  	childSetAction("OK", onBtnOK, this); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 913bb676b0..f0ed659f5a 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2088,7 +2088,8 @@ void LLPanelLandOptions::refresh()  			LLStyle::Params style;  			style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate")));  			LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl; -			fullaccess_mature_ctrl->getTextBox()->setText(std::string("icon"),style); +			fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit("")); +			fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style);  			fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false);  			fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip"));  			fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE); diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp index 63365e3461..48095ff200 100644 --- a/indra/newview/llfloatervoicedevicesettings.cpp +++ b/indra/newview/llfloatervoicedevicesettings.cpp @@ -227,7 +227,23 @@ void LLPanelVoiceDeviceSettings::refresh()  				iter != LLVoiceClient::getInstance()->getCaptureDevices().end();  				iter++)  			{ -				mCtrlInputDevices->add( *iter, ADD_BOTTOM ); +				// Lets try to localize some system device names. EXT-8375 +				std::string device_name = *iter; +				LLStringUtil::toLower(device_name); //compare in low case +				if ("default system device" == device_name) +				{ +					device_name = getString(device_name); +				} +				else if ("no device" == device_name) +				{ +					device_name = getString(device_name); +				} +				else +				{ +					// restore original value +					device_name = *iter; +				} +				mCtrlInputDevices->add(device_name, ADD_BOTTOM );  			}  			if(!mCtrlInputDevices->setSimple(mInputDevice)) @@ -244,7 +260,23 @@ void LLPanelVoiceDeviceSettings::refresh()  			for(iter= LLVoiceClient::getInstance()->getRenderDevices().begin();   				iter !=  LLVoiceClient::getInstance()->getRenderDevices().end(); iter++)  			{ -				mCtrlOutputDevices->add( *iter, ADD_BOTTOM ); +				// Lets try to localize some system device names. EXT-8375 +				std::string device_name = *iter; +				LLStringUtil::toLower(device_name); //compare in low case +				if ("default system device" == device_name) +				{ +					device_name = getString(device_name); +				} +				else if ("no device" == device_name) +				{ +					device_name = getString(device_name); +				} +				else +				{ +					// restore original value +					device_name = *iter; +				} +				mCtrlOutputDevices->add(device_name, ADD_BOTTOM );  			}  			if(!mCtrlOutputDevices->setSimple(mOutputDevice)) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 983fd97b0b..88f8545877 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -206,6 +206,7 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)  	mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);  	//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE); +	mCommitCallbackRegistrar.add("WMap.Coordinates",	boost::bind(&LLFloaterWorldMap::onCoordinatesCommit, this));  	mCommitCallbackRegistrar.add("WMap.Location",		boost::bind(&LLFloaterWorldMap::onLocationCommit, this));  	mCommitCallbackRegistrar.add("WMap.AvatarCombo",	boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));  	mCommitCallbackRegistrar.add("WMap.Landmark",		boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this)); @@ -336,8 +337,6 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)  	}  } - -  // static  void LLFloaterWorldMap::reloadIcons(void*)  { @@ -582,6 +581,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)  		S32 world_y = S32(pos_global.mdV[1] / 256);  		LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);  		setDefaultBtn(""); + +		// clicked on a non-region - turn off coord display +		enableTeleportCoordsDisplay( false ); +  		return;  	}  	if (sim_info->isDown()) @@ -592,6 +595,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)  		LLWorldMap::getInstance()->setTrackingInvalid();  		LLTracker::stopTracking(NULL);  		setDefaultBtn(""); + +		// clicked on a down region - turn off coord display +		enableTeleportCoordsDisplay( false ); +  		return;  	} @@ -609,9 +616,40 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)  	LLTracker::trackLocation(pos_global, full_name, tooltip);  	LLWorldMap::getInstance()->cancelTracking();		// The floater is taking over the tracking +	LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); +	updateTeleportCoordsDisplay( coord_pos ); + +	// we have a valid region - turn on coord display +	enableTeleportCoordsDisplay( true ); +  	setDefaultBtn("Teleport");  } +// enable/disable teleport destination coordinates  +void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled ) +{ +	childSetEnabled("teleport_coordinate_x", enabled ); +	childSetEnabled("teleport_coordinate_y", enabled ); +	childSetEnabled("teleport_coordinate_z", enabled ); +} + +// update display of teleport destination coordinates - pos is in global coordinates +void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos ) +{ +	// if we're going to update their value, we should also enable them +	enableTeleportCoordsDisplay( true ); + +	// convert global specified position to a local one +	F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS ); +	F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS ); +	F32 region_local_z = (F32)fmod( pos.mdV[VZ], (F64)REGION_WIDTH_METERS ); + +	// write in the values +	childSetValue("teleport_coordinate_x", region_local_x ); +	childSetValue("teleport_coordinate_y", region_local_y ); +	childSetValue("teleport_coordinate_z", region_local_z ); +} +  void LLFloaterWorldMap::updateLocation()  {  	bool gotSimName; @@ -638,6 +676,9 @@ void LLFloaterWorldMap::updateLocation()  				// Fill out the location field  				childSetValue("location", agent_sim_name); +				// update the coordinate display with location of avatar in region +				updateTeleportCoordsDisplay( agentPos ); +  				// Figure out where user is  				// Set the current SLURL  				mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal()); @@ -668,6 +709,10 @@ void LLFloaterWorldMap::updateLocation()  		childSetValue("location", sim_name); +		// refresh coordinate display to reflect where user clicked. +		LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); +		updateTeleportCoordsDisplay( coord_pos ); +  		// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL  		if ( gotSimName )  		{ @@ -1139,6 +1184,22 @@ void LLFloaterWorldMap::onLocationCommit()  	}  } +void LLFloaterWorldMap::onCoordinatesCommit() +{ +	if( mIsClosing ) +	{ +		return; +	} + +	S32 x_coord = (S32)childGetValue("teleport_coordinate_x").asReal(); +	S32 y_coord = (S32)childGetValue("teleport_coordinate_y").asReal(); +	S32 z_coord = (S32)childGetValue("teleport_coordinate_z").asReal(); + +	const std::string region_name = childGetValue("location").asString(); + +	trackURL( region_name, x_coord, y_coord, z_coord ); +} +  void LLFloaterWorldMap::onClearBtn()  {  	mTrackedStatus = LLTracker::TRACKING_NOTHING; @@ -1199,6 +1260,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)  	else if(LLWorldMap::getInstance()->isTracking())  	{  		pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();; + + +  	}  	else  	{ diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 550b4ef689..e31bafaf9b 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -149,6 +149,7 @@ protected:  	void			updateSearchEnabled();  	void			onLocationFocusChanged( LLFocusableElement* ctrl );  	void		    onLocationCommit(); +	void			onCoordinatesCommit();  	void		    onCommitSearchResult();  	void			cacheLandmarkPosition(); @@ -160,6 +161,12 @@ private:  	F32						mCurZoomVal;  	LLFrameTimer			mZoomTimer; +	// update display of teleport destination coordinates - pos is in global coordinates +	void updateTeleportCoordsDisplay( const LLVector3d& pos ); + +	// enable/disable teleport destination coordinates  +	void enableTeleportCoordsDisplay( bool enabled ); +  	LLDynamicArray<LLUUID>	mLandmarkAssetIDList;  	LLDynamicArray<LLUUID>	mLandmarkItemIDList; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 87c5a830e9..5aa504eb35 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1195,7 +1195,7 @@ void LLFolderView::propertiesSelectedItems( void )  void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)  { -	LLFolderBridge *folder_bridge = LLFolderBridge::sSelf; +	LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();  	if (!folder_bridge) return;  	LLViewerInventoryCategory *cat = folder_bridge->getCategory(); @@ -1874,13 +1874,18 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  		}  		// Successively filter out invalid options -		selected_items_t::iterator item_itor; +  		U32 flags = FIRST_SELECTED_ITEM; -		for (item_itor = mSelectedItems.begin(); item_itor != mSelectedItems.end(); ++item_itor) +		for (selected_items_t::iterator item_itor = mSelectedItems.begin();  +			 item_itor != mSelectedItems.end();  +			 ++item_itor)  		{ -			(*item_itor)->buildContextMenu(*menu, flags); +			LLFolderViewItem* selected_item = (*item_itor); +			selected_item->buildContextMenu(*menu, flags);  			flags = 0x0;  		} +	    +		addNoOptions(menu);  		menu->updateParent(LLMenuGL::sMenuContainer);  		LLMenuGL::showPopup(this, menu, x, y); @@ -1889,7 +1894,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  	}  	else  	{ -		if(menu && menu->getVisible()) +		if (menu && menu->getVisible())  		{  			menu->setVisible(FALSE);  		} @@ -1898,6 +1903,37 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  	return handled;  } +// Add "--no options--" if the menu is completely blank. +BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const +{ +	const std::string nooptions_str = "--no options--"; +	LLView *nooptions_item = NULL; +	 +	const LLView::child_list_t *list = menu->getChildList(); +	for (LLView::child_list_t::const_iterator itor = list->begin();  +		 itor != list->end();  +		 ++itor) +	{ +		LLView *menu_item = (*itor); +		if (menu_item->getVisible()) +		{ +			return FALSE; +		} +		std::string name = menu_item->getName(); +		if (menu_item->getName() == nooptions_str) +		{ +			nooptions_item = menu_item; +		} +	} +	if (nooptions_item) +	{ +		nooptions_item->setVisible(TRUE); +		nooptions_item->setEnabled(FALSE); +		return TRUE; +	} +	return FALSE; +} +  BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )  {  	return LLView::handleHover( x, y, mask ); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 55eb543f5f..24cd7b8018 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -262,6 +262,7 @@ public:  	BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }  	BOOL needsAutoRename() { return mNeedsAutoRename; }  	void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; } +	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }  	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } @@ -290,6 +291,8 @@ protected:  	bool selectFirstItem();  	bool selectLastItem(); +	BOOL addNoOptions(LLMenuGL* menu) const; +  protected:  	LLHandle<LLView>					mPopupMenuHandle; diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 996553ccf7..d464b67105 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -903,7 +903,15 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  			if (member_id.notNull())  			{ -				formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25 +				if (online_status == "Online") +				{ +					static std::string localized_online(LLTrans::getString("group_member_status_online")); +					online_status = localized_online; +				} +				else +				{ +					formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25 +				}  				//llinfos << "Member " << member_id << " has powers " << std::hex << agent_powers << std::dec << llendl;  				LLGroupMemberData* newdata = new LLGroupMemberData(member_id,  diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7ec6440dc3..38f3521b2d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -952,6 +952,8 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)  BOOL LLInvFVBridge::canShare() const  { +	if (!isAgentInventory()) return FALSE; +  	const LLInventoryModel* model = getInventoryModel();  	if (!model) return FALSE; @@ -963,9 +965,10 @@ BOOL LLInvFVBridge::canShare() const  		return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item);  	} -	// All categories can be given. -	const LLViewerInventoryCategory* cat = model->getCategory(mUUID); -	return (cat != NULL); +	// Categories can be given. +	if (model->getCategory(mUUID)) return TRUE; + +	return FALSE;  }  // +=================================================+ @@ -1444,7 +1447,7 @@ bool LLItemBridge::isRemoveAction(std::string action) const  // |        LLFolderBridge                           |  // +=================================================+ -LLFolderBridge* LLFolderBridge::sSelf=NULL; +LLHandle<LLFolderBridge> LLFolderBridge::sSelf;  // Can be moved to another folder  BOOL LLFolderBridge::isItemMovable() const @@ -2388,8 +2391,11 @@ void LLFolderBridge::pasteLinkFromClipboard()  void LLFolderBridge::staticFolderOptionsMenu()  { -	if (!sSelf) return; -	sSelf->folderOptionsMenu(); +	LLFolderBridge* selfp = sSelf.get(); +	if (selfp) +	{ +		selfp->folderOptionsMenu(); +	}  }  void LLFolderBridge::folderOptionsMenu() @@ -2466,11 +2472,15 @@ void LLFolderBridge::folderOptionsMenu()  		}  		mItems.push_back(std::string("Outfit Separator"));  	} -	hide_context_entries(*mMenu, mItems, disabled_items, TRUE); +	LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get()); +	if (menup) +	{ +		hide_context_entries(*menup, mItems, disabled_items, TRUE); -	// Reposition the menu, in case we're adding items to an existing menu. -	mMenu->needsArrange(); -	mMenu->arrangeAndClear(); +		// Reposition the menu, in case we're adding items to an existing menu. +		menup->needsArrange(); +		menup->arrangeAndClear(); +	}  }  BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type) @@ -2512,6 +2522,10 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		mDisabledItems.push_back(std::string("New Body Parts"));  	} +	// clear out old menu and folder pointers +	mMenu.markDead(); +	sSelf.markDead(); +  	if(trash_id == mUUID)  	{  		// This is the trash. @@ -2587,9 +2601,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		{  			mWearables=TRUE;  		} - -		mMenu = &menu; -		sSelf = this;  	}  	// Preemptively disable system folder removal if more than one item selected. @@ -2604,12 +2615,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		mDisabledItems.push_back(std::string("Share"));  	} -	if (mItems.empty()) -	{ -		mItems.push_back(std::string("--no options--")); -		mDisabledItems.push_back(std::string("--no options--")); -	} -  	hide_context_entries(menu, mItems, mDisabledItems);  	// Add menu items that are dependent on the contents of the folder. @@ -2619,6 +2624,9 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	{  		folders.push_back(category->getUUID());  	} + +	mMenu = menu.getHandle(); +	sSelf = getHandle();  	LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);  	fetch->startFetch();  	inc_busy_count(); @@ -4134,7 +4142,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  						}  						LLSD cbparams;  						cbparams["index"] = curiter->first; -						cbparams["label"] = attachment->getName(); +						cbparams["label"] = p.name;  						p.on_click.function_name = "Inventory.AttachObject";  						p.on_click.parameter = LLSD(attachment->getName());  						p.on_enable.function_name = "Attachment.Label"; diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 9dc50b542d..91055eb906 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -230,8 +230,8 @@ public:  				   const LLUUID& uuid) :  		LLInvFVBridge(inventory, root, uuid),  		mCallingCards(FALSE), -		mWearables(FALSE), -		mMenu(NULL) {} +		mWearables(FALSE) +	{}  	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop);  	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop); @@ -272,6 +272,7 @@ public:  	static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);  	LLViewerInventoryCategory* getCategory() const; +	LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }  protected:  	//-------------------------------------------------------------------- @@ -305,16 +306,17 @@ protected:  	// Messy hacks for handling folder options  	//--------------------------------------------------------------------  public: -	static LLFolderBridge* sSelf; +	static LLHandle<LLFolderBridge> sSelf;  	static void staticFolderOptionsMenu();  	void folderOptionsMenu();  private: -	BOOL			mCallingCards; -	BOOL			mWearables; -	LLMenuGL*		mMenu; -	menuentry_vec_t mItems; -	menuentry_vec_t mDisabledItems; +	BOOL				mCallingCards; +	BOOL				mWearables; +	LLHandle<LLView>	mMenu; +	menuentry_vec_t		mItems; +	menuentry_vec_t		mDisabledItems; +	LLRootHandle<LLFolderBridge> mHandle;  };  class LLTextureBridge : public LLItemBridge diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 2d11337955..ba357b2361 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -250,6 +250,18 @@ BOOL get_can_item_be_worn(const LLUUID& id)  	const LLViewerInventoryItem* item = gInventory.getItem(id);  	if (!item)  		return FALSE; + +	if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID())) +	{ +		// an item having links in COF (i.e. a worn item) +		return FALSE; +	} + +	if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF())) +	{ +		// a non-link object in COF (should not normally happen) +		return FALSE; +	}  	switch(item->getType())  	{ diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 3090371a73..2201481df3 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -117,6 +117,7 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,  	if (item_is_multi)  	{  		idx = ICONNAME_OBJECT_MULTI; +		return getIconName(idx);  	}  	switch(asset_type) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 236ed9bbd1..5a952bb6a8 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -294,6 +294,30 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id,  	items = get_ptr_in_map(mParentChildItemTree, cat_id);  } +LLMD5 LLInventoryModel::hashDirectDescendentNames(const LLUUID& cat_id) const +{ +	LLInventoryModel::cat_array_t* cat_array; +	LLInventoryModel::item_array_t* item_array; +	getDirectDescendentsOf(cat_id,cat_array,item_array); +	LLMD5 item_name_hash; +	if (!item_array) +	{ +		item_name_hash.finalize(); +		return item_name_hash; +	} +	for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin(); +		 iter != item_array->end(); +		 iter++) +	{ +		const LLViewerInventoryItem *item = (*iter); +		if (!item) +			continue; +		item_name_hash.update(item->getName()); +	} +	item_name_hash.finalize(); +	return item_name_hash; +} +  // SJB: Added version to lock the arrays to catch potential logic bugs  void LLInventoryModel::lockDirectDescendentArrays(const LLUUID& cat_id,  												  cat_array_t*& categories, @@ -1254,6 +1278,9 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category)  	//llinfos << "LLInventoryModel::addCategory()" << llendl;  	if(category)  	{ +		// try to localize default names first. See EXT-8319, EXT-7051. +		category->localizeName(); +  		// Insert category uniquely into the map  		mCategoryMap[category->getUUID()] = category; // LLPointer will deref and delete the old one  		//mInventory[category->getUUID()] = category; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 7b56d0bdd1..ff8a5bae9b 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -41,6 +41,7 @@  #include "lluuid.h"  #include "llpermissionsflags.h"  #include "llstring.h" +#include "llmd5.h"  #include <map>  #include <set>  #include <string> @@ -194,6 +195,9 @@ public:  	void getDirectDescendentsOf(const LLUUID& cat_id,  								cat_array_t*& categories,  								item_array_t*& items) const; + +	// Compute a hash of direct descendent names (for detecting child name changes) +	LLMD5 hashDirectDescendentNames(const LLUUID& cat_id) const;  	// Starting with the object specified, add its descendents to the  	// array provided, but do not add the inventory object specified diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index bd6877d9d3..5416f01033 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -676,7 +676,9 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		 iter != mCategoryMap.end();  		 ++iter)  	{ -		LLViewerInventoryCategory* category = gInventory.getCategory((*iter).first); +		const LLUUID& cat_id = (*iter).first; + +		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);  		if (!category)  			continue; @@ -691,7 +693,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		// Check number of known descendents to find out whether it has changed.  		LLInventoryModel::cat_array_t* cats;  		LLInventoryModel::item_array_t* items; -		gInventory.getDirectDescendentsOf((*iter).first, cats, items); +		gInventory.getDirectDescendentsOf(cat_id, cats, items);  		if (!cats || !items)  		{  			llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; @@ -703,20 +705,33 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  			continue;  		} - +		  		const S32 current_num_known_descendents = cats->count() + items->count();  		LLCategoryData cat_data = (*iter).second; +		bool cat_changed = false; +  		// If category version or descendents count has changed -		// update category data in mCategoryMap and fire a callback. +		// update category data in mCategoryMap  		if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount)  		{  			cat_data.mVersion = version;  			cat_data.mDescendentsCount = current_num_known_descendents; +			cat_changed = true; +		} -			cat_data.mCallback(); +		// If any item names have changed, update the name hash  +		LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id); +		if (cat_data.mItemNameHash != item_name_hash) +		{ +			cat_data.mItemNameHash = item_name_hash; +			cat_changed = true;  		} + +		// If anything has changed above, fire the callback. +		if (cat_changed) +			cat_data.mCallback();  	}  } diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 4a88a65bf8..ccd5fa5f4e 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -34,6 +34,7 @@  #define LL_LLINVENTORYOBSERVERS_H  #include "lluuid.h" +#include "llmd5.h"  #include <string>  #include <vector> @@ -298,11 +299,14 @@ protected:  		: mCallback(cb)  		, mVersion(version)  		, mDescendentsCount(num_descendents) -		{} +		{ +			mItemNameHash.finalize(); +		}  		callback_t	mCallback;  		S32			mVersion;  		S32			mDescendentsCount; +		LLMD5		mItemNameHash;  	};  	typedef	std::map<LLUUID, LLCategoryData>	category_map_t; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 5af99f3c8f..ac92f41624 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -790,7 +790,7 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata)  void LLInventoryPanel::doCreate(const LLSD& userdata)  { -	menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf, userdata); +	menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);  }  bool LLInventoryPanel::beginIMSession() diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 06f490e8e3..ae8efc01a3 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -58,6 +58,7 @@  #endif  #include "llsecapi.h"  #include "llstartup.h" +#include "llmachineid.h"  static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";  static const char * const TOS_LISTENER_NAME = "lllogininstance_tos"; @@ -165,22 +166,24 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia  	// (re)initialize the request params with creds.  	LLSD request_params = user_credential->getLoginParams(); -	char hashed_mac_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */ -	LLMD5 hashed_mac; -	unsigned char MACAddress[MAC_ADDRESS_BYTES]; -	if(LLUUID::getNodeID(MACAddress) == 0) { -		llerrs << "Failed to get node id; cannot uniquely identify this machine." << llendl; +	char hashed_unique_id_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */ +	LLMD5 hashed_unique_id; +	unsigned char unique_id[MAC_ADDRESS_BYTES]; +	if(LLUUID::getNodeID(unique_id) == 0) { +		if(LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) == 0) { +			llerrs << "Failed to get an id; cannot uniquely identify this machine." << llendl; +		}  	} -	hashed_mac.update( MACAddress, MAC_ADDRESS_BYTES ); -	hashed_mac.finalize(); -	hashed_mac.hex_digest(hashed_mac_string); +	hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES); +	hashed_unique_id.finalize(); +	hashed_unique_id.hex_digest(hashed_unique_id_string);  	request_params["start"] = construct_start_string();  	request_params["skipoptional"] = mSkipOptionalUpdate;  	request_params["agree_to_tos"] = false; // Always false here. Set true in   	request_params["read_critical"] = false; // handleTOSResponse  	request_params["last_exec_event"] = mLastExecEvent; -	request_params["mac"] = hashed_mac_string; +	request_params["mac"] = hashed_unique_id_string;  	request_params["version"] = gCurrentVersion; // Includes channel name  	request_params["channel"] = gSavedSettings.getString("VersionChannelName");  	request_params["id0"] = mSerialNumber; diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 6ae4a5e5e4..fc41137686 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -83,6 +83,16 @@ LLFloaterMove::LLFloaterMove(const LLSD& key)  {  } +LLFloaterMove::~LLFloaterMove() +{ +	// Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458. +	setVisible(FALSE); + +	// Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid. +	// Such situation was possible when LLFloaterReg returns "dead" instance of floater. +	// Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg. +} +  // virtual  BOOL LLFloaterMove::postBuild()  { diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index d463861188..43b0342744 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -51,7 +51,7 @@ class LLFloaterMove  private:  	LLFloaterMove(const LLSD& key); -	~LLFloaterMove() {} +	~LLFloaterMove();  public:  	/*virtual*/	BOOL	postBuild(); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index a300e15edd..8a52cf715f 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -317,9 +317,19 @@ void LLGestureComboList::refreshGestures()  	if (gestures)  	{ -		S32 index = gestures->getSelectedValue().asInteger(); -		if(index > 0) -			gesture = mGestures.at(index); +		S32 sel_index = gestures->getFirstSelectedIndex(); +		if (sel_index != 0) +		{ +			S32 index = gestures->getSelectedValue().asInteger(); +			if (index<0 || index >= (S32)mGestures.size()) +			{ +				llwarns << "out of range gesture access" << llendl; +			} +			else +			{ +				gesture = mGestures.at(index); +			} +		}  	}  	if(gesture && LLGestureMgr::instance().isGesturePlaying(gesture)) @@ -335,13 +345,13 @@ void LLGestureComboList::onCommitGesture()  	LLCtrlListInterface* gestures = getListInterface();  	if (gestures)  	{ -		S32 index = gestures->getFirstSelectedIndex(); -		if (index == 0) +		S32 sel_index = gestures->getFirstSelectedIndex(); +		if (sel_index == 0)  		{  			return;  		} -		index = gestures->getSelectedValue().asInteger(); +		S32 index = gestures->getSelectedValue().asInteger();  		if (mViewAllItemIndex == index)  		{ @@ -357,13 +367,20 @@ void LLGestureComboList::onCommitGesture()  			return;  		} -		LLMultiGesture* gesture = mGestures.at(index); -		if(gesture) +		if (index<0 || index >= (S32)mGestures.size()) +		{ +			llwarns << "out of range gesture index" << llendl; +		} +		else  		{ -			LLGestureMgr::instance().playGesture(gesture); -			if(!gesture->mReplaceText.empty()) +			LLMultiGesture* gesture = mGestures.at(index); +			if(gesture)  			{ -				LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE); +				LLGestureMgr::instance().playGesture(gesture); +				if(!gesture->mReplaceText.empty()) +				{ +					LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE); +				}  			}  		}  	} @@ -374,6 +391,13 @@ LLGestureComboList::~LLGestureComboList()  	LLGestureMgr::instance().removeObserver(this);  } +LLCtrlListInterface* LLGestureComboList::getListInterface() +{ +	LLCtrlListInterface *result = mList; +	llassert((LLCtrlListInterface*)mList==result); +	return mList; +}; +  LLNearbyChatBar::LLNearbyChatBar()   	: LLPanel()  	, mChatBox(NULL) diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 83c174fd10..0eaa60ce81 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -68,7 +68,7 @@ public:  	~LLGestureComboList(); -	LLCtrlListInterface* getListInterface()		{ return (LLCtrlListInterface*)mList; }; +	LLCtrlListInterface* getListInterface();  	virtual void	showList();  	virtual void	hideList();  	virtual BOOL	handleKeyHere(KEY key, MASK mask); diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp index 03414b9964..60c941b456 100644 --- a/indra/newview/lloutfitobserver.cpp +++ b/indra/newview/lloutfitobserver.cpp @@ -40,6 +40,7 @@  LLOutfitObserver::LLOutfitObserver() :  	mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)  { +	mItemNameHash.finalize();  	gInventory.addObserver(this);  } @@ -87,13 +88,24 @@ bool LLOutfitObserver::checkCOF()  	if (cof.isNull())  		return false; +	bool cof_changed = false; +	LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cof); +	if (item_name_hash != mItemNameHash) +	{ +		cof_changed = true; +		mItemNameHash = item_name_hash; +	} +  	S32 cof_version = getCategoryVersion(cof); +	if (cof_version != mCOFLastVersion) +	{ +		cof_changed = true; +		mCOFLastVersion = cof_version; +	} -	if (cof_version == mCOFLastVersion) +	if (!cof_changed)  		return false; - -	mCOFLastVersion = cof_version; - +	  	// dirtiness state should be updated before sending signal  	LLAppearanceMgr::getInstance()->updateIsDirty();  	mCOFChanged(); diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h index 3a66b5ea9f..4bb2b9b5ec 100644 --- a/indra/newview/lloutfitobserver.h +++ b/indra/newview/lloutfitobserver.h @@ -34,6 +34,7 @@  #define LL_OUTFITOBSERVER_H  #include "llsingleton.h" +#include "llmd5.h"  /**   * Outfit observer facade that provides simple possibility to subscribe on @@ -84,6 +85,8 @@ protected:  	bool mLastOutfitDirtiness; +	LLMD5 mItemNameHash; +  private:  	signal_t mBOFReplaced;  	signal_t mBOFChanged; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 63ffb80ff2..8147a97317 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -665,7 +665,18 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)  	}  	if (command_name == "wear")  	{ -		return !gAgentWearables.isCOFChangeInProgress(); +		if (gAgentWearables.isCOFChangeInProgress()) +		{ +			return false; +		} + +		if (hasItemSelected()) +		{ +			return canWearSelected(); +		} + +		// outfit selected +		return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);  	}  	if (command_name == "take_off")  	{ @@ -677,6 +688,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)  	if (command_name == "wear_add")  	{ +		// *TODO: do we ever get here?  		if (gAgentWearables.isCOFChangeInProgress())  		{  			return false; @@ -984,6 +996,26 @@ bool LLOutfitsList::canTakeOffSelected()  	return false;  } +bool LLOutfitsList::canWearSelected() +{ +	uuid_vec_t selected_items; +	getSelectedItemsUUIDs(selected_items); + +	for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it) +	{ +		const LLUUID& id = *it; + +		// Check whether the item is worn. +		if (!get_can_item_be_worn(id)) +		{ +			return false; +		} +	} + +	// All selected items can be worn. +	return true; +} +  void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)  {  	LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index d7cf8a8c08..206854b232 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -183,6 +183,11 @@ private:  	 */  	bool canTakeOffSelected(); +	/** +	 * Returns true if all selected items can be worn. +	 */ +	bool canWearSelected(); +  	void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);  	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);  	void onCOFChanged(); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 14f05bdb17..62e6cdc79d 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -47,6 +47,7 @@  #include "llvoavatarself.h"  #include "lltexteditor.h"  #include "lltextbox.h" +#include "llaccordionctrl.h"  #include "llaccordionctrltab.h"  #include "llagentwearables.h"  #include "llscrollingpanelparam.h" @@ -666,6 +667,35 @@ void LLPanelEditWearable::updateAvatarHeightLabel()  	mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);  } +void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl) +{ +	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL) +	{ +		accordion_ctrl->expandDefaultTab(); +	} +} + +void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel) +{ +	if (bodypart_panel != NULL) +	{ +		LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion"); + +		if (accordion_ctrl != NULL) +		{ +			bodypart_panel->setVisibleCallback( +					boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl)); +		} +		else +		{ +			llwarns << "accordion_ctrl is NULL" << llendl; +		} +	} +	else +	{ +		llwarns << "bodypart_panel is NULL" << llendl; +	} +}  // virtual   BOOL LLPanelEditWearable::postBuild() @@ -695,6 +725,14 @@ BOOL LLPanelEditWearable::postBuild()  	mPanelEyes = getChild<LLPanel>("edit_eyes_panel");  	mPanelHair = getChild<LLPanel>("edit_hair_panel"); +	// Setting the visibility callback is applied only to the bodyparts panel +	// because currently they are the only ones whose 'wearable_accordion' has +	// multiple accordion tabs (see EXT-8164 for details). +	setWearablePanelVisibilityChangeCallback(mPanelShape); +	setWearablePanelVisibilityChangeCallback(mPanelSkin); +	setWearablePanelVisibilityChangeCallback(mPanelEyes); +	setWearablePanelVisibilityChangeCallback(mPanelHair); +  	//clothes  	mPanelShirt = getChild<LLPanel>("edit_shirt_panel");  	mPanelPants = getChild<LLPanel>("edit_pants_panel"); @@ -786,7 +824,7 @@ BOOL LLPanelEditWearable::isDirty() const  	if (mWearablePtr)  	{  		if (mWearablePtr->isDirty() || -			mWearablePtr->getName().compare(mNameEditor->getText()) != 0) +			mWearableItem->getName().compare(mNameEditor->getText()) != 0)  		{  			isDirty = TRUE;  		} @@ -839,7 +877,7 @@ void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& r  		if( !wearable_name.empty() )  		{  			mNameEditor->setText(wearable_name); -			saveChanges(); +			saveChanges(true);  		}  	}  } @@ -896,7 +934,7 @@ void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)  		{  			// Set the new version  			LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID()); -			if( image->getID().isNull() ) +			if( image->getID() == IMG_DEFAULT )  			{  				image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);  			} @@ -971,7 +1009,7 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)  	}  } -void LLPanelEditWearable::saveChanges() +void LLPanelEditWearable::saveChanges(bool force_save_as)  {  	if (!mWearablePtr || !isDirty())  	{ @@ -980,16 +1018,18 @@ void LLPanelEditWearable::saveChanges()  	}  	U32 index = gAgentWearables.getWearableIndex(mWearablePtr); -	 -	if (mWearablePtr->getName().compare(mNameEditor->getText()) != 0) + +	std::string new_name = mNameEditor->getText(); +	if (force_save_as)  	{  		// the name of the wearable has changed, re-save wearable with new name  		LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false); -		gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, mNameEditor->getText(), FALSE); +		gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE); +		mNameEditor->setText(mWearableItem->getName());  	}  	else  	{ -		gAgentWearables.saveWearable(mWearablePtr->getType(), index); +		gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);  	}  } @@ -1002,7 +1042,7 @@ void LLPanelEditWearable::revertChanges()  	}  	mWearablePtr->revertValues(); -	mNameEditor->setText(mWearablePtr->getName()); +	mNameEditor->setText(mWearableItem->getName());  	updatePanelPickerControls(mWearablePtr->getType());  	updateTypeSpecificControls(mWearablePtr->getType());  	gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE); @@ -1048,7 +1088,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)  		mDescTitle->setText(description_title);  		// set name -		mNameEditor->setText(wearable->getName()); +		mNameEditor->setText(mWearableItem->getName());  		updatePanelPickerControls(type);  		updateTypeSpecificControls(type); diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index bfce2ae56e..c0823dd3fa 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -39,6 +39,7 @@  #include "llvoavatardefines.h"  #include "llwearabletype.h" +class LLAccordionCtrl;  class LLCheckBoxCtrl;  class LLWearable;  class LLTextBox; @@ -63,7 +64,7 @@ public:  	LLWearable* 		getWearable() { return mWearablePtr; }  	void				setWearable(LLWearable *wearable); -	void				saveChanges(); +	void				saveChanges(bool force_save_as = false);  	void				revertChanges();  	void				showDefaultSubpart(); @@ -113,6 +114,10 @@ private:  	// updates avatar height label  	void updateAvatarHeightLabel(); +	void onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl); + +	void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel); +  	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.  	LLWearable *mWearablePtr;  	LLViewerInventoryItem* mWearableItem; diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index d997b83cbb..38e776b195 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -182,6 +182,11 @@ BOOL LLPanelGroup::postBuild()  	LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");  	LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel"); +	if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion")) +	{ +		setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl)); +	} +  	if(panel_general)	mTabs.push_back(panel_general);  	if(panel_roles)		mTabs.push_back(panel_roles);  	if(panel_notices)	mTabs.push_back(panel_notices); @@ -305,6 +310,13 @@ void LLPanelGroup::onBtnCancel()  	onBackBtnClick();  } +void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl) +{ +	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL) +	{ +		accordion_ctrl->expandDefaultTab(); +	} +}  void LLPanelGroup::changed(LLGroupChange gc)  { diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 13a03b0713..2b21e9895a 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -42,6 +42,7 @@ class LLOfferInfo;  const S32 UPDATE_MEMBERS_PER_FRAME = 500;  // Forward declares +class LLAccordionCtrl;  class LLPanelGroupTab;  class LLTabContainer;  class LLAgent; @@ -102,6 +103,7 @@ protected:  	void onBackBtnClick();  	void onBtnJoin();  	void onBtnCancel(); +	void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);  	static void onBtnApply(void*);  	static void onBtnRefresh(void*); @@ -126,7 +128,6 @@ protected:  	LLButton*		mButtonJoin;  	LLUICtrl*		mJoinText; -  };  class LLPanelGroupTab : public LLPanel diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 65fe7165c2..b7d6b65ce5 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -1432,10 +1432,10 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,  // 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));  // 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits,  (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members))); -	text.append( "                      Group\n"); -	text.append(llformat( "%-24s %6d\n", "Credits", total_credits)); -	text.append(llformat( "%-24s %6d\n", "Debits", total_debits)); -	text.append(llformat( "%-24s %6d\n", "Total", total_credits + total_debits)); +	text.append(llformat( "%s\n", LLTrans::getString("GroupColumn").c_str())); +	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits)); +	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits)); +	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits));  	if ( mImplementationp->mTextEditorp )  	{ diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 26e8a932aa..7a28d10baf 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -51,6 +51,7 @@  #include "lltabcontainer.h"  #include "lltextbox.h"  #include "lltexteditor.h" +#include "lltrans.h"  #include "llviewertexturelist.h"  #include "llviewerwindow.h"  #include "llfocusmgr.h" @@ -587,7 +588,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,  		row["columns"][1]["column"] = "action";  		row["columns"][1]["type"] = "text"; -		row["columns"][1]["value"] = action_set->mActionSetData->mName; +		row["columns"][1]["value"] = LLTrans::getString(action_set->mActionSetData->mName);  		row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL"; @@ -1593,6 +1594,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  	LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); +	LLUIString donated = getString("donation_area");  	S32 i = 0;  	for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME;  @@ -1614,9 +1616,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  		if (add_member)  		{ -			// Build the donated tier string. -			std::ostringstream donated; -			donated << mMemberProgress->second->getContribution() << " sq. m."; +			donated.setArg("[AREA]", llformat("%d", mMemberProgress->second->getContribution()));  			LLSD row;  			row["id"] = (*mMemberProgress).first; @@ -1625,7 +1625,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  			// value is filled in by name list control  			row["columns"][1]["column"] = "donated"; -			row["columns"][1]["value"] = donated.str(); +			row["columns"][1]["value"] = donated.getString();  			row["columns"][2]["column"] = "online";  			row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 29ce3449d1..17ec0d3a56 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -566,7 +566,8 @@ void LLPanelMainInventory::draw()  void LLPanelMainInventory::updateItemcountText()  { -	LLLocale locale(LLLocale::USER_LOCALE); +	// *TODO: Calling setlocale() on each frame may be inefficient. +	LLLocale locale(LLStringUtil::getLocale());  	std::string item_count_string;  	LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount()); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index ca1361c84b..116e5ba4cb 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -750,8 +750,6 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  {  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	items.push_back(std::string("--no options--")); -	disabled_items.push_back(std::string("--no options--"));  	hide_context_entries(menu, items, disabled_items);  } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index f8350a56ef..5195b719d4 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -923,6 +923,18 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch  	return false;  } +void LLPanelOutfitEdit::resetAccordionState() +{ +	if (mCOFWearables != NULL) +	{ +		mCOFWearables->expandDefaultAccordionTab(); +	} +	else +	{ +		llwarns << "mCOFWearables is NULL" << llendl; +	} +} +  void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)  {  	if(!mGearMenu) diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index fb9a35411c..5009de0fef 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -182,6 +182,8 @@ public:  	 */  	bool switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel); +	void resetAccordionState(); +  	virtual BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  									  EDragAndDropType cargo_type,  									  void* cargo_data, diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index ca5679d5b0..16ef7998b3 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -337,7 +337,7 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const  void LLPanelOutfitsInventory::setWearablesLoading(bool val)  { -	mListCommands->childSetEnabled("wear_btn", !val); +	updateVerbs();  }  void LLPanelOutfitsInventory::onWearablesLoaded() diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 8c1f5d0915..99e48cca6d 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -60,7 +60,8 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()  	mScrollingPanelWidth(0),  	mInfoType(UNKNOWN),  	mScrollingPanel(NULL), -	mScrollContainer(NULL) +	mScrollContainer(NULL), +	mDescEditor(NULL)  {}  //virtual @@ -248,6 +249,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  // virtual  void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)  { + +	// This if was added to force collapsing description textbox on Windows at the beginning of reshape +	// (the only case when reshape is skipped here is when it's caused by this textbox, so called_from_parent is FALSE) +	// This way it is consistent with Linux where topLost collapses textbox at the beginning of reshape. +	// On windows it collapsed only after reshape which caused EXT-8342. +	if(called_from_parent) +	{ +		if(mDescEditor) mDescEditor->onTopLost(); +	} +  	LLPanel::reshape(width, height, called_from_parent);  	if (!mScrollContainer || !mScrollingPanel) diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 1f979b0ef1..08835dc2b8 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -79,7 +79,8 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()  :	LLPanelPlaceInfo(),  	mForSalePanel(NULL),  	mYouAreHerePanel(NULL), -	mSelectedParcelID(-1) +	mSelectedParcelID(-1), +	mAccordionCtrl(NULL)  {}  // virtual @@ -139,6 +140,7 @@ BOOL LLPanelPlaceProfile::postBuild()  	mSubdivideText = getChild<LLTextEditor>("subdivide");  	mResaleText = getChild<LLTextEditor>("resale");  	mSaleToText = getChild<LLTextBox>("sale_to"); +	mAccordionCtrl = getChild<LLAccordionCtrl>("advanced_info_accordion");  	icon_pg = getString("icon_PG");  	icon_m = getString("icon_M"); @@ -278,6 +280,11 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)  			parcel_mgr->deselectUnused();  		}  	} + +	if (mAccordionCtrl != NULL) +	{ +		mAccordionCtrl->expandDefaultTab(); +	}  }  void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index e77b441567..49c13ff5e3 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -35,6 +35,7 @@  #include "llpanelplaceinfo.h" +class LLAccordionCtrl;  class LLIconCtrl;  class LLTextEditor; @@ -118,6 +119,7 @@ private:  	LLTextEditor*		mSubdivideText;  	LLTextEditor*		mResaleText;  	LLTextBox*			mSaleToText; +	LLAccordionCtrl*	mAccordionCtrl;  };  #endif // LL_LLPANELPLACEPROFILE_H diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 705b196ef1..c713bc3965 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -718,8 +718,8 @@ void LLPanelPlaces::onOverflowButtonClicked()  	bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;  	if ((is_agent_place_info_visible || -		 mPlaceInfoType == "remote_place" || -		 mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL) +		 mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || +		 mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) && mPlaceMenu != NULL)  	{  		menu = mPlaceMenu; @@ -1089,6 +1089,8 @@ void LLPanelPlaces::updateVerbs()  	if (is_place_info_visible)  	{ +		mShowOnMapBtn->setEnabled(have_3d_pos); +  		if (is_agent_place_info_visible)  		{  			// We don't need to teleport to the current location diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp index f59a55cb8b..18a91b0eb0 100644 --- a/indra/newview/llplacesinventorybridge.cpp +++ b/indra/newview/llplacesinventorybridge.cpp @@ -115,7 +115,7 @@ void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601   		// repeat parent functionality - 		sSelf = this; // necessary for "New Folder" functionality + 		sSelf = getHandle(); // necessary for "New Folder" functionality  		hide_context_entries(menu, items, disabled_items);  	} diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index a7b4873fed..6f9d8a7623 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -1625,7 +1625,17 @@ std::string LLPreviewGesture::getLabel(std::vector<std::string> labels)  		result=LLTrans::getString("AnimFlagStart");  	} -	result.append(v_labels[1]); +	// lets localize action value +	std::string action = v_labels[1]; +	if ("None" == action) +	{ +		action = LLTrans::getString("GestureActionNone"); +	} +	else if ("until animations are done" == action) +	{ +		action = LLFloaterReg::getInstance("preview_gesture")->getChild<LLCheckBoxCtrl>("wait_anim_check")->getLabel(); +	} +	result.append(action);  	return result;  } diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index bf18c9e5e7..ef6ceb5f2e 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -87,7 +87,7 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)  LLPreviewTexture::~LLPreviewTexture()  { -	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList, this) ; +	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;  	if( mLoadingFullImage )  	{ @@ -280,7 +280,7 @@ void LLPreviewTexture::saveAs()  	mLoadingFullImage = TRUE;  	getWindow()->incBusyCount();  	mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave,  -								0, TRUE, FALSE, new LLUUID( mItemUUID ), this, &mCallbackTextureList ); +								0, TRUE, FALSE, new LLUUID( mItemUUID ), &mCallbackTextureList );  }  // virtual diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 7a7ffb9983..98cd0b88eb 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -190,13 +190,16 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)  {  	if (new_visibility.asBoolean())  	{ -		if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible())) +		bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible(); +		bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible(); + +		if (is_outfit_edit_visible || is_wearable_edit_visible)  		{  			if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))  			{  				gAgentCamera.changeCameraToCustomizeAvatar();  			} -			if (mEditWearable && mEditWearable->getVisible()) +			if (is_wearable_edit_visible)  			{  				LLWearable *wearable_ptr = mEditWearable->getWearable();  				if (gAgentWearables.getWearableIndex(wearable_ptr) == LLAgentWearables::MAX_CLOTHING_PER_TYPE) @@ -205,6 +208,11 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)  					showOutfitEditPanel();  				}  			} + +			if (is_outfit_edit_visible) +			{ +				mOutfitEdit->resetAccordionState(); +			}  		}  	}  	else @@ -283,6 +291,15 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()  void LLSidepanelAppearance::showOutfitEditPanel()  { +	// Accordion's state must be reset in all cases except the one when user +	// is returning back to the mOutfitEdit panel from the mEditWearable panel. +	// The simplest way to control this is to check the visibility state of the mEditWearable +	// BEFORE it is changed by the call to the toggleWearableEditPanel(FALSE, NULL, TRUE). +	if (mEditWearable != NULL && !mEditWearable->getVisible() && mOutfitEdit != NULL) +	{ +		mOutfitEdit->resetAccordionState(); +	} +  	togglMyOutfitsPanel(FALSE);  	toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode  	toggleOutfitEditPanel(TRUE); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index de59af49da..0951586dd5 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -33,10 +33,13 @@  #include "llsidepanelinventory.h"  #include "llagent.h" +#include "llappearancemgr.h"  #include "llavataractions.h"  #include "llbutton.h"  #include "llinventorybridge.h" +#include "llinventoryfunctions.h"  #include "llinventorypanel.h" +#include "lloutfitobserver.h"  #include "llpanelmaininventory.h"  #include "llsidepaneliteminfo.h"  #include "llsidepaneltaskinfo.h" @@ -98,6 +101,8 @@ BOOL LLSidepanelInventory::postBuild()  		my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK);  		my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE);  		*/ + +		LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));  	}  	// UI elements from item panel @@ -283,7 +288,7 @@ void LLSidepanelInventory::updateVerbs()  		case LLInventoryType::IT_OBJECT:  		case LLInventoryType::IT_ATTACHMENT:  			mWearBtn->setVisible(TRUE); -			mWearBtn->setEnabled(TRUE); +			mWearBtn->setEnabled(get_can_item_be_worn(item->getLinkedUUID()));  		 	mShopBtn->setVisible(FALSE);  			break;  		case LLInventoryType::IT_SOUND: diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index 010173e84e..99d0603ec5 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -121,7 +121,7 @@ private:  protected:  	LLViewerObject*				getObject();  private: -	LLViewerObject*				mObject; +	LLPointer<LLViewerObject>	mObject;  	LLObjectSelectionHandle		mObjectSelection;  	static LLSidepanelTaskInfo* sActivePanel;  }; diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index ddb5d08e07..cecc135951 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -158,6 +158,7 @@ void LLSurface::initClasses()  void LLSurface::setRegion(LLViewerRegion *regionp)  {  	mRegionp = regionp; +	mWaterObjp = NULL; // depends on regionp, needs recreating  }  // Assumes that arguments are powers of 2, and that @@ -958,6 +959,7 @@ LLSurfacePatch *LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const  LLSurfacePatch *LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const  { +	llassert(mRegionp);  	LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global);  	return resolvePatchRegion(pos_region);  } diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 46bd55de43..f4f8241b99 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -119,14 +119,16 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,  										 S32 width, S32 height) :  	// ORDER_LAST => must render these after the hints are created.  	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),  -	mNeedsUpdate(TRUE), -	mNeedsUpload(FALSE),  	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates +	mNeedsUpload(FALSE),  	mNumLowresUploads(0), +	mNeedsUpdate(TRUE), +	mNumLowresUpdates(0),  	mTexLayerSet(owner)  {  	LLTexLayerSetBuffer::sGLByteCount += getSize();  	mNeedsUploadTimer.start(); +	mNeedsUpdateTimer.start();  }  LLTexLayerSetBuffer::~LLTexLayerSetBuffer() @@ -165,8 +167,9 @@ void LLTexLayerSetBuffer::dumpTotalByteCount()  void LLTexLayerSetBuffer::requestUpdate()  { -	conditionalRestartUploadTimer(); +	restartUpdateTimer();  	mNeedsUpdate = TRUE; +	mNumLowresUpdates = 0;  	// 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.  	mUploadID.setNull(); @@ -196,6 +199,12 @@ void LLTexLayerSetBuffer::conditionalRestartUploadTimer()  	}  } +void LLTexLayerSetBuffer::restartUpdateTimer() +{ +	mNeedsUpdateTimer.reset(); +	mNeedsUpdateTimer.start(); +} +  void LLTexLayerSetBuffer::cancelUpload()  {  	mNeedsUpload = FALSE; @@ -229,25 +238,31 @@ BOOL LLTexLayerSetBuffer::needsRender()  	llassert(mTexLayerSet->getAvatar() == gAgentAvatarp);  	if (!isAgentAvatarValid()) return FALSE; -	const BOOL upload_now = isReadyToUpload(); -	BOOL needs_update = (mNeedsUpdate || upload_now) && !gAgentAvatarp->mAppearanceAnimating; -	if (needs_update) +	const BOOL upload_now = mNeedsUpload && isReadyToUpload(); +	const BOOL update_now = mNeedsUpdate && isReadyToUpdate(); + +	// Don't render if we don't want to (or aren't ready to) upload or update. +	if (!(update_now || upload_now))  	{ -		BOOL invalid_skirt = gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT); -		if (invalid_skirt) -		{ -			// we were trying to create a skirt texture -			// but we're no longer wearing a skirt... -			needs_update = FALSE; -			cancelUpload(); -		} -		else -		{ -			needs_update &= mTexLayerSet->isLocalTextureDataAvailable(); -		} +		return FALSE; +	} + +	// Don't render if we're animating our appearance. +	if (gAgentAvatarp->getIsAppearanceAnimating()) +	{ +		return FALSE;  	} -	return needs_update; +	// Don't render if we are trying to create a shirt texture but aren't wearing a skirt. +	if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED &&  +		!gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT)) +	{ +		cancelUpload(); +		return FALSE; +	} + +	// Render if we have at least minimal level of detail for each local texture. +	return mTexLayerSet->isLocalTextureDataAvailable();  }  void LLTexLayerSetBuffer::preRender(BOOL clear_depth) @@ -272,11 +287,12 @@ BOOL LLTexLayerSetBuffer::render()  	gGL.setColorMask(true, true);  	// do we need to upload, and do we have sufficient data to create an uploadable composite? -	// When do we upload the texture if gAgent.mNumPendingQueries is non-zero? -	const BOOL upload_now = isReadyToUpload(); +	// TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero? +	const BOOL upload_now = mNeedsUpload && isReadyToUpload(); +	const BOOL update_now = mNeedsUpdate && isReadyToUpdate(); +	  	BOOL success = TRUE; -  	// Composite the color data  	LLGLSUIDefault gls_ui;  	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight ); @@ -294,7 +310,7 @@ BOOL LLTexLayerSetBuffer::render()  			if (mTexLayerSet->isVisible())  			{  				mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish. -				readBackAndUpload(); +				doUpload();  			}  			else  			{ @@ -305,6 +321,11 @@ BOOL LLTexLayerSetBuffer::render()  			}  		}  	} +	 +	if (update_now) +	{ +		doUpdate(); +	}  	// reset GL state  	gGL.setColorMask(true, true); @@ -312,7 +333,6 @@ BOOL LLTexLayerSetBuffer::render()  	// we have valid texture data now  	mGLTexturep->setGLTextureCreated(true); -	mNeedsUpdate = FALSE;  	return success;  } @@ -339,16 +359,16 @@ BOOL LLTexLayerSetBuffer::uploadInProgress() const  BOOL LLTexLayerSetBuffer::isReadyToUpload() const  { -	if (!mNeedsUpload) return FALSE; // Don't need to upload if we haven't requested one.  	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.  	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites.  	// If we requested an upload and have the final LOD ready, then upload. -	const BOOL can_highest_lod = mTexLayerSet->isLocalTextureDataFinal(); -	if (can_highest_lod) return TRUE; +	if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE; -	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout"); -	if (texture_timeout) +	// Upload if we've hit a timeout.  Upload is a pretty expensive process so we need to make sure +	// we aren't doing uploads too frequently. +	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout"); +	if (texture_timeout != 0)  	{  		// The timeout period increases exponentially between every lowres upload in order to prevent  		// spamming the server with frequent uploads. @@ -359,10 +379,33 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const  		const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();  		if (has_lower_lod && is_upload_textures_timeout) return TRUE;   	} +  	return FALSE;  } -BOOL LLTexLayerSetBuffer::updateImmediate() +BOOL LLTexLayerSetBuffer::isReadyToUpdate() const +{ +	// If we requested an update and have the final LOD ready, then update. +	if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE; + +	// If we haven't done an update yet, then just do one now regardless of state of textures. +	if (mNumLowresUpdates == 0) return TRUE; + +	// Update if we've hit a timeout.  Unlike for uploads, we can make this timeout fairly small +	// since render unnecessarily doesn't cost much. +	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout"); +	if (texture_timeout != 0) +	{ +		// If we hit our timeout and have textures available at even lower resolution, then update. +		const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout; +		const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable(); +		if (has_lower_lod && is_update_textures_timeout) return TRUE;  +	} + +	return FALSE; +} + +BOOL LLTexLayerSetBuffer::requestUpdateImmediate()  {  	mNeedsUpdate = TRUE;  	BOOL result = FALSE; @@ -377,7 +420,9 @@ BOOL LLTexLayerSetBuffer::updateImmediate()  	return result;  } -void LLTexLayerSetBuffer::readBackAndUpload() +// Create the baked texture, send it out to the server, then wait for it to come +// back so we can switch to using it. +void LLTexLayerSetBuffer::doUpload()  {  	llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;  	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); @@ -447,6 +492,7 @@ void LLTexLayerSetBuffer::readBackAndUpload()  				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp,   																			 this->mTexLayerSet,   																			 asset_id); +				// upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.  				mUploadID = asset_id;  				// Upload the image @@ -490,12 +536,13 @@ void LLTexLayerSetBuffer::readBackAndUpload()  				// Print out notification that we uploaded this texture.  				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))  				{ -					std::string lod_str = highest_lod ? "HighRes" : "LowRes"; +					const std::string lod_str = highest_lod ? "HighRes" : "LowRes";  					LLSD args;  					args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());  					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());  					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();  					args["RESOLUTION"] = lod_str; +					args["ACTION"] = "uploaded";  					LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args);  					llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;  				} @@ -520,6 +567,37 @@ void LLTexLayerSetBuffer::readBackAndUpload()  	delete [] baked_color_data;  } +// Mostly bookkeeping; don't need to actually "do" anything since +// render() will actually do the update. +void LLTexLayerSetBuffer::doUpdate() +{ +	const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal(); +	if (highest_lod) +	{ +		mNeedsUpdate = FALSE; +	} +	else +	{ +		mNumLowresUpdates++; +	} + +	restartUpdateTimer(); +	 +	// Print out notification that we uploaded this texture. +	if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +	{ +		const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal(); +		const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; +		LLSD args; +		args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32()); +		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32()); +		args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); +		args["RESOLUTION"] = lod_str; +		args["ACTION"] = "locally updated"; +		LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args); +		llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl; +	} +}  // static  void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, @@ -931,7 +1009,7 @@ void LLTexLayerSet::setUpdatesEnabled( BOOL b )  void LLTexLayerSet::updateComposite()  {  	createComposite(); -	mComposite->updateImmediate(); +	mComposite->requestUpdateImmediate();  }  LLTexLayerSetBuffer* LLTexLayerSet::getComposite() diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index cb2e1faaa6..745cd88c47 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -270,47 +270,69 @@ class LLTexLayerSetBuffer : public LLViewerDynamicTexture  public:  	LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);  	virtual ~LLTexLayerSetBuffer(); -	/*virtual*/ S8          getType() const; -	virtual void			preRender(BOOL clear_depth); -	virtual void			postRender(BOOL success); -	virtual BOOL			render(); -	BOOL					updateImmediate(); +public: +	/*virtual*/ S8          getType() 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 +	static void				dumpTotalByteCount(); +	const std::string		dumpTextureInfo() const; +	virtual void 			restoreGLTexture(); +	virtual void 			destroyGLTexture(); +protected: +	void					pushProjection() const; +	void					popProjection() const; +private: +	LLTexLayerSet* const    mTexLayerSet; +	static S32				sGLByteCount; +	//-------------------------------------------------------------------- +	// Render +	//-------------------------------------------------------------------- +public:  	/*virtual*/ BOOL		needsRender(); -	void					requestUpdate(); +protected: +	BOOL					render(S32 x, S32 y, S32 width, S32 height); +	virtual void			preRender(BOOL clear_depth); +	virtual void			postRender(BOOL success); +	virtual BOOL			render();	 +	 +	//-------------------------------------------------------------------- +	// Uploads +	//-------------------------------------------------------------------- +public:  	void					requestUpload();  	void					cancelUpload(); -	BOOL					render(S32 x, S32 y, S32 width, S32 height); -	void					readBackAndUpload(); +	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 +	BOOL					uploadPending() const; 			// We are expecting a new texture to be uploaded at some point  	static void				onTextureUploadComplete(const LLUUID& uuid,  													void* userdata,  													S32 result, LLExtStat ext_status); -	static void				dumpTotalByteCount(); -	const std::string		dumpTextureInfo() const; -	virtual void 			restoreGLTexture(); -	virtual void 			destroyGLTexture(); - -  protected: -	void					pushProjection() const; -	void					popProjection() const;  	BOOL					isReadyToUpload() const; +	void					doUpload(); 					// Does a read back and upload.  	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; // 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; -	LLFrameTimer    		mNeedsUploadTimer; // Tracks time since upload was requested +	BOOL					mNeedsUpload; 					// Whether we need to send 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). +	LLFrameTimer    		mNeedsUploadTimer; 				// Tracks time since upload was requested and performed. + +	//-------------------------------------------------------------------- +	// Updates +	//-------------------------------------------------------------------- +public: +	void					requestUpdate(); +	BOOL					requestUpdateImmediate(); +protected: +	BOOL					isReadyToUpdate() const; +	void					doUpdate(); +	void					restartUpdateTimer(); +private: +	BOOL					mNeedsUpdate; 					// Whether we need to locally update our baked textures +	U32						mNumLowresUpdates; 				// Number of times we've locally updated with lowres version of our baked textures +	LLFrameTimer    		mNeedsUpdateTimer; 				// Tracks time since update was requested and performed.  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp index f2d1b5d032..dc97c4b673 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/newview/lltexlayerparams.cpp @@ -180,7 +180,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)  		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.  		{ -			if (gAgentCamera.cameraCustomizeAvatar()) +			if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  			{  				upload_bake = FALSE;  			} diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 9ad2322765..403692951f 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -391,6 +391,7 @@ bool LLTextureCacheRemoteWorker::doRead()  		}  		else  		{ +			//llinfos << "texture " << mID.asString() << " found in local_assets" << llendl;  			mImageSize = local_size;  			mImageLocal = TRUE;  		} diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index fcb9deb20b..d324cb1565 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -175,6 +175,8 @@ protected:  	BOOL				mNoCopyTextureSelected;  	F32					mContextConeOpacity;  	LLSaveFolderState	mSavedFolderState; + +	BOOL				mSelectedItemPinned;  };  LLFloaterTexturePicker::LLFloaterTexturePicker(	 @@ -197,7 +199,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(  	mFilterEdit(NULL),  	mImmediateFilterPermMask(immediate_filter_perm_mask),  	mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), -	mContextConeOpacity(0.f) +	mContextConeOpacity(0.f), +	mSelectedItemPinned( FALSE )  {  	mCanApplyImmediately = can_apply_immediately;  	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL); @@ -593,6 +596,31 @@ void LLFloaterTexturePicker::draw()  			mTentativeLabel->setVisible( TRUE );  			drawChild(mTentativeLabel);  		} + +		if (mSelectedItemPinned) return; + +		LLFolderView* folder_view = mInventoryPanel->getRootFolder(); +		if (!folder_view) return; + +		LLInventoryFilter* filter = folder_view->getFilter(); +		if (!filter) return; + +		bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() && +				filter->isNotDefault(); + +		// After inventory panel filter is applied we have to update +		// constraint rect for the selected item because of folder view +		// AutoSelectOverride set to TRUE. We force PinningSelectedItem +		// flag to FALSE state and setting filter "dirty" to update +		// scroll container to show selected item (see LLFolderView::doIdle()). +		if (!is_filter_active && !mSelectedItemPinned) +		{ +			folder_view->setPinningSelectedItem(mSelectedItemPinned); +			folder_view->dirtyFilter(); +			folder_view->arrangeFromRoot(); + +			mSelectedItemPinned = TRUE; +		}  	}  } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index ceed90e210..dddfed097d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -290,8 +290,8 @@ class HTTPGetResponder : public LLCurl::Responder  {  	LOG_CLASS(HTTPGetResponder);  public: -	HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset) -		: mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset) +	HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir) +		: mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir)  	{  	}  	~HTTPGetResponder() @@ -344,6 +344,11 @@ public:   			llwarns << "Worker not found: " << mID << llendl;  		}  	} + +	virtual bool followRedir() +	{ +		return mFollowRedir; +	}  private:  	LLTextureFetch* mFetcher; @@ -351,6 +356,7 @@ private:  	U64 mStartTime;  	S32 mRequestedSize;  	U32 mOffset; +	bool mFollowRedir;  };  ////////////////////////////////////////////////////////////////////////////// @@ -897,7 +903,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				std::vector<std::string> headers;  				headers.push_back("Accept: image/x-j2c");  				res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, -															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset)); +															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));  			}  			if (!res)  			{ @@ -945,17 +951,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  					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; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 8ea4dbeb04..b588ff91d1 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -450,14 +450,14 @@ void LLAvatarTexBar::draw()  												 text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);  		line_num++;  	} -	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout"); +	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");  	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()); +	std::string header_text = llformat("[ Timeout('AvatarBakedTextureUploadTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());  	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++; diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index fa21b1a866..81559429b0 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -147,7 +147,7 @@ void LLVisualParamHint::requestHintUpdates( LLVisualParamHint* exception1, LLVis  BOOL LLVisualParamHint::needsRender()  { -	return mNeedsUpdate && mDelayFrames-- <= 0 && !gAgentAvatarp->mAppearanceAnimating && mAllowsUpdates; +	return mNeedsUpdate && mDelayFrames-- <= 0 && !gAgentAvatarp->getIsAppearanceAnimating() && mAllowsUpdates;  }  void LLVisualParamHint::preRender(BOOL clear_depth) diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp index f7f5ec72fd..f683bd8674 100644 --- a/indra/newview/llviewerattachmenu.cpp +++ b/indra/newview/llviewerattachmenu.cpp @@ -84,7 +84,7 @@ void LLViewerAttachMenu::populateMenus(const std::string& attach_to_menu_name, c  		LLSD cbparams;  		cbparams["index"] = curiter->first; -		cbparams["label"] = attachment->getName(); +		cbparams["label"] = p.name;  		p.on_click.function_name = "Object.Attach";  		p.on_click.parameter = LLSD(attachment->getName());  		p.on_enable.function_name = "Attachment.Label"; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 1ff4d6db9e..7e8f11c41a 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -67,7 +67,7 @@  #include "llsidepanelappearance.h"  ///---------------------------------------------------------------------------- -/// Helper class to store special inventory item names  +/// Helper class to store special inventory item names and their localized values.  ///----------------------------------------------------------------------------  class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInventoryItemsDictionary>  { @@ -93,8 +93,10 @@ public:  		mInventoryItemsDict["New Tattoo"]		= LLTrans::getString("New Tattoo");  		mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); +		mInventoryItemsDict["New Gesture"]		= LLTrans::getString("New Gesture");  		mInventoryItemsDict["New Script"]		= LLTrans::getString("New Script");  		mInventoryItemsDict["New Folder"]		= LLTrans::getString("New Folder"); +		mInventoryItemsDict["New Note"]			= LLTrans::getString("New Note");  		mInventoryItemsDict["Contents"]			= LLTrans::getString("Contents");  		mInventoryItemsDict["Gesture"]			= LLTrans::getString("Gesture"); @@ -108,7 +110,7 @@ public:  		//male  		mInventoryItemsDict["Male - Excuse me"]			= LLTrans::getString("Male - Excuse me"); -		mInventoryItemsDict["Male - Get lost"]			= LLTrans::getString("Male - Get lost"); +		mInventoryItemsDict["Male  - Get lost"]			= LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319  		mInventoryItemsDict["Male - Blow kiss"]			= LLTrans::getString("Male - Blow kiss");  		mInventoryItemsDict["Male - Boo"]				= LLTrans::getString("Male - Boo");  		mInventoryItemsDict["Male - Bored"]				= LLTrans::getString("Male - Bored"); @@ -120,19 +122,47 @@ public:  		mInventoryItemsDict["Male - Wow"]				= LLTrans::getString("Male - Wow");  		//female +		mInventoryItemsDict["Female - Chuckle"]			= LLTrans::getString("Female - Chuckle"); +		mInventoryItemsDict["Female - Cry"]				= LLTrans::getString("Female - Cry"); +		mInventoryItemsDict["Female - Embarrassed"]		= LLTrans::getString("Female - Embarrassed");  		mInventoryItemsDict["Female - Excuse me"]		= LLTrans::getString("Female - Excuse me"); -		mInventoryItemsDict["Female - Get lost"]		= LLTrans::getString("Female - Get lost"); +		mInventoryItemsDict["Female  - Get lost"]		= LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319  		mInventoryItemsDict["Female - Blow kiss"]		= LLTrans::getString("Female - Blow kiss");  		mInventoryItemsDict["Female - Boo"]				= LLTrans::getString("Female - Boo");  		mInventoryItemsDict["Female - Bored"]			= LLTrans::getString("Female - Bored");  		mInventoryItemsDict["Female - Hey"]				= LLTrans::getString("Female - Hey"); +		mInventoryItemsDict["Female - Hey baby"]		= LLTrans::getString("Female - Hey baby");  		mInventoryItemsDict["Female - Laugh"]			= LLTrans::getString("Female - Laugh"); +		mInventoryItemsDict["Female - Looking good"]	= LLTrans::getString("Female - Looking good"); +		mInventoryItemsDict["Female - Over here"]		= LLTrans::getString("Female - Over here"); +		mInventoryItemsDict["Female - Please"]			= LLTrans::getString("Female - Please");  		mInventoryItemsDict["Female - Repulsed"]		= LLTrans::getString("Female - Repulsed");  		mInventoryItemsDict["Female - Shrug"]			= LLTrans::getString("Female - Shrug");  		mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out");  		mInventoryItemsDict["Female - Wow"]				= LLTrans::getString("Female - Wow");  	} + +	/** +	 * Finds passed name in dictionary and replaces it with found localized value. +	 * +	 * @param object_name - string to be localized. +	 * @return true if passed name was found and localized, false otherwise. +	 */ +	bool localizeInventoryObjectName(std::string& object_name) +	{ +		LL_DEBUGS("InventoryLocalize") << "Searching for localization: " << object_name << LL_ENDL; + +		std::map<std::string, std::string>::const_iterator dictionary_iter = mInventoryItemsDict.find(object_name); + +		bool found = dictionary_iter != mInventoryItemsDict.end(); +		if(found) +		{ +			object_name = dictionary_iter->second; +			LL_DEBUGS("InventoryLocalize") << "Found, new name is: " << object_name << LL_ENDL; +		} +		return found; +	}  }; @@ -391,16 +421,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* bloc  {  	BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num); -	std::string localized_str; - -	std::map<std::string, std::string>::const_iterator dictionary_iter; - -	dictionary_iter = LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.find(mName); - -	if(dictionary_iter != LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.end()) -	{ -		mName = dictionary_iter->second; -	} +	LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName);  	mIsComplete = TRUE;  	return rv; @@ -820,6 +841,11 @@ void LLViewerInventoryCategory::changeType(LLFolderType::EType new_folder_type)  	gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);  } +void LLViewerInventoryCategory::localizeName() +{ +	LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName); +} +  ///----------------------------------------------------------------------------  /// Local function definitions  ///---------------------------------------------------------------------------- @@ -895,7 +921,7 @@ void ModifiedCOFCallback::fire(const LLUUID& inv_item)  	gAgentWearables.editWearableIfRequested(inv_item);  	// TODO: camera mode may not be changed if a debug setting is tweaked -	if( gAgentCamera.cameraCustomizeAvatar() ) +	if(gAgentCamera.cameraCustomizeAvatar())  	{  		// If we're in appearance editing mode, the current tab may need to be refreshed  		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLSideTray::getInstance()->getPanel("sidepanel_appearance")); @@ -1132,6 +1158,14 @@ void move_inventory_item(  void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)  { +	if (NULL == src) +	{ +		LL_WARNS("copy_inventory_from_notecard") << "Null pointer to item was passed for object_id " +												 << object_id << " and notecard_inv_id " +												 << notecard_inv_id << LL_ENDL; +		return; +	} +  	LLViewerRegion* viewer_region = NULL;      LLViewerObject* vo = NULL;  	if (object_id.notNull() && (vo = gObjectList.findObject(object_id)) != NULL) @@ -1154,6 +1188,16 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar          return;      } +	// check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459. +	std::string url = viewer_region->getCapability("CopyInventoryFromNotecard"); +	if (url.empty()) +	{ +        LL_WARNS("copy_inventory_from_notecard") << "There is no 'CopyInventoryFromNotecard' capability" +												 << " for region: " << viewer_region->getName() +                                                 << LL_ENDL; +		return; +	} +      LLSD request, body;      body["notecard-id"] = notecard_inv_id;      body["object-id"] = object_id; diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index d0d3ad693e..690c23e6a5 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -228,6 +228,11 @@ public:  	bool importFileLocal(LLFILE* fp);  	void determineFolderType();  	void changeType(LLFolderType::EType new_folder_type); + +private: +	friend class LLInventoryModel; +	void localizeName(); // intended to be called from the LLInventoryModel +  protected:  	LLUUID mOwnerID;  	S32 mVersion; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 635cc361f3..df8e127b1f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -108,9 +108,12 @@  #include "llappearancemgr.h"  #include "lltrans.h"  #include "lleconomy.h" +#include "boost/unordered_map.hpp"  using namespace LLVOAvatarDefines; +static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels; +  BOOL enable_land_build(void*);  BOOL enable_object_build(void*); @@ -2403,31 +2406,53 @@ void handle_object_touch()  		msg->sendMessage(object->getRegion()->getHost());  } -// One object must have touch sensor -class LLObjectEnableTouch : public view_listener_t +static void init_default_item_label(const std::string& item_name)  { -	bool handleEvent(const LLSD& userdata) +	boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); +	if (it == sDefaultItemLabels.end())  	{ -		LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); -		 -		bool new_value = obj && obj->flagHandleTouch(); - -		// Update label based on the node touch name if available. -		std::string touch_text; -		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); -		if (node && node->mValid && !node->mTouchName.empty()) -		{ -			touch_text = node->mTouchName; -		} -		else +		LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString(); +		if (!default_label.empty())  		{ -			touch_text = userdata.asString(); +			sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));  		} -		gMenuHolder->childSetText("Object Touch", touch_text); -		gMenuHolder->childSetText("Attachment Object Touch", touch_text); +	} +} -		return new_value; +static LLStringExplicit get_default_item_label(const std::string& item_name) +{ +	LLStringExplicit res(""); +	boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); +	if (it != sDefaultItemLabels.end()) +	{ +		res = it->second; +	} + +	return res; +} + + +bool enable_object_touch(LLUICtrl* ctrl) +{ +	LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + +	bool new_value = obj && obj->flagHandleTouch(); + +	std::string item_name = ctrl->getName(); +	init_default_item_label(item_name); + +	// Update label based on the node touch name if available. +	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); +	if (node && node->mValid && !node->mTouchName.empty()) +	{ +		gMenuHolder->childSetText(item_name, node->mTouchName); +	} +	else +	{ +		gMenuHolder->childSetText(item_name, get_default_item_label(item_name));  	} + +	return new_value;  };  //void label_touch(std::string& label, void*) @@ -3627,7 +3652,7 @@ class LLEnableEditShape : public view_listener_t  	}  }; -bool enable_sit_object() +bool is_object_sittable()  {  	LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -5513,56 +5538,37 @@ bool enable_pay_object()  	return false;  } -bool visible_object_stand_up() +bool enable_object_stand_up()  { -	// 'Object Stand Up' menu item is visible when agent is sitting on selection +	// 'Object Stand Up' menu item is enabled when agent is sitting on selection  	return sitting_on_selection();  } -bool visible_object_sit() +bool enable_object_sit(LLUICtrl* ctrl)  { -	// 'Object Sit' menu item is visible when agent is not sitting on selection -	bool is_sit_visible = !sitting_on_selection(); -	if (is_sit_visible) +	// 'Object Sit' menu item is enabled when agent is not sitting on selection +	bool sitting_on_sel = sitting_on_selection(); +	if (!sitting_on_sel)  	{ -		LLMenuItemGL* sit_menu_item = gMenuHolder->getChild<LLMenuItemGL>("Object Sit"); -		// Init default 'Object Sit' menu item label -		static const LLStringExplicit sit_text(sit_menu_item->getLabel()); +		std::string item_name = ctrl->getName(); + +		// init default labels +		init_default_item_label(item_name); +  		// Update label -		std::string label;  		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();  		if (node && node->mValid && !node->mSitName.empty())  		{ -			label.assign(node->mSitName); +			gMenuHolder->childSetText(item_name, node->mSitName);  		}  		else  		{ -			label = sit_text; +			gMenuHolder->childSetText(item_name, get_default_item_label(item_name));  		} -		sit_menu_item->setLabel(label);  	} -	return is_sit_visible; +	return !sitting_on_sel && is_object_sittable();  } -class LLObjectEnableSitOrStand : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		bool new_value = false; -		LLViewerObject* dest_object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - -		if(dest_object) -		{ -			if(dest_object->getPCode() == LL_PCODE_VOLUME) -			{ -				new_value = true; -			} -		} - -		return new_value; -	} -}; -  void dump_select_mgr(void*)  {  	LLSelectMgr::getInstance()->dump(); @@ -8067,7 +8073,6 @@ void initialize_menus()  	view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");  	commit.add("Object.Touch", boost::bind(&handle_object_touch));  	commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); -	enable.add("Object.EnableSit", boost::bind(&enable_sit_object));  	commit.add("Object.Delete", boost::bind(&handle_object_delete));  	view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");  	view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); @@ -8083,13 +8088,12 @@ void initialize_menus()  	commit.add("Object.Open", boost::bind(&handle_object_open));  	commit.add("Object.Take", boost::bind(&handle_take));  	enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); -	view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); -	view_listener_t::addMenu(new LLObjectEnableSitOrStand(), "Object.EnableSitOrStand"); +	enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));  	enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));  	enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid)); -	enable.add("Object.StandUpVisible", boost::bind(&visible_object_stand_up)); -	enable.add("Object.SitVisible", boost::bind(&visible_object_sit)); +	enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up)); +	enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));  	view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");  	view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 07b6431c92..04545d2549 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1138,10 +1138,26 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam  						}  						else if(from_name.empty())  						{ +							std::string folder_name; +							if (parent_folder) +							{ +								// Localize folder name. +								// *TODO: share this code? +								folder_name = parent_folder->getName(); +								if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType())) +								{ +									LLTrans::findString(folder_name, "InvFolder " + folder_name); +								} +							} +							else +							{ +								 folder_name = LLTrans::getString("Unknown"); +							} +  							// we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.  							LLSD args;  							args["LANDMARK_NAME"] = item->getName(); -							args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown"); +							args["FOLDER_NAME"] = folder_name;  							LLNotificationsUtil::add("LandmarkCreated", args);  						}  					} @@ -1215,8 +1231,9 @@ bool highlight_offered_object(const LLUUID& obj_id)  void inventory_offer_mute_callback(const LLUUID& blocked_id,  								   const std::string& first_name,  								   const std::string& last_name, -								   BOOL is_group, LLOfferInfo* offer = NULL) +								   BOOL is_group, boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)  { +	LLOfferInfo* offer =  dynamic_cast<LLOfferInfo*>(offer_ptr.get());  	std::string from_name;  	LLMute::EType type;  	if (is_group) @@ -1406,7 +1423,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  	// * we can't build two messages at once.  	if (2 == button) // Block  	{ -		gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); +		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + +		llassert(notification_ptr != NULL); +		if (notification_ptr != NULL) +		{ +			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); +		}  	}  	std::string from_string; // Used in the pop-up. @@ -1540,7 +1563,13 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const  	// * we can't build two messages at once.  	if (2 == button)  	{ -		gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); +		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + +		llassert(notification_ptr != NULL); +		if (notification_ptr != NULL) +		{ +			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); +		}  	}  	LLMessageSystem* msg = gMessageSystem; @@ -5093,7 +5122,7 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data)  void process_alert_core(const std::string& message, BOOL modal)  { -	// HACK -- handle callbacks for specific alerts +	// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml  	if ( message == "You died and have been teleported to your home location")  	{  		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 59efae4cb2..8bd43bb30c 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -90,7 +90,7 @@ public:  	}  	static void processForeignLandmark(LLLandmark* landmark,  			const LLUUID& object_id, const LLUUID& notecard_inventory_id, -			LLInventoryItem* item) +			LLPointer<LLInventoryItem> item_ptr)  	{  		LLVector3d global_pos;  		landmark->getGlobalPos(global_pos); @@ -103,8 +103,16 @@ public:  		}  		else  		{ -			LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied(); -			copy_inventory_from_notecard(object_id, notecard_inventory_id, item, gInventoryCallbacks.registerCB(cb)); +			if (item_ptr.isNull()) +			{ +				// check to prevent a crash. See EXT-8459. +				llwarns << "Passed handle contains a dead inventory item. Most likely notecard has been closed and embedded item was destroyed." << llendl; +			} +			else +			{ +				LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied(); +				copy_inventory_from_notecard(object_id, notecard_inventory_id, item_ptr.get(), gInventoryCallbacks.registerCB(cb)); +			}  		}  	}  }; @@ -300,14 +308,14 @@ public:  	void	markSaved(); -	static LLInventoryItem* getEmbeddedItem(llwchar ext_char); // returns item from static list +	static LLPointer<LLInventoryItem> getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list  	static BOOL getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved  private:  	struct embedded_info_t  	{ -		LLPointer<LLInventoryItem> mItem; +		LLPointer<LLInventoryItem> mItemPtr;  		BOOL mSaved;  	};  	typedef std::map<llwchar, embedded_info_t > item_map_t; @@ -378,7 +386,7 @@ BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch  		++wc_emb;  	} -	sEntries[wc_emb].mItem = item; +	sEntries[wc_emb].mItemPtr = item;  	sEntries[wc_emb].mSaved = is_new ? FALSE : TRUE;  	*ext_char = wc_emb;  	mEmbeddedUsedChars.insert(wc_emb); @@ -400,14 +408,14 @@ BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char )  }  // static -LLInventoryItem* LLEmbeddedItems::getEmbeddedItem(llwchar ext_char) +LLPointer<LLInventoryItem> LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char)  {  	if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR )  	{  		item_map_t::iterator iter = sEntries.find(ext_char);  		if (iter != sEntries.end())  		{ -			return iter->second.mItem; +			return iter->second.mItemPtr;  		}  	}  	return NULL; @@ -505,7 +513,7 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char)  LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const  { -	LLInventoryItem* item = getEmbeddedItem(ext_char); +	LLInventoryItem* item = getEmbeddedItemPtr(ext_char);  	if (item)  	{  		const char* img_name = ""; @@ -567,7 +575,7 @@ void LLEmbeddedItems::getEmbeddedItemList( std::vector<LLPointer<LLInventoryItem  	for (std::set<llwchar>::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter)  	{  		llwchar wc = *iter; -		LLPointer<LLInventoryItem> item = getEmbeddedItem(wc); +		LLPointer<LLInventoryItem> item = getEmbeddedItemPtr(wc);  		if (item)  		{  			items.push_back(item); @@ -698,7 +706,7 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)  			{  				wc = getWText()[mCursorPos];  			} -			LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc); +			LLPointer<LLInventoryItem> item_at_pos = LLEmbeddedItems::getEmbeddedItemPtr(wc);  			if (item_at_pos)  			{  				mDragItem = item_at_pos; @@ -1019,7 +1027,7 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char)  	{  		return ext_char; // already exists in my list  	} -	LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(ext_char); +	LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItemPtr(ext_char);  	if (item)  	{  		// Add item to my list and return new llwchar associated with it @@ -1053,7 +1061,7 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)  			&& embedded_char <= LAST_EMBEDDED_CHAR   			&& mEmbeddedItemList->hasEmbeddedItem(embedded_char) )  		{ -			LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItem(embedded_char); +			LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char);  			LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char);  			insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this));  		} @@ -1065,7 +1073,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)  	if( pos < getLength())  	{  		llwchar wc = getWText()[pos]; -		LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem( wc ); +		LLPointer<LLInventoryItem> item = LLEmbeddedItems::getEmbeddedItemPtr( wc );  		if( item )  		{  			BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( wc ); @@ -1083,7 +1091,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)  } -BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc) +BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc)  {  	switch( item->getType() ) @@ -1151,17 +1159,17 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc )  } -void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc ) +void LLViewerTextEditor::openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc )  { -	if (!item) +	if (item_ptr.isNull())  		return; -	LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID(), -			boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item)); +	LLLandmark* landmark = gLandmarkList.getAsset(item_ptr->getAssetUUID(), +			boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item_ptr));  	if (landmark)  	{  		LLEmbeddedLandmarkCopied::processForeignLandmark(landmark, mObjectID, -				mNotecardInventoryID, item); +				mNotecardInventoryID, item_ptr);  	}  } @@ -1220,7 +1228,7 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD&  	{  		LLUUID item_id = notification["payload"]["item_id"].asUUID();  		llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); -		LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItem(wc); +		LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc);  		if (itemp)  			copyInventory(itemp);  	} diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index ba0c40cb2e..74b6d70640 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -104,13 +104,16 @@ private:  	virtual llwchar	pasteEmbeddedItem(llwchar ext_char);  	BOOL			openEmbeddedItemAtPos( S32 pos ); -	BOOL			openEmbeddedItem(LLInventoryItem* item, llwchar wc); +	BOOL			openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc);  	S32				insertEmbeddedItem(S32 pos, LLInventoryItem* item); +	// *NOTE: most of openEmbeddedXXX methods except openEmbeddedLandmark take pointer to LLInventoryItem. +	// Be sure they don't bind it to callback function to avoid situation when it gets invalid when +	// callback is trigged after text editor is closed. See EXT-8459.  	void			openEmbeddedTexture( LLInventoryItem* item, llwchar wc );  	void			openEmbeddedSound( LLInventoryItem* item, llwchar wc ); -	void			openEmbeddedLandmark( LLInventoryItem* item, llwchar wc ); +	void			openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );  	void			openEmbeddedNotecard( LLInventoryItem* item, llwchar wc);  	void			openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);  	void			showCopyToInvDialog( LLInventoryItem* item, llwchar wc ); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0afbce7d51..2929dce898 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -114,7 +114,6 @@ LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,  					  BOOL need_imageraw, // Needs image raw for the callback  					  void* userdata,  					  LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, -					  void* source,  					  LLViewerFetchedTexture* target,  					  BOOL pause)   	: mCallback(cb), @@ -123,7 +122,6 @@ LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,  	  mNeedsImageRaw(need_imageraw),  	  mUserData(userdata),  	  mSourceCallbackList(src_callback_list), -	  mSource(source),  	  mPaused(pause)  {  	if(mSourceCallbackList) @@ -145,10 +143,10 @@ void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex)  }  //static  -void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list, void* src) +void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list)  {  	//clear texture callbacks. -	if(!callback_list->empty()) +	if(callback_list && !callback_list->empty())  	{  		for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin();  				iter != callback_list->end(); ++iter) @@ -156,7 +154,7 @@ void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_ca  			LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;  			if(tex)  			{ -				tex->deleteCallbackEntry(src) ;			 +				tex->deleteCallbackEntry(callback_list) ;			  			}  		}  		callback_list->clear() ; @@ -513,6 +511,7 @@ LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)  LLViewerTexture::~LLViewerTexture()  { +	cleanup();  	sImageCount--;  } @@ -545,7 +544,6 @@ S8 LLViewerTexture::getType() const  	return LLViewerTexture::LOCAL_TEXTURE ;  } -//virtual  void LLViewerTexture::cleanup()  {  	mFaceList.clear() ; @@ -1176,7 +1174,6 @@ S8 LLViewerFetchedTexture::getType() const  	return LLViewerTexture::FETCHED_TEXTURE ;  } -//virtual  void LLViewerFetchedTexture::cleanup()  {  	for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); @@ -1198,8 +1195,6 @@ void LLViewerFetchedTexture::cleanup()  	mCachedRawDiscardLevel = -1 ;  	mCachedRawImageReady = FALSE ;  	mSavedRawImage = NULL ; - -	LLViewerTexture::cleanup();  }  void LLViewerFetchedTexture::setForSculpt() @@ -1609,6 +1604,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()  		S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;  		ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);  		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; +		setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far.  	}  	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))  	{ @@ -2003,7 +1999,7 @@ void LLViewerFetchedTexture::setIsMissingAsset()  }  void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback, -									   S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata, void* src, +									   S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata,   									   LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause)  {  	// @@ -2022,9 +2018,9 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call  	if(mPauseLoadedCallBacks && !pause)  	{ -		unpauseLoadedCallbacks(src) ; +		unpauseLoadedCallbacks(src_callback_list) ;  	} -	LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, src, this, pause); +	LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);  	mLoadedCallbackList.push_back(entryp);	  	mNeedsAux |= needs_aux; @@ -2039,9 +2035,9 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call  	}  } -void LLViewerFetchedTexture::deleteCallbackEntry(void* src) +void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)  { -	if(mLoadedCallbackList.empty()) +	if(mLoadedCallbackList.empty() || !callback_list)  	{  		return ;  	} @@ -2052,13 +2048,13 @@ void LLViewerFetchedTexture::deleteCallbackEntry(void* src)  			iter != mLoadedCallbackList.end(); )  	{  		LLLoadedCallbackEntry *entryp = *iter; -		if(entryp->mSource == src) +		if(entryp->mSourceCallbackList == callback_list)  		{  			// We never finished loading the image.  Indicate failure.  			// Note: this allows mLoadedCallbackUserData to be cleaned up.  			entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); -			delete entryp;  			iter = mLoadedCallbackList.erase(iter) ; +			delete entryp;  		}  		else  		{ @@ -2097,14 +2093,20 @@ void LLViewerFetchedTexture::deleteCallbackEntry(void* src)  	}  } -void LLViewerFetchedTexture::unpauseLoadedCallbacks(void* src) +void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)  { +	if(!callback_list) +	{ +		mPauseLoadedCallBacks = FALSE ; +		return ; +	} +  	BOOL need_raw = FALSE ;  	for(callback_list_t::iterator iter = mLoadedCallbackList.begin();  			iter != mLoadedCallbackList.end(); )  	{  		LLLoadedCallbackEntry *entryp = *iter++; -		if(entryp->mSource == src) +		if(entryp->mSourceCallbackList == callback_list)  		{  			entryp->mPaused = FALSE ;  			if(entryp->mNeedsImageRaw) @@ -2120,15 +2122,20 @@ void LLViewerFetchedTexture::unpauseLoadedCallbacks(void* src)  	}  } -void LLViewerFetchedTexture::pauseLoadedCallbacks(void* src) +void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)  { +	if(!callback_list) +	{ +		return ; +	} +  	bool paused = true ;  	for(callback_list_t::iterator iter = mLoadedCallbackList.begin();  			iter != mLoadedCallbackList.end(); )  	{  		LLLoadedCallbackEntry *entryp = *iter++; -		if(entryp->mSource == src) +		if(entryp->mSourceCallbackList == callback_list)  		{  			entryp->mPaused = TRUE ;  		} @@ -2305,10 +2312,6 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()  				BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;  				//llinfos << "Running callback for " << getID() << llendl;  				//llinfos << mRawImage->getWidth() << "x" << mRawImage->getHeight() << llendl; -				if (final) -				{ -					//llinfos << "Final!" << llendl; -				}  				entryp->mLastUsedDiscard = mRawDiscardLevel;  				entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);  				if (final) @@ -3665,7 +3668,7 @@ void LLTexturePipelineTester::updateStablizingTime()  	{  		F32 t = mEndStablizingTime - mStartStablizingTime ; -		if(t > 0.0001f && (t - mTotalStablizingTime) < 0.0001f) +		if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO)  		{  			//already stablized  			mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime ; @@ -3790,7 +3793,7 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi  		//time  		F32 start_time = (*log)[label]["StartFetchingTime"].asReal() ;  		F32 cur_time   = (*log)[label]["Time"].asReal() ; -		if(start_time - start_fetching_time > 0.0001f) //fetching has paused for a while +		if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while  		{  			sessionp->mTotalFetchingTime += total_fetching_time ;  			sessionp->mTotalGrayTime += total_gray_time ; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 8b69408e4b..f071c6e392 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -75,7 +75,6 @@ public:  						  BOOL need_imageraw, // Needs image raw for the callback  						  void* userdata,  						  source_callback_list_t* src_callback_list, -						  void* source,  						  LLViewerFetchedTexture* target,  						  BOOL pause);  	~LLLoadedCallbackEntry(); @@ -88,10 +87,9 @@ public:  	BOOL                    mPaused;  	void*					mUserData;  	source_callback_list_t* mSourceCallbackList; -	void*                   mSource;  public: -	static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list, void* src) ; +	static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ;  };  class LLTextureBar; @@ -264,7 +262,7 @@ public:  	/*virtual*/ void updateBindStatsForTester() ;  protected: -	virtual void cleanup() ; +	void cleanup() ;  	void init(bool firstinit) ;	  	void reorganizeFaceList() ;  	void reorganizeVolumeList() ; @@ -384,13 +382,13 @@ public:  	// Set callbacks to get called when the image gets updated with higher   	// resolution versions.  	void setLoadedCallback(loaded_callback_func cb, -						   S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* src, +						   S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,  						   void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE);  	bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }	 -	void pauseLoadedCallbacks(void* src); -	void unpauseLoadedCallbacks(void* src); +	void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); +	void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);  	bool doLoadedCallbacks(); -	void deleteCallbackEntry(void* src); +	void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);  	void addToCreateTexture(); @@ -485,7 +483,7 @@ protected:  private:  	void init(bool firstinit) ; -	/*virtual*/ void cleanup() ; +	void cleanup() ;  	void saveRawImage() ;  	void setCachedRawImage() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b3aff30324..31f0998fab 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1402,12 +1402,17 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st  	mUIImages.insert(std::make_pair(name, new_imagep));  	mUITextureList.push_back(imagep); -	LLUIImageLoadData* datap = new LLUIImageLoadData; -	datap->mImageName = name; -	datap->mImageScaleRegion = scale_rect; - -	imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap, NULL, NULL); +	//Note: +	//Some other textures such as ICON also through this flow to be fetched. +	//But only UI textures need to set this callback. +	if(imagep->getBoostLevel() == LLViewerTexture::BOOST_UI) +	{ +		LLUIImageLoadData* datap = new LLUIImageLoadData; +		datap->mImageName = name; +		datap->mImageScaleRegion = scale_rect; +		imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap, NULL); +	}  	return new_imagep;  } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6346ac320b..5f0fcb72f0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4524,7 +4524,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)  		gResizeScreenTexture = TRUE; -		if (gAgentCamera.cameraCustomizeAvatar()) +		if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  		{  			LLVisualParamHint::requestHintUpdates();  		} diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 47e35ca0c4..32723dfe3d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -835,6 +835,7 @@ LLVOAvatar::~LLVOAvatar()  	mDead = TRUE;  	mAnimationSources.clear(); +	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;  	lldebugs << "LLVOAvatar Destructor end" << llendl;  } @@ -848,7 +849,7 @@ void LLVOAvatar::markDead()  		sNumVisibleChatBubbles--;  	}  	mVoiceVisualizer->markDead(); -	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList, this) ; +	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;  	LLViewerObject::markDead();  } @@ -4142,9 +4143,13 @@ void LLVOAvatar::updateTextures()  	}  	else  	{ -		render_avatar = isVisible() && !mCulled; +		if(!isVisible()) +		{ +			return ;//do not update for invisible avatar. +		} + +		render_avatar = !mCulled; //visible and not culled.  	} -	checkTextureLoading() ;  	std::vector<BOOL> layer_baked;  	// GL NOT ACTIVE HERE - *TODO @@ -4224,10 +4229,11 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture  	return;  } -			     +const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.	 +const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = S32_MAX ; //frames  void LLVOAvatar::checkTextureLoading()  { -	static const F32 MAX_INVISIBLE_WAITING_TIME = 30.f ; //seconds +	static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds  	BOOL pause = !isVisible() ;  	if(!pause) @@ -4247,7 +4253,7 @@ void LLVOAvatar::checkTextureLoading()  	if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)  	{ -		return ; +		return ; //have not been invisible for enough time.  	}  	for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin(); @@ -4258,30 +4264,40 @@ void LLVOAvatar::checkTextureLoading()  		{  			if(pause)//pause texture fetching.  			{ -				tex->pauseLoadedCallbacks(this) ; +				tex->pauseLoadedCallbacks(&mCallbackTextureList) ; + +				//set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames. +				tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL); +				tex->resetMaxVirtualSizeResetCounter() ;  			}  			else//unpause  			{  				static const F32 START_AREA = 100.f ; -				tex->unpauseLoadedCallbacks(this) ; +				tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;  				tex->addTextureStats(START_AREA); //jump start the fetching again  			}  		}		  	}			 +	if(!pause) +	{ +		updateTextures() ; //refresh texture stats. +	}  	mLoadedCallbacksPaused = pause ;  	return ;  }  void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)  { -	//if this function is not called for the last 512 frames, the texture pipeline will stop fetching this texture. -	static const S32  MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 512 ; //frames	 +	//Note: +	//if this function is not called for the last MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL frames,  +	//the texture pipeline will stop fetching this texture.  	imagep->resetTextureStats();  	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.  	imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); +	imagep->resetMaxVirtualSizeResetCounter() ;  	mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);  	mMinPixelArea = llmin(pixel_area, mMinPixelArea);	 @@ -6206,11 +6222,9 @@ void LLVOAvatar::updateMeshTextures()  	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures  	const BOOL other_culled = !isSelf() && mCulled;  	LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; -	void* callback_src = NULL ;  	BOOL paused = FALSE;  	if(!isSelf())  	{ -		callback_src = this ;  		src_callback_list = &mCallbackTextureList ;  		paused = mLoadedCallbacksPaused ;  	} @@ -6286,10 +6300,10 @@ void LLVOAvatar::updateMeshTextures()  				if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )  				{			  					baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),  -						callback_src, src_callback_list, paused);	 +						src_callback_list, paused);	  				}  				baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),  -					callback_src, src_callback_list, paused ); +					src_callback_list, paused );  			}  		}  		else if (mBakedTextureDatas[i].mTexLayerSet  @@ -6750,11 +6764,9 @@ void LLVOAvatar::onFirstTEMessageReceived()  		mFirstTEMessageReceived = TRUE;  		LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; -		void* callback_src = NULL ;  		BOOL paused = FALSE ;  		if(!isSelf())  		{ -			callback_src = this ;  			src_callback_list = &mCallbackTextureList ;  			paused = mLoadedCallbacksPaused ;  		} @@ -6773,10 +6785,10 @@ void LLVOAvatar::onFirstTEMessageReceived()  				if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )  				{  					image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),  -						callback_src, src_callback_list, paused); +						src_callback_list, paused);  				}  				image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),  -					callback_src, src_callback_list, paused ); +					src_callback_list, paused );  			}  		} diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 3dad919875..bb04511a8d 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -611,8 +611,9 @@ public:  	// Appearance morphing  	//--------------------------------------------------------------------  public: -	BOOL			mAppearanceAnimating; +	BOOL			getIsAppearanceAnimating() const { return mAppearanceAnimating; }  private: +	BOOL			mAppearanceAnimating;  	LLFrameTimer	mAppearanceMorphTimer;  	F32				mLastAppearanceBlendTime; @@ -1048,5 +1049,6 @@ protected: // Shared with LLVOAvatarSelf   *******************************************************************************/  }; // LLVOAvatar +extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;  #endif // LL_VO_AVATAR_H diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 4edbbb7402..46d987353f 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1148,11 +1148,11 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr  			discard_level < local_tex_obj->getDiscard())  		{  			local_tex_obj->setDiscard(discard_level); -			if (!gAgentCamera.cameraCustomizeAvatar()) +			if (isUsingBakedTextures())  			{  				requestLayerSetUpdate(index);  			} -			else if (gAgentCamera.cameraCustomizeAvatar()) +			else  			{  				LLVisualParamHint::requestHintUpdates();  			} @@ -1622,18 +1622,21 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te  				if (tex_discard >= 0 && tex_discard <= desired_discard)  				{  					local_tex_obj->setDiscard(tex_discard); -					if (isSelf() && !gAgentCamera.cameraCustomizeAvatar()) -					{ -						requestLayerSetUpdate(type); -					} -					else if (isSelf() && gAgentCamera.cameraCustomizeAvatar()) +					if (isSelf())  					{ -						LLVisualParamHint::requestHintUpdates(); +						if (gAgentAvatarp->isUsingBakedTextures()) +						{ +							requestLayerSetUpdate(type); +						} +						else +						{ +							LLVisualParamHint::requestHintUpdates(); +						}  					}  				}  				else  				{					 -					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL, NULL); +					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);  				}  			}  			tex->setMinDiscardLevel(desired_discard); @@ -2032,7 +2035,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  			imagep->setBoostLevel(getAvatarBoostLevel());  			imagep->resetTextureStats(); -			imagep->setMaxVirtualSizeResetInterval(16); +			imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);  			imagep->addTextureStats( desired_pixels / texel_area_ratio );  			imagep->setAdditionalDecodePriority(1.0f) ;  			imagep->forceUpdateBindStats() ; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index a82afbeb76..8a58a9c65b 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -53,6 +53,7 @@  #include "llworld.h"  #include "lldir.h"  #include "llxmltree.h" +#include "llvotree.h"  const S32 GRASS_MAX_BLADES =	32;  const F32 GRASS_BLADE_BASE =	0.25f;			//  Width of grass at base @@ -294,6 +295,23 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  		return TRUE;  	} +	if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass +	{ +		if(mNumBlades) +		{ +			mNumBlades = 0 ; +			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); +		} +		return TRUE ; +	} +	else if(!mNumBlades)//restart grass rendering +	{ +		mNumBlades = GRASS_MAX_BLADES ; +		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); +		 +		return TRUE ; +	} +  	if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))  	{  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); @@ -340,7 +358,20 @@ BOOL LLVOGrass::updateLOD()  	{  		return FALSE;  	} -	 +	if(LLVOTree::isTreeRenderingStopped()) +	{ +		if(mNumBlades) +		{ +			mNumBlades = 0 ; +			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); +		} +		return TRUE ; +	} +	if(!mNumBlades) +	{ +		mNumBlades = GRASS_MAX_BLADES; +	} +  	LLFace* face = mDrawable->getFace(0);  	F32 tan_angle = 0.f; @@ -387,8 +418,24 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_GRASS("Update Grass");  BOOL LLVOGrass::updateGeometry(LLDrawable *drawable)  {  	LLFastTimer ftm(FTM_UPDATE_GRASS); +  	dirtySpatialGroup(); -	plantBlades(); + +	if(!mNumBlades)//stop rendering grass +	{ +		if (mDrawable->getNumFaces() > 0) +		{ +			LLFace* facep = mDrawable->getFace(0); +			if(facep) +			{ +				facep->setSize(0, 0);			 +			} +		} +	} +	else +	{		 +		plantBlades(); +	}  	return TRUE;  } @@ -429,6 +476,11 @@ void LLVOGrass::getGeometry(S32 idx,  								LLStrider<LLColor4U>& colorsp,   								LLStrider<U16>& indicesp)  { +	if(!mNumBlades)//stop rendering grass +	{ +		return ; +	} +  	mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());  	if (mPatch)  		mLastPatchUpdateTime = mPatch->getLastUpdateTime(); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 5431aec07c..0efe6682be 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -73,7 +73,7 @@ S32 LLVOTree::sLODVertexCount[sMAX_NUM_TREE_LOD_LEVELS];  S32 LLVOTree::sLODIndexOffset[sMAX_NUM_TREE_LOD_LEVELS];  S32 LLVOTree::sLODIndexCount[sMAX_NUM_TREE_LOD_LEVELS];  S32 LLVOTree::sLODSlices[sMAX_NUM_TREE_LOD_LEVELS] = {10, 5, 4, 3}; -F32 LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS] = {30.f, 20.f, 15.f, 0.00001f}; +F32 LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS] = {30.f, 20.f, 15.f, F_ALMOST_ZERO};  F32 LLVOTree::sTreeFactor = 1.f; @@ -101,6 +101,12 @@ LLVOTree::~LLVOTree()  	}  } +//static +bool LLVOTree::isTreeRenderingStopped() +{ +	return LLVOTree::sTreeFactor < LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS - 1] ; +} +  // static  void LLVOTree::initClass()  { diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 036ad692b1..a6850e4790 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -59,6 +59,7 @@ public:  	// Initialize data that's only inited once per class.  	static void initClass();  	static void cleanupClass(); +	static bool isTreeRenderingStopped();  	/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,  											void **user_data, diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index ec9c78ee53..c5042ca016 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -444,8 +444,7 @@ BOOL LLWearable::importFile( LLFILE* file )  			delete mSavedTEMap[te];  		} -		image->setBoostLevel(LLViewerTexture::BOOST_AVATAR_SELF) ; -		image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL, NULL); +		image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL);  		LLUUID textureid(text_buffer);  		mTEMap[te] = new LLLocalTextureObject(image, textureid); @@ -699,7 +698,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake  		}  	} -	if( gAgentCamera.cameraCustomizeAvatar() ) +	if(gAgentCamera.cameraCustomizeAvatar())  	{  		LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));  	} diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 3887f64618..c01d7fa62f 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -365,6 +365,29 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLWearableItemTypeNameComparator::LLWearableTypeOrder::LLWearableTypeOrder(LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name): +		mOrderPriority(order_priority), +		mSortAssetTypeByName(sort_asset_by_name), +		mSortWearableTypeByName(sort_wearable_by_name) +{ +} + +LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator() +{ +	// By default the sort order conforms the order by spec of MY OUTFITS items list: +	// 1. CLOTHING - sorted by name +	// 2. OBJECT   - sorted by type +	// 3. BODYPART - sorted by name +	mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false); +	mWearableOrder[LLAssetType::AT_OBJECT]   = LLWearableTypeOrder(ORDER_RANK_2, true, true); +	mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true); +} + +void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type,  LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name) +{ +	mWearableOrder[items_of_type] = LLWearableTypeOrder(order_priority, sort_asset_items_by_name, sort_wearable_items_by_name); +} +  /*virtual*/  bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const  { @@ -393,7 +416,7 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB  		return item_type_order1 < item_type_order2;  	} -	if (item_type_order1 & TLO_SORTABLE_BY_NAME) +	if (sortAssetTypeByName(item_type1))  	{  		// If both items are of the same asset type except AT_CLOTHING and AT_BODYPART  		// we can compare them by name. @@ -405,38 +428,61 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB  	if (item_wearable_type1 != item_wearable_type2)  	{ -		// If items are of different clothing types they are compared -		// by clothing types order determined in LLWearableType::EType. +		// If items are of different LLWearableType::EType types they are compared +		// by LLWearableType::EType. types order determined in LLWearableType::EType.  		return item_wearable_type1 < item_wearable_type2;  	}  	else  	{  		// If both items are of the same clothing type they are compared -		// by description and place in reverse order i.e. outer layer item -		// on top. +		// by description and place in reverse order (i.e. outer layer item +		// on top) OR by name +		if(sortWearableTypeByName(item_type1)) +		{ +			return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2); +		}  		return wearable_item1->getDescription() > wearable_item2->getDescription();  	}  } -// static -LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) +LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) const  { -	switch (item_type) +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type); + +	if(const_it == mWearableOrder.end())  	{ -	case LLAssetType::AT_OBJECT: -		return TLO_ATTACHMENT; +		llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return ORDER_RANK_UNKNOWN; +	} -	case LLAssetType::AT_CLOTHING: -		return TLO_CLOTHING; +	return const_it->second.mOrderPriority; +} -	case LLAssetType::AT_BODYPART: -		return TLO_BODYPART; +bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType item_type) const +{ +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type); -	default: -		return TLO_UNKNOWN; +	if(const_it == mWearableOrder.end()) +	{ +		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return true;  	} + +	return const_it->second.mSortAssetTypeByName;  } +bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const +{ +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type); + +	if(const_it == mWearableOrder.end()) +	{ +		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return true; +	} + +	return const_it->second.mSortWearableTypeByName; +}  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// @@ -576,13 +622,11 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()  	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, true, LLPointer<LLInventoryCallback>(NULL)); -	functor_t add = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, false, LLPointer<LLInventoryCallback>(NULL));  	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.Wear", boost::bind(wear_multiple, ids, true)); +	registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));  	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)); @@ -665,8 +709,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu  	bool standalone = mParent ? mParent->isStandalone() : false;  	// *TODO: eliminate multiple traversals over the menu items -	setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0); -	setMenuItemEnabled(menu, "wear_wear", 			n_already_worn == 0); +	setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0); +	setMenuItemEnabled(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0);  	setMenuItemVisible(menu, "wear_add",			mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0);  	setMenuItemEnabled(menu, "wear_add",			n_items == 1 && canAddWearable(ids.front()) && n_already_worn != 0);  	setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0); diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index d16a2a89c8..0e5403f30c 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -281,33 +281,76 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator  	LOG_CLASS(LLWearableItemTypeNameComparator);  public: -	LLWearableItemTypeNameComparator() {}; + +	LLWearableItemTypeNameComparator();  	virtual ~LLWearableItemTypeNameComparator() {}; +	enum ETypeListOrder +	{ +		ORDER_RANK_1 = 1, +		ORDER_RANK_2, +		ORDER_RANK_3, +		ORDER_RANK_UNKNOWN +	}; + +	void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name); +  protected:  	/** -	 * Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following: -	 *   - Attachments (abc order) -	 *   - Clothing -	 *         - by type (types order determined in LLWearableType::EType) -	 *         - outer layer on top -	 *   - Body Parts (abc order), -	 * "false" otherwise. +	 * All information about sort order is stored in mWearableOrder map +	 * +	 * mWearableOrder :      KYES              VALUES +	 *                  [LLAssetType] [struct LLWearableTypeOrder] +	 * +	 *--------------------------------------------------------------------------------------------- +	 * I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list. +	 *     For example by spec in MY OUTFITS the order is: +	 *     1. AT_CLOTHING (ORDER_RANK_1) +	 *     2. AT_OBJECT   (ORDER_RANK_2) +	 *     3. AT_BODYPART (ORDER_RANK_3) +	 * +	 * II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType) +	 *     For example by spec in MY OUTFITS the order within each items type(LLAssetType) is: +	 *     1. AT_OBJECTS (abc order) +	 *     2. AT_CLOTHINGS +	 *       - by type (types order determined in LLWearableType::EType) +	 *       - outer layer on top +	 *     3. AT_BODYPARTS  (abc order) +	 *--------------------------------------------------------------------------------------------- +	 * +	 * For each LLAssetType (KEYS in mWearableOrder) the information about: +	 * +	 *                                             I.  ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority) +	 * +	 *                                             II. whether items of this LLAssetType type should be ordered +	 *                                                 by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName) +	 * +	 *                                             III.whether items of LLWearableType type within this LLAssetType +	 *                                                 should be ordered by name (the flag is LLWearableTypeOrder::mSortWearableTypeByName) +	 * +	 *  holds in mWearableOrder map as VALUES (struct LLWearableTypeOrder).  	 */  	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;  private: -	enum ETypeListOrder + +	struct LLWearableTypeOrder  	{ -		TLO_CLOTHING	= 0x01, -		TLO_ATTACHMENT	= 0x02, -		TLO_BODYPART	= 0x04, -		TLO_UNKNOWN		= 0x08, +		ETypeListOrder mOrderPriority; +		bool mSortAssetTypeByName; +		bool mSortWearableTypeByName; -		TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN +		LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name); +		LLWearableTypeOrder(){};  	}; -	static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type); +	ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const; + +	bool sortAssetTypeByName(LLAssetType::EType item_type) const; +	bool sortWearableTypeByName(LLAssetType::EType item_type) const; + +	typedef std::map<LLAssetType::EType,LLWearableTypeOrder> wearable_type_order_map_t; +	wearable_type_order_map_t mWearableOrder;  };  /** diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 66cb02ce99..9bbe005de8 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -37,6 +37,7 @@  #include "llworldmapmessage.h"  #include "message.h"  #include "lltracker.h" +#include "lluistring.h"  #include "llviewertexturelist.h"  #include "lltrans.h" @@ -522,8 +523,12 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&  		case MAP_ITEM_LAND_FOR_SALE:		// land for sale  		case MAP_ITEM_LAND_FOR_SALE_ADULT:	// adult land for sale   		{ -			std::string tooltip = llformat("%d sq. m. L$%d", extra, extra2); -			new_item.setTooltip(tooltip); +			static LLUIString tooltip_fmt = LLTrans::getString("worldmap_item_tooltip_format"); + +			tooltip_fmt.setArg("[AREA]",  llformat("%d", extra)); +			tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2)); +			new_item.setTooltip(tooltip_fmt.getString()); +  			if (type == MAP_ITEM_LAND_FOR_SALE)  			{  				siminfo->insertLandForSale(new_item); diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index e4e677eb64..b97e5249e1 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -52,7 +52,7 @@ public:  	LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id);  	// Setters -	void setTooltip(std::string& tooltip) { mToolTip = tooltip; } +	void setTooltip(const std::string& tooltip) { mToolTip = tooltip; }  	void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; }  	void setCount(S32 count) { mCount = count; }  //	void setSelected(bool selected) { mSelected = selected; } diff --git a/indra/newview/skins/default/xui/da/menu_object.xml b/indra/newview/skins/default/xui/da/menu_object.xml index c98a07e140..f4f7eb0af8 100644 --- a/indra/newview/skins/default/xui/da/menu_object.xml +++ b/indra/newview/skins/default/xui/da/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Berør" name="Object Touch"/> +	<menu_item_call label="Berør" name="Object Touch"> +		<on_enable parameter="Berør" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Redigér" name="Edit..."/>  	<menu_item_call label="Byg" name="Build"/>  	<menu_item_call label="Åben" name="Open"/> diff --git a/indra/newview/skins/default/xui/da/panel_nearby_media.xml b/indra/newview/skins/default/xui/da/panel_nearby_media.xml index 7d25b2af99..a269e35f4b 100644 --- a/indra/newview/skins/default/xui/da/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/da/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Navn" name="media_name"/>  			<scroll_list.columns label="Debug" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Stop valgte medie"/> diff --git a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml index 070b4218a8..b1ec2c44df 100644 --- a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profil for genstand"/>  	<text name="origin" value="(Beholdning)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Navn:  		</text> diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml index 8bb7b66482..756b606d65 100644 --- a/indra/newview/skins/default/xui/de/menu_object.xml +++ b/indra/newview/skins/default/xui/de/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Berühren" name="Object Touch"/> +	<menu_item_call label="Berühren" name="Object Touch"> +		<on_enable parameter="Berühren" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Bearbeiten" name="Edit..."/>  	<menu_item_call label="Bauen" name="Build"/>  	<menu_item_call label="Öffnen" name="Open"/> diff --git a/indra/newview/skins/default/xui/de/panel_nearby_media.xml b/indra/newview/skins/default/xui/de/panel_nearby_media.xml index e7886fa149..ef66148902 100644 --- a/indra/newview/skins/default/xui/de/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/de/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Name" name="media_name"/>  			<scroll_list.columns label="Fehler beseitigen" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Ausgewählte Medien stoppen"/> diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml index 63e7bce8ae..b9ca969ac5 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Objektprofil"/>  	<text name="origin" value="(Inventar)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Name:  		</text> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 68e36ff0b3..99bf3e6bc1 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1472,8 +1472,10 @@ Only large parcels can be listed in search.               left="14"               name="MatureCheck"               top="177" +             label_text.valign="center"  +             label_text.v_pad="-5"                tool_tip=" " -             width="107" /> +             width="200" />              <text               type="string"               length="1" diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml index 0ad4fbc967..c88de878f4 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml @@ -529,13 +529,14 @@ sold with objects       length="1"       follows="top|left"       font="SansSerifBig" -     height="16" +     height="32"       layout="topleft"       left="72"       name="account_action"       right="438"       top="200" -     width="218"> +     width="218" +     wrap="true">          Upgrade you to premium membership.      </text>      <text @@ -577,19 +578,21 @@ sold with objects       layout="topleft"       left="0"       name="step_2" +     top_pad="-10"       width="64" />      <text       type="string"       length="1"       follows="top|left"       font="SansSerifBig" -     height="16" +     height="32"       layout="topleft"       left="72"       name="land_use_action"       right="438"       top="284" -     width="218"> +     width="218" +     wrap="true">          Increase your monthly land use fees to US$ 40/month.      </text>      <text @@ -620,14 +623,15 @@ This parcel is 512 m² of land.      <text       type="string"       length="1" -     bottom_delta="-38" +     bottom_delta="-22"       follows="top|left"       font="SansSerifBig" -     height="16" +     height="32"       layout="topleft"       left="72"       name="purchase_action" -     right="438"> +     right="438" +     wrap="true">          Pay Joe Resident L$ 4000 for the land      </text>      <text @@ -665,7 +669,7 @@ This parcel is 512 m² of land.       layout="topleft"       left="170"       name="currency_amt" -     top="408" +     top="424"       width="80">          1000      </line_editor> @@ -681,7 +685,7 @@ This parcel is 512 m² of land.       layout="topleft"       left="260"       name="currency_est" -     top="409" +     top="425"       width="178">          for approx. [LOCAL_AMOUNT]      </text> @@ -713,7 +717,7 @@ This parcel is 512 m² of land.       layout="topleft"       left="70"       name="buy_btn" -     top="448" +     top="460"       width="100" />      <button       follows="bottom|right" diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml index 6281bc5272..7be9cfbb71 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml @@ -162,12 +162,16 @@       top_delta="15"       width="180">          <scroll_list.rows +         name="action_animation"           value="Animation" />          <scroll_list.rows +         name="action_sound"           value="Sound" />          <scroll_list.rows +         name="action_chat"           value="Chat" />          <scroll_list.rows +         name="action_wait"           value="Wait" />      </scroll_list>      <button diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index a59db1420f..20629018e2 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -395,7 +395,7 @@      <panel       follows="right|top|bottom" -	 height="310" +	 height="330"  	 top_pad="0"  	 width="238"  	 name="layout_panel_4"> @@ -534,7 +534,66 @@  		<scroll_list.commit_callback  		function="WMap.SearchResult" />      </scroll_list> -    <button +      <text +      type="string" +      length="1" +      follows="right|bottom" +      halign="right" +      height="16" +      layout="topleft" +      left="25" +      name="events_label" +      top_pad="16" +      width="70"> +      Location: +      </text> +      <spinner +        control_name="Teleport_Coordinate_X" +        decimal_digits="0" +        follows="right|bottom" +        height="23" +        increment="1" +        initial_value="128" +        layout="topleft" +        left_delta="74" +        max_val="255" +        min_val="0" +        name="teleport_coordinate_x" +        width="44" > +        <spinner.commit_callback  +          function="WMap.Coordinates" /> +      </spinner> +      <spinner +        control_name="Teleport_Coordinate_Y" +        decimal_digits="0" +        follows="right|bottom" +        height="23" +        increment="1" +        initial_value="128" +        layout="topleft" +        left_delta="47" +        max_val="255" +        min_val="0" +        name="teleport_coordinate_y" > +        <spinner.commit_callback +          function="WMap.Coordinates" /> +      </spinner> +      <spinner +        control_name="Teleport_Coordinate_Z" +        decimal_digits="0" +        follows="right|bottom" +        height="23" +        increment="1" +        initial_value="128" +        layout="topleft" +        left_delta="47" +        max_val="255" +        min_val="0" +        name="teleport_coordinate_z"> +        <spinner.commit_callback +          function="WMap.Coordinates" /> +      </spinner> +      <button       follows="right|bottom"       height="23"       image_unselected="PushButton_On" @@ -574,66 +633,6 @@  		<button.commit_callback  		function="WMap.ShowTarget" />      </button> - -<!-- <text -     type="string" -     length="1" -     follows="bottom|right" -     halign="left" -     height="16" -     top_pad="4" -     left="25" -     layout="topleft" -     name="land_sale_label" -     width="250"> -        Location: -    </text> -      <spinner -     decimal_digits="0" -     follows="bottom|right" -     increment="1" -     initial_value="128" -     layout="topleft" -     top_pad="0" -     left="25" -     max_val="255" -     name="spin x" -     tool_tip="X coordinate of location to show on map" -     width="48"> -		<spinner.commit_callback -		function="WMap.CommitLocation" /> -    </spinner> -    <spinner -     decimal_digits="0" -     follows="bottom|right" -     height="16" -     increment="1" -     initial_value="128" -     layout="topleft" -     left_pad="2" -     max_val="255" -     name="spin y" -     tool_tip="Y coordinate of location to show on map" -     top_delta="0" -     width="48" > -		<spinner.commit_callback -		function="WMap.CommitLocation" /> -    </spinner> -    <spinner -     decimal_digits="0" -     follows="bottom|right" -     increment="1" -     initial_value="0" -     layout="topleft" -     left_pad="2" -     max_val="4096" -     name="spin z" -     tool_tip="Z coordinate of location to show on map" -     top_delta="0" -     width="48"> -		<spinner.commit_callback -		function="WMap.CommitLocation" /> -    </spinner>-->      </panel>        <panel      follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 7239b13466..e2348375d5 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -11,8 +11,7 @@           function="Object.Touch" />          <menu_item_call.on_enable           function="Object.EnableTouch" -         name="EnableTouch" -         parameter="Touch" /> +         name="EnableTouch"/>      </menu_item_call>      <!--menu_item_call       label="Stand Up" diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml index 22df02cd7e..8ec7689819 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml @@ -22,7 +22,7 @@      <menu_item_call.on_click       function="InspectObject.Sit"/>      <menu_item_call.on_visible -     function="Object.EnableSit" /> +     function="Object.EnableSit"/>    </menu_item_call>    <menu_item_call     label="Pay" diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index 397e61c97a..b6cc222e96 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -45,10 +45,7 @@          <menu_item_call.on_click           function="Object.SitOrStand" />          <menu_item_call.on_enable -         function="Object.SitVisible" /> -        <menu_item_call.on_enable -         function="Object.EnableSitOrStand" -         name="EnableSitOrStand" /> +         function="Object.EnableSit" />     </menu_item_call>     <menu_item_call       enabled="false" @@ -57,10 +54,7 @@          <menu_item_call.on_click           function="Object.SitOrStand" />          <menu_item_call.on_enable -         function="Object.StandUpVisible" /> -        <menu_item_call.on_enable -         function="Object.EnableSitOrStand" -         name="EnableSitOrStand" /> +         function="Object.EnableStandUp" />     </menu_item_call>     <menu_item_call         label="Object Profile" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 04a8a02ecd..1bb282dff9 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6346,7 +6346,7 @@ Avatar '[NAME]' left as fully loaded.     name="AvatarRezSelfBakeNotification"     type="notifytip">  ( [EXISTENCE] seconds alive ) -You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. +You [ACTION] a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.    </notification>    <notification @@ -6405,11 +6405,14 @@ If you continue to have problems, please visit the [SUPPORT_SITE].  - Your system memory does not meet the minimum requirements.    </global> -<!-- this is alert string from server. the name needs to match entire the server string, and needs to be changed +<!-- these are alert strings from server. the name needs to match entire the server string, and needs to be changed  	whenever the server string changes -->     <global name="You can only set your 'Home Location' on your land or at a mainland Infohub.">  If you own a piece of land, you can make it your home location.  Otherwise, you can look at the Map and find places marked "Infohub".    </global> +  <global name="You died and have been teleported to your home location"> +You died and have been teleported to your home location. +  </global>  </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_classified.xml b/indra/newview/skins/default/xui/en/panel_classified.xml index c8293d3663..e96dbd527c 100644 --- a/indra/newview/skins/default/xui/en/panel_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_classified.xml @@ -25,6 +25,7 @@          [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]      </panel.string>      <texture_picker +     fallback_image="default_land_picture.j2c"       follows="left|top"       height="300"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index b7fd9773f2..e66cf400b4 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -93,6 +93,7 @@           width="275"          >          <texture_picker +         fallback_image="default_land_picture.j2c"           enabled="false"           follows="left|top|right"           height="197" diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml index af3315ebfe..e390b9e836 100644 --- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml @@ -33,7 +33,7 @@      <texture_picker       allow_no_texture="true"       border_enabled="true" -     default_image_name="TabIcon_Places_Large" +     fallback_image="default_land_picture.j2c"       enabled="false"       follows="left|top"       height="80" diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index 9408f193fd..a5c74b08e7 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -78,6 +78,7 @@           top="10"           width="272">        <texture_picker +       fallback_image="default_land_picture.j2c"         follows="left|top|right"         height="197"         width="272" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index dc83b334b5..f50e182313 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -63,6 +63,7 @@       left="0"       width="285">      <texture_picker +     fallback_image="default_land_picture.j2c"       follows="left|top|right"       height="197"       width="272" diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 484617df34..9fb777e0e7 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -242,6 +242,7 @@           max_length="63"           name="description"           prevalidate_callback="ascii" +         select_on_focus="true"           text_color="black"           top_pad="3"           width="290" /> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 6523b0d491..41f2b28004 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -76,19 +76,22 @@ Maximum 200 per group daily         follows="top|left"         height="23"         image_overlay="AddItem_Off" +       image_overlay_alignment="left" +       imgoverlay_label_space="-10" +       label="New Notice"         layout="topleft"         left="5"         name="create_new_notice"         tool_tip="Create a new notice" -       top_delta="-3" -       width="23" /> +       top_delta="0" +       width="93" />       <button       follows="top|left"       height="23"       image_overlay="Refresh_Off"       layout="topleft"       name="refresh_notices" -     left_pad="230" +     left="260"       tool_tip="Refresh list of notices"       top_delta="0"       width="23" /> @@ -113,7 +116,7 @@ Maximum 200 per group daily           mouse_opaque="false"           name="lbl"           text_color="EmphasisColor" -         top="0" +         top="5"           width="200">              Create a Notice          </text> @@ -270,7 +273,7 @@ Maximum 200 per group daily           mouse_opaque="false"           name="lbl"           text_color="EmphasisColor" -         top_pad="0" +         top_pad="5"           width="265">              Archived Notice          </text> diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 0eb5c47f85..18a2f37ba2 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -50,6 +50,10 @@ Select multiple Members by holding the Ctrl key and  clicking on their names.              </panel.string>              <panel.string +             name="donation_area"> +                [AREA] m² +            </panel.string> +            <panel.string               name="power_folder_icon" translate="false">                  Inv_FolderClosed              </panel.string> diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml index 1083f4d467..2e49fc8d6f 100644 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml @@ -141,6 +141,7 @@                 allow_no_texture="true"                 default_image_name="None"                 enabled="false" +               fallback_image="Generic_Person_Large"                 follows="top|left"                 height="124"                 layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml index d8675b3512..a4cac97af6 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml @@ -185,6 +185,7 @@  		bevel_style="in"  		background_visible="false"   		follows="left|right|bottom" +		name="media_controls_panel"  		top_pad="5"  		height="30"  		left="10" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 1d01bcb8a5..f6f1c33fe3 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -55,6 +55,7 @@       left="0"       width="285">          <texture_picker +         fallback_image="default_land_picture.j2c"           enabled="false"           follows="left|top|right"           height="197" diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 41651edaa0..292bd47207 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -33,7 +33,7 @@      <texture_picker       allow_no_texture="true"       border_enabled="true" -     default_image_name="TabIcon_Places_Large" +     fallback_image="default_land_picture.j2c"       enabled="false"       follows="left|top"       height="80" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 65c78ad333..aa760edad3 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -408,6 +408,14 @@          name="default_text">          Default        </panel.string> +      <panel.string +        name="default system device"> +        Default system device +      </panel.string> +      <panel.string +        name="no device"> +        No device +      </panel.string>        <icon               height="18"               image_name="Microphone_On" diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index daa4356c83..b48c5d1f8a 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -5,8 +5,6 @@       background_visible="true"       bg_alpha_color="DkGray">           <accordion -     no_matched_tabs_text.value="Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]." -     no_visible_tabs_text.value="Teleport history is empty. Try [secondlife:///app/search/places/ Search]."       follows="left|top|right|bottom"       height="373"       layout="topleft" @@ -16,6 +14,12 @@       background_visible="true"       bg_alpha_color="DkGray2"       width="307"> +        <no_matched_tabs_text +         name="no_matched_teleports_msg" +         value="Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]." /> +        <no_visible_tabs_text +         name="no_teleports_msg" +         value="Teleport history is empty. Try [secondlife:///app/search/places/ Search]." />  	    <accordion_tab           layout="topleft"           name="today" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 50df227fbf..49b252174c 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -80,10 +80,11 @@  	<panel           follows="all"           height="493" +         help_topic=""           label=""           layout="topleft"           left="9" -         help_topic="" +         name="item_profile"           top="45"           width="313"     background_visible="true" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0c31fda68b..20d49fac04 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -278,6 +278,7 @@  	<!-- world map -->  	<string name="texture_loading">Loading...</string>  	<string name="worldmap_offline">Offline</string> +	<string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>  	<string name="worldmap_results_none_found">None found.</string>  	<!-- animations uploading status codes --> @@ -1913,6 +1914,7 @@ Clears (deletes) the media and all params from the given face.  	<string name="AnimFlagStop"  value=" Stop Animation :    " />  	<string name="AnimFlagStart" value=" Start Animation :   " />  	<string name="Wave"          value=" Wave " /> +	<string name="GestureActionNone" value="None" />  	<string name="HelloAvatar"   value=" Hello, avatar! " />  	<string name="ViewAllGestures"  value="  View All >>" />  	<string name="GetMoreGestures"  value="  Get More >>" /> @@ -1957,6 +1959,7 @@ Clears (deletes) the media and all params from the given face.  	<string name="InvFolder Gestures">Gestures</string>  	<string name="InvFolder Favorite">Favorites</string>  	<string name="InvFolder Current Outfit">Current Outfit</string> +	<string name="InvFolder Initial Outfits">Initial Outfits</string>  	<string name="InvFolder My Outfits">My Outfits</string>  	<string name="InvFolder Accessories">Accessories</string> @@ -2097,6 +2100,7 @@ Clears (deletes) the media and all params from the given face.  	<string name="SummaryForTheWeek"    value="Summary for this week, beginning on " />  	<string name="NextStipendDay"       value="The next stipend day is " />  	<string name="GroupIndividualShare" value="                      Group       Individual Share" /> +	<string name="GroupColumn"          value="                      Group" />  	<string name="Balance">Balance</string>  	<string name="Credits">Credits</string>  	<string name="Debits">Debits</string> @@ -3140,6 +3144,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <string name="group_role_everyone">Everyone</string>    <string name="group_role_officers">Officers</string>    <string name="group_role_owners">Owners</string> +  <string name="group_member_status_online">Online</string>    <string name="uploading_abuse_report">Uploading... @@ -3162,7 +3167,9 @@ Abuse Report</string>    <string name="New Alpha">New Alpha</string>    <string name="New Tattoo">New Tattoo</string>    <string name="Invalid Wearable">Invalid Wearable</string> +  <string name="New Gesture">New Gesture</string>    <string name="New Script">New Script</string> +  <string name="New Note">New Note</string>    <string name="New Folder">New Folder</string>    <string name="Contents">Contents</string>    <string name="Gesture">Gesture</string> @@ -3184,13 +3191,20 @@ Abuse Report</string>    <string name="Male - Stick tougue out">Male - Stick tougue out</string>    <string name="Male - Wow">Male - Wow</string> +  <string name="Female - Chuckle">Female - Chuckle</string> +  <string name="Female - Cry">Female - Cry</string> +  <string name="Female - Embarrassed">Female - Embarrassed</string>    <string name="Female - Excuse me">Female - Excuse me</string>    <string name="Female - Get lost">Female - Get lost</string>    <string name="Female - Blow kiss">Female - Blow kiss</string>    <string name="Female - Boo">Female - Boo</string>    <string name="Female - Bored">Female - Bored</string>    <string name="Female - Hey">Female - Hey</string> +  <string name="Female - Hey baby">Female - Hey baby</string>    <string name="Female - Laugh">Female - Laugh</string> +  <string name="Female - Looking good">Female - Looking good</string> +  <string name="Female - Over here">Female - Over here</string> +  <string name="Female - Please">Female - Please</string>    <string name="Female - Repulsed">Female - Repulsed</string>    <string name="Female - Shrug">Female - Shrug</string>    <string name="Female - Stick tougue out">Female - Stick tougue out</string> @@ -3223,4 +3237,23 @@ Abuse Report</string>    <string name="dateTimeDayFormat">[MDAY]</string>    <string name="dateTimeAM">AM</string>    <string name="dateTimePM">PM</string> + +  <!--  currency formatting --> +  <string name="LocalEstimateUSD">US$ [AMOUNT]</string> + +  <!-- Group Profile roles and powers --> +  <string name="Membership">Membership</string> +  <string name="Roles">Roles</string> +  <string name="Group Identity">Group Identity</string> +  <string name="Parcel Management">Parcel Management</string> +  <string name="Parcel Identity">Parcel Identity</string> +  <string name="Parcel Settings">Parcel Settings</string> +  <string name="Parcel Powers">Parcel Powers</string> +  <string name="Parcel Access">Parcel Access</string> +  <string name="Parcel Content">Parcel Content</string> +  <string name="Object Management">Object Management</string> +  <string name="Accounting">Accounting</string> +  <string name="Notices">Notices</string> +  <string name="Chat">Chat</string> +    </strings> diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml index 19f8234389..1a66f0f5c5 100644 --- a/indra/newview/skins/default/xui/en/widgets/accordion.xml +++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml @@ -3,6 +3,12 @@   height="100"   name="accordion"   width="200"> +  <!-- It is possible to override attributes of "no_matched_tabs_text" and "no_visible_tabs_text" with a short form: +    no_matched_tabs_text.value="Overridden text" (placed among <accordion> attributes) +    But unfortunatly such form is not supported by VLT Tool. It requires to have the overridden "value" +    attribute declared in tags below ("no_matched_tabs_text" & "no_visible_tabs_text"). +    It looks less clean but we have to use "long" form for these messages to enable automated translation with VLT. +  -->      <no_matched_tabs_text       follows="all"       height="100" diff --git a/indra/newview/skins/default/xui/es/menu_object.xml b/indra/newview/skins/default/xui/es/menu_object.xml index d2743cd4fc..060d806c55 100644 --- a/indra/newview/skins/default/xui/es/menu_object.xml +++ b/indra/newview/skins/default/xui/es/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Tocar" name="Object Touch"/> +	<menu_item_call label="Tocar" name="Object Touch"> +		<on_enable parameter="Tocar" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Editar" name="Edit..."/>  	<menu_item_call label="Construir" name="Build"/>  	<menu_item_call label="Abrir" name="Open"/> diff --git a/indra/newview/skins/default/xui/es/panel_nearby_media.xml b/indra/newview/skins/default/xui/es/panel_nearby_media.xml index b78ecd0cd0..f03338e4c7 100644 --- a/indra/newview/skins/default/xui/es/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/es/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nombre" name="media_name"/>  			<scroll_list.columns label="Depurar" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Parar los media seleccionados"/> diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml index 38f43c3cbc..d3b91e7a71 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Perfil del elemento"/>  	<text name="origin" value="(Inventario)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nombre:  		</text> diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml index 4eaff8535e..b3acc83078 100644 --- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml @@ -22,10 +22,10 @@ le Lindex...  	<text name="currency_action">  		Je veux acheter  	</text> -	<text name="currency_label"> +	<text name="currency_label" left="308">  		L$  	</text> -	<line_editor label="L$" name="currency_amt" width="65"> +	<line_editor label="L$" name="currency_amt" width="65" left_pad="-85">  		1234  	</line_editor>  	<text name="buying_label"> diff --git a/indra/newview/skins/default/xui/fr/floater_water.xml b/indra/newview/skins/default/xui/fr/floater_water.xml index 96723b0fe6..7d1e3cd65c 100644 --- a/indra/newview/skins/default/xui/fr/floater_water.xml +++ b/indra/newview/skins/default/xui/fr/floater_water.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <floater name="Water Floater" title="ÉDITEUR D'EAU AVANCÉ">  	<floater.string name="WLDefaultWaterNames"> -		Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez +		Valeur par défaut:Transparente:Bassin:Trouble:Première plaie:SERPENT !!!:Valdez  	</floater.string>  	<text name="KeyFramePresetsText" width="120">  		Préréglages : diff --git a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml index 74f1697449..657e5f5051 100644 --- a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml @@ -184,6 +184,6 @@  		</panel>  	</tab_container>  	<string name="WLDefaultSkyNames"> -		A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality +		A-Minuit:A-Midi:A-3h:A-15h:A-16h30:A-6h:A-18h:A-9h:A-21h:Barcelone:Blizzard:Bleu mi-journée:Après-midi sur la côte:Coucher de soleil (côte):Valeur par défaut:Coucher de soleil (désert):Belle journée:Gros nuages floconneux:Brumeux:Funky Funky:Funky Funky Funky:Gelatto:Fantôme:Vérités incohérentes:Mi-journée 1:Mi-journée 2:Mi-journée 3:Mi-journée 4:Nuit:Pirate:Mauve:Rêve de navigateur:Sensualité pure  	</string>  </floater> diff --git a/indra/newview/skins/default/xui/fr/menu_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml index 576fc66d46..257c44795f 100644 --- a/indra/newview/skins/default/xui/fr/menu_object.xml +++ b/indra/newview/skins/default/xui/fr/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Toucher" name="Object Touch"/> +	<menu_item_call label="Toucher" name="Object Touch"> +		<on_enable parameter="Toucher" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Modifier" name="Edit..."/>  	<menu_item_call label="Construire" name="Build"/>  	<menu_item_call label="Ouvrir" name="Open"/> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml index 0a5680fe06..0350ea5116 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profil de l'article"/>  	<text name="origin" value="(inventaire)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nom :  		</text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 0a269016f5..7aadaed209 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -1472,7 +1472,7 @@  		Solde  	</string>  	<string name="Credits"> -		Remerciements +		Crédits  	</string>  	<string name="Debits">  		Débits @@ -1787,7 +1787,7 @@  		Solde  	</string>  	<string name="GroupMoneyCredits"> -		Remerciements +		Crédits  	</string>  	<string name="GroupMoneyDebits">  		Débits @@ -3859,4 +3859,5 @@ de l'infraction signalée  	<string name="dateTimePM">  		PM  	</string> +	<string name="LocalEstimateUSD">[AMOUNT] US$</string>   </strings> diff --git a/indra/newview/skins/default/xui/it/menu_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml index 237b6b3a0e..81f27ab8fa 100644 --- a/indra/newview/skins/default/xui/it/menu_object.xml +++ b/indra/newview/skins/default/xui/it/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Tocca" name="Object Touch"/> +	<menu_item_call label="Tocca" name="Object Touch"> +		<on_enable parameter="Tocca" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Modifica" name="Edit..."/>  	<menu_item_call label="Costruisci" name="Build"/>  	<menu_item_call label="Apri" name="Open"/> diff --git a/indra/newview/skins/default/xui/it/panel_nearby_media.xml b/indra/newview/skins/default/xui/it/panel_nearby_media.xml index bec36fd427..40312f76b4 100644 --- a/indra/newview/skins/default/xui/it/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/it/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nome" name="media_name"/>  			<scroll_list.columns label="Debug" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Interrompi supporto selezionato"/> diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml index d0ec943e67..627aeb5cb5 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profilo articolo"/>  	<text name="origin" value="(Inventario)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nome:  		</text> diff --git a/indra/newview/skins/default/xui/ja/menu_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml index e59a500534..be25a2932e 100644 --- a/indra/newview/skins/default/xui/ja/menu_object.xml +++ b/indra/newview/skins/default/xui/ja/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="触る" name="Object Touch"/> +	<menu_item_call label="触る" name="Object Touch"> +		<on_enable parameter="触る" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="編集" name="Edit..."/>  	<menu_item_call label="制作" name="Build"/>  	<menu_item_call label="開く" name="Open"/> diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml index b3df3503bb..07293e6c79 100644 --- a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="名前" name="media_name"/>  			<scroll_list.columns label="デバッグ" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="選択したメディアを停止"/> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml index fdabe88362..414eba0509 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="アイテムのプロフィール"/>  	<text name="origin" value="(持ち物)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			名前:  		</text> diff --git a/indra/newview/skins/default/xui/pl/menu_object.xml b/indra/newview/skins/default/xui/pl/menu_object.xml index 763b120f89..f25495e8e6 100644 --- a/indra/newview/skins/default/xui/pl/menu_object.xml +++ b/indra/newview/skins/default/xui/pl/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Dotknij" name="Object Touch"/> +	<menu_item_call label="Dotknij" name="Object Touch"> +		<on_enable parameter="Dotknij" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Edytuj" name="Edit..."/>  	<menu_item_call label="Buduj" name="Build"/>  	<menu_item_call label="Otwórz" name="Open"/> diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml index 86c7275e79..926ca806ac 100644 --- a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nazwa" name="media_name"/>  			<scroll_list.columns label="Debugowanie" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Wyłącz wybrane media"/> diff --git a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml index 2f43e0c215..0c6169c9c0 100644 --- a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profil obiektu"/>  	<text name="origin" value="(Szafa)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nazwa:  		</text> diff --git a/indra/newview/skins/default/xui/pt/menu_object.xml b/indra/newview/skins/default/xui/pt/menu_object.xml index a5969cacc3..cd1a72b896 100644 --- a/indra/newview/skins/default/xui/pt/menu_object.xml +++ b/indra/newview/skins/default/xui/pt/menu_object.xml @@ -1,6 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Tocar" name="Object Touch"/> +	<menu_item_call label="Tocar" name="Object Touch"> +		<on_enable parameter="Tocar" name="EnableTouch"/> +	</menu_item_call>  	<menu_item_call label="Editar" name="Edit..."/>  	<menu_item_call label="Construir" name="Build"/>  	<menu_item_call label="Abrir" name="Open"/> diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml index 672b8e6735..7d1b48ad76 100644 --- a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nome" name="media_name"/>  			<scroll_list.columns label="Depurar" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Parar mídia selecionada"/> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml index 8e880588e9..d2050f4660 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Perfil do item"/>  	<text name="origin" value="(Inventário)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nome:  		</text> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 1c29feec5f..347a5e8ab8 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -226,6 +226,16 @@ S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& resp  	return response.asInteger();  } +//----------------------------------------------------------------------------- +#include "../llmachineid.h" +unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2}; + +S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) +{ +	memcpy(unique_id, gMACAddress, len); +	return 1; +} +//-----------------------------------------------------------------------------  // misc  std::string xml_escape_string(const std::string& in)  { | 
