diff options
| author | Tofu Linden <tofu.linden@lindenlab.com> | 2010-07-26 10:34:39 +0100 | 
|---|---|---|
| committer | Tofu Linden <tofu.linden@lindenlab.com> | 2010-07-26 10:34:39 +0100 | 
| commit | 44d0fd81ee3d26a80068713182ac19885ea40f95 (patch) | |
| tree | 96577339efce5ccb30dc3968ebb3ee2bd9ea4155 | |
| parent | d6726e6e4b40efaee35b8df5ac9d1098f208bcac (diff) | |
| parent | fe91462d6277251dbcc6053bc8ecd54dd93a13f0 (diff) | |
(hairy) merge from viewer-release
75 files changed, 1032 insertions, 416 deletions
| diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp index cf509bee14..689f649d0a 100644 --- a/indra/llcommon/llformat.cpp +++ b/indra/llcommon/llformat.cpp @@ -37,16 +37,40 @@  #include <cstdarg> -std::string llformat(const char *fmt, ...) +// common used function with va_list argument +// wrapper for vsnprintf to be called from llformatXXX functions. +static void va_format(std::string& out, const char *fmt, va_list va)  {  	char tstr[1024];	/* Flawfinder: ignore */ -	va_list va; -	va_start(va, fmt);  #if LL_WINDOWS  	_vsnprintf(tstr, 1024, fmt, va);  #else  	vsnprintf(tstr, 1024, fmt, va);	/* Flawfinder: ignore */  #endif +	out.assign(tstr); +} + +std::string llformat(const char *fmt, ...) +{ +	std::string res; +	va_list va; +	va_start(va, fmt); +	va_format(res, fmt, va);  	va_end(va); -	return std::string(tstr); +	return res; +} + +std::string llformat_to_utf8(const char *fmt, ...) +{ +	std::string res; +	va_list va; +	va_start(va, fmt); +	va_format(res, fmt, va); +	va_end(va); + +#if LL_WINDOWS +	// made converting to utf8. See EXT-8318. +	res = ll_convert_string_to_utf8_string(res); +#endif +	return res;  } diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h index dc64edb26d..17d8b4a8ad 100644 --- a/indra/llcommon/llformat.h +++ b/indra/llcommon/llformat.h @@ -42,4 +42,8 @@  std::string LL_COMMON_API llformat(const char *fmt, ...); +// the same version as above but ensures that returned string is in utf8 on windows +// to enable correct converting utf8_to_wstring. +std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...); +  #endif // LL_LLFORMAT_H diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 1561bda201..671b0a108c 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -633,14 +633,14 @@ namespace snprintf_hack  	}  } -std::string ll_convert_wide_to_string(const wchar_t* in) +std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)  {  	std::string out;  	if(in)  	{  		int len_in = wcslen(in);  		int len_out = WideCharToMultiByte( -			CP_ACP, +			code_page,  			0,  			in,  			len_in, @@ -655,7 +655,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in)  		if(pout)  		{  			WideCharToMultiByte( -				CP_ACP, +				code_page,  				0,  				in,  				len_in, @@ -669,6 +669,38 @@ std::string ll_convert_wide_to_string(const wchar_t* in)  	}  	return out;  } + +wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page) +{ +	// From review: +	// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
 +	// plus one for a null terminator, and be guaranteed to not overflow.
 +
 +	//	Normally, I'd call that sort of thing premature optimization, +	// but we *are* seeing string operations taking a bunch of time, especially when constructing widgets. +//	int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0); + +	// reserve place to NULL terminator +	int output_str_len = in.length(); +	wchar_t* w_out = new wchar_t[output_str_len + 1]; + +	memset(w_out, 0, output_str_len + 1); +	int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len); + +	//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. +	w_out[real_output_str_len] = 0; + +	return w_out; +} + +std::string ll_convert_string_to_utf8_string(const std::string& in) +{ +	wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP); +	std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8)); +	delete[] w_mesg; + +	return out_utf8; +}  #endif // LL_WINDOWS  long LLStringOps::sPacificTimeOffset = 0; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 8071c8aa2d..41fac0f8cc 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -564,7 +564,20 @@ using snprintf_hack::snprintf;   *   * This replaces the unsafe W2A macro from ATL.   */ -LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); +LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page); + +/** + * Converts a string to wide string. + * + * It will allocate memory for result string with "new []". Don't forget to release it with "delete []". + */ +LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page); + +/** + * Converts incoming string into urf8 string + * + */ +LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);  //@}  #endif // LL_WINDOWS diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 36874a5d48..ac50411de8 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -364,13 +364,6 @@ U32 LLCurl::Easy::report(CURLcode code)  		responseCode = 499;  		responseReason = strerror(code) + " : " + mErrorBuffer;  	} -		 -	if(responseCode >= 300 && responseCode < 400) //redirect -	{ -		char new_url[512] ; -		curl_easy_getinfo(mCurlEasyHandle, CURLINFO_REDIRECT_URL, new_url); -		responseReason = new_url ; //get the new URL. -	}  	if (mResponder)  	{	 @@ -469,6 +462,13 @@ void LLCurl::Easy::prepRequest(const std::string& url,  	setopt(CURLOPT_HEADERFUNCTION, (void*)&curlHeaderCallback);  	setopt(CURLOPT_HEADERDATA, (void*)this); +	// Allow up to five redirects +	if(responder && responder->followRedir()) +	{ +		setopt(CURLOPT_FOLLOWLOCATION, 1); +		setopt(CURLOPT_MAXREDIRS, MAX_REDIRECTS); +	} +  	setErrorBuffer();  	setCA(); @@ -1061,3 +1061,4 @@ void LLCurl::cleanupClass()  	curl_global_cleanup();  } +const unsigned int LLCurl::MAX_REDIRECTS = 5; diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index b6a637ae5b..20ca87c87b 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -123,6 +123,11 @@ public:  			// Used internally to set the url for debugging later.  			void setURL(const std::string& url); +			virtual bool followRedir()  +			{ +				return false; +			} +  	public: /* but not really -- don't touch this */  		U32 mReferenceCount; @@ -182,6 +187,7 @@ public:  private:  	static std::string sCAPath;  	static std::string sCAFile; +	static const unsigned int MAX_REDIRECTS;  };  namespace boost diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e22f8d2ddc..1a48c8a06c 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -109,11 +109,20 @@ void LLImageGL::checkTexSize(bool forced) const  {  	if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D)  	{ +		{ +			//check viewport +			GLint vp[4] ; +			glGetIntegerv(GL_VIEWPORT, vp) ; +			llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ; +		} +  		GLint texname;  		glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);  		BOOL error = FALSE;  		if (texname != mTexName)  		{ +			llinfos << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << llendl; +  			error = TRUE;  			if (gDebugSession)  			{ diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 673631f99a..2bc8ea054a 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -811,6 +811,31 @@ void	LLAccordionCtrl::reset		()  		mScrollbar->setDocPos(0);  } +void LLAccordionCtrl::expandDefaultTab() +{ +	if (mAccordionTabs.size() > 0) +	{ +		LLAccordionCtrlTab* tab = mAccordionTabs.front(); + +		if (!tab->getDisplayChildren()) +		{ +			tab->setDisplayChildren(true); +		} + +		for (size_t i = 1; i < mAccordionTabs.size(); ++i) +		{ +			tab = mAccordionTabs[i]; + +			if (tab->getDisplayChildren()) +			{ +				tab->setDisplayChildren(false); +			} +		} + +		arrange(); +	} +} +  void LLAccordionCtrl::sort()  {  	if (!mTabComparator) diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index b5fdf796cd..8241ee1518 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -122,6 +122,7 @@ public:  	S32		notifyParent(const LLSD& info);  	void	reset		(); +	void	expandDefaultTab();  	void	setComparator(const LLTabComparator* comp) { mTabComparator = comp; }  	void	sort(); diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 3d32157406..0c524cd470 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -81,17 +81,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)  	// must be big enough to hold all children  	setUseBoundingRect(TRUE); -	// Label (add a little space to make sure text actually renders) -	const S32 FUDGE = 10; -	S32 text_width = mFont->getWidth( p.label ) + FUDGE; -	S32 text_height = llround(mFont->getLineHeight()); -	LLRect label_rect; -	label_rect.setOriginAndSize( -		llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, -		llcheckboxctrl_vpad + 1, // padding to get better alignment -		text_width + llcheckboxctrl_hpad, -		text_height ); -  	// *HACK Get rid of this with SL-55508...   	// this allows blank check boxes and radio boxes for now  	std::string local_label = p.label; @@ -101,7 +90,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)  	}  	LLTextBox::Params tbparams = p.label_text; -	tbparams.rect(label_rect);  	tbparams.initial_value(local_label);  	if (p.font.isProvided())  	{ @@ -111,6 +99,17 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)  	mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);  	addChild(mLabel); +	S32 text_width = mLabel->getTextBoundingRect().getWidth(); +	S32 text_height = llround(mFont->getLineHeight()); +	LLRect label_rect; +	label_rect.setOriginAndSize( +		llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, +		llcheckboxctrl_vpad + 1, // padding to get better alignment +		text_width + llcheckboxctrl_hpad, +		text_height ); +	mLabel->setShape(label_rect); + +  	// Button  	// Note: button cover the label by extending all the way to the right.  	LLRect btn_rect; @@ -190,8 +189,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  	static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);  	static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0); -	const S32 FUDGE = 10; -	S32 text_width = mFont->getWidth( mLabel->getText() ) + FUDGE; +	S32 text_width = mLabel->getTextBoundingRect().getWidth();  	S32 text_height = llround(mFont->getLineHeight());  	LLRect label_rect;  	label_rect.setOriginAndSize( @@ -199,7 +197,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  		llcheckboxctrl_vpad,  		text_width,  		text_height ); -	mLabel->setRect(label_rect); +	mLabel->setShape(label_rect);  	LLRect btn_rect;  	btn_rect.setOriginAndSize( @@ -207,7 +205,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  		llcheckboxctrl_vpad,  		llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width,  		llmax( text_height, llcheckboxctrl_btn_size() ) ); -	mButton->setRect( btn_rect ); +	mButton->setShape( btn_rect );  	LLUICtrl::reshape(width, height, called_from_parent);  } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 39a6855273..22d6f6ca52 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -451,6 +451,14 @@ void LLFloater::enableResizeCtrls(bool enable)  	}  } +void LLFloater::destroy() +{ +	// LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before +	// it was deleted via LLMortician::updateClass(). See EXT-8458. +	LLFloaterReg::removeInstance(mInstanceName, mKey); +	die(); +} +  // virtual  LLFloater::~LLFloater()  { diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3ea035777c..42f422f91c 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -308,7 +308,7 @@ protected:  	BOOL			getAutoFocus() const { return mAutoFocus; }  	LLDragHandle*	getDragHandle() const { return mDragHandle; } -	void			destroy() { die(); } // Don't call this directly.  You probably want to call closeFloater() +	void			destroy(); // Don't call this directly.  You probably want to call closeFloater()  	virtual	void	onClickCloseBtn(); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index b4a1bcb7c5..8610d79142 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -218,6 +218,12 @@ void LLMenuItemGL::setValue(const LLSD& value)  }  //virtual +LLSD LLMenuItemGL::getValue() const +{ +	return getLabel(); +} + +//virtual  BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)  {  	if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 7668f301ea..a484405eaa 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -95,6 +95,7 @@ public:  	// LLUICtrl overrides  	/*virtual*/ void setValue(const LLSD& value); +	/*virtual*/ LLSD getValue() const;  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask); diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index ed870d46d5..9158bc70f5 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -298,11 +298,11 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const  		{  			if (fraction == remaining_count)  			{ -				fraction_string = llformat("%d%c", fraction, getThousandsSeparator()); +				fraction_string = llformat_to_utf8("%d%c", fraction, getThousandsSeparator());  			}  			else  			{ -				fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator()); +				fraction_string = llformat_to_utf8("%3.3d%c", fraction, getThousandsSeparator());  			}  			output = fraction_string + output;  		} diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 53b7febba7..e85d108bb2 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3079,7 +3079,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *  		return;  	} -	if (gAgentCamera.cameraCustomizeAvatar()) +	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  	{  		// ignore baked textures when in customize mode  		return; @@ -3548,7 +3548,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/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index d2449abf08..b64007aa75 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1801,9 +1801,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) @@ -2699,6 +2699,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; @@ -2726,3 +2741,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 21766a731d..d222d94ec6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -357,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(); 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 35a1ad747b..01932949e4 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -284,7 +284,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),  	mAttachmentsTab(NULL),  	mBodyPartsTab(NULL),  	mLastSelectedTab(NULL), -	mCOFVersion(-1) +	mCOFVersion(-1), +	mAccordionCtrl(NULL)  {  	mClothingMenu = new CofClothingContextMenu(this);  	mAttachmentMenu = new CofAttachmentContextMenu(this); @@ -336,6 +337,8 @@ BOOL LLCOFWearables::postBuild()  	mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT;  	mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART; +	mAccordionCtrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); +  	return LLPanel::postBuild();  } @@ -652,18 +655,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() +{ +	if (mAccordionCtrl != NULL)  	{ -	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); -	const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab(); +		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 d005b75eaa..cd7cc060e5 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; @@ -87,6 +88,7 @@ public:  	LLAssetType::EType getExpandedAccordionAssetType();  	LLAssetType::EType getSelectedAccordionAssetType(); +	void expandDefaultAccordionTab();  	LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; } @@ -125,6 +127,8 @@ protected:  	LLListContextMenu* mAttachmentMenu;  	LLListContextMenu* mBodyPartMenu; +	LLAccordionCtrl*	mAccordionCtrl; +  	/* COF category version since last refresh */  	S32 mCOFVersion;  }; 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/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/llfolderview.h b/indra/newview/llfolderview.h index 3944fa53c9..03e1bb9eee 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -263,6 +263,7 @@ public:  	BOOL needsAutoRename() { return mNeedsAutoRename; }  	void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }  	void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; } +	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }  	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } 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/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index ea57d36c06..b1f5b3be2f 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -96,9 +96,12 @@ void LLPanelInventoryListItemBase::draw()  	if (mSeparatorVisible && mSeparatorImage)  	{ -		// stretch along bottom of listitem, using image height +		// place under bottom of listitem, using image height +		// item_pad in list using the item should be >= image height +		// to avoid cropping of top of the next item.  		LLRect separator_rect = getLocalRect(); -		separator_rect.mTop = mSeparatorImage->getHeight(); +		separator_rect.mTop = separator_rect.mBottom; +		separator_rect.mBottom -= mSeparatorImage->getHeight();  		mSeparatorImage->draw(separator_rect);  	} 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/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 63ffb80ff2..c3eee1d1ad 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,31 @@ 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; + +		if (LLAppearanceMgr::isLinkInCOF(id)) +		{ +			return false; +		} + +		// 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 094769b8f5..ac71069621 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"); @@ -905,7 +943,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);  			} diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 1c980c207e..03b2cb7932 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; @@ -115,6 +116,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 2112c8c026..2fc74e138b 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..445cfe64f7 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1593,6 +1593,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 +1615,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 +1624,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/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 6ab7fd6a2b..6c6f830000 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -421,6 +421,8 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()  	delete mCOFDragAndDropObserver; +	delete mWearableListViewItemsComparator; +  	while (!mListViewItemTypes.empty()) {  		delete mListViewItemTypes.back();  		mListViewItemTypes.pop_back(); @@ -526,12 +528,25 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); +	/* +	 * By default AT_CLOTHING are sorted by (in in MY OUTFITS): +	 *  - by type (types order determined in LLWearableType::EType) +	 *  - each LLWearableType::EType by outer layer on top +	 * +	 * In Add More panel AT_CLOTHING should be sorted in a such way: +	 *  - by type (types order determined in LLWearableType::EType) +	 *  - each LLWearableType::EType by name (EXT-8205) +	*/ +	mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator(); +	mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true); +  	mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel");  	mWearableItemsList = getChild<LLWearableItemsList>("list_view");  	mWearableItemsList->setCommitOnSelectionChange(true);  	mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));  	mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this)); -	mWearableItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("AddWearableSortOrder")); +	mWearableItemsList->setComparator(mWearableListViewItemsComparator); +        mWearableItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("AddWearableSortOrder"));  	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));  	return TRUE; @@ -901,7 +916,9 @@ void LLPanelOutfitEdit::updatePlusButton()  	}  	// If any of the selected items are not wearable (due to already being worn OR being of the wrong type), disable the add button. -	uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1)); +	uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1) +		// since item can be not worn but in wearing process at that time - we need to check is link to item presents in COF +		|| boost::bind(&LLAppearanceMgr::isLinkInCOF, _1));  	bool can_add = ( unwearable_item == selected_items.end() );  	mPlusBtn->setEnabled(can_add); @@ -1149,16 +1166,18 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch  	return false;  } -void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) +void LLPanelOutfitEdit::resetAccordionState()  { -	LLMenuGL* menu = NULL; +	if (mCOFWearables != NULL)  	if (mAddWearablesPanel->getVisible())  	{ -		if (!mAddWearablesGearMenu) -		{ -			mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel); -		} +		mCOFWearables->expandDefaultAccordionTab(); +	} +	else +	{ +		llwarns << "mCOFWearables is NULL" << llendl; +	}  		menu = mAddWearablesGearMenu;  	} diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 93215c5920..fa3c48c3e7 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -64,6 +64,7 @@ class LLMenuGL;  class LLFindNonLinksByMask;  class LLFindWearablesOfType;  class LLSaveOutfitComboBtn; +class LLWearableItemTypeNameComparator;  class LLPanelOutfitEdit : public LLPanel  { @@ -188,6 +189,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, @@ -228,6 +231,7 @@ private:  	LLFilteredWearableListManager* 	mWearableListManager;  	LLWearableItemsList* 			mWearableItemsList;  	LLPanel*						mWearablesListViewPanel; +	LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;  	LLCOFDragAndDropObserver* mCOFDragAndDropObserver; 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/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/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/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 0b02861b75..c0518b705b 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); @@ -597,6 +600,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/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 2d57c16889..9926c8d15f 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -96,6 +96,7 @@ public:  		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"); @@ -935,7 +936,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")); @@ -1172,6 +1173,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) @@ -1194,6 +1203,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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b3fc0df1bf..090b7bba90 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*) @@ -5519,27 +5544,27 @@ bool enable_object_stand_up()  	return sitting_on_selection();  } -bool enable_object_sit() +bool enable_object_sit(LLUICtrl* ctrl)  {  	// '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 !sitting_on_sel && is_object_sittable();  } @@ -8087,7 +8112,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.EnableGearSit", boost::bind(&is_object_sittable));  	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"); @@ -8103,12 +8127,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"); +	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.EnableStandUp", boost::bind(&enable_object_stand_up)); -	enable.add("Object.EnableSit", boost::bind(&enable_object_sit)); +	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 2b6eadcc04..401433e6e1 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);  						}  					} 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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2f63e7ef01..00873a797c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4390,7 +4390,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 9353c6daef..68085b1baf 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4095,9 +4095,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 @@ -4138,7 +4142,7 @@ void LLVOAvatar::updateTextures()  				}  			}  		} -		if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar) +		if (isIndexBakedTexture((ETextureIndex) texture_index))  		{  			const S32 boost_level = getAvatarBakedBoostLevel();  			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); @@ -4172,10 +4176,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) @@ -4195,9 +4200,9 @@ 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();  		iter != mCallbackTextureList.end(); ++iter)  	{ @@ -4207,17 +4212,22 @@ void LLVOAvatar::checkTextureLoading()  			if(pause)//pause texture fetching.  			{  				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(&mCallbackTextureList) ; -				tex->addTextureStats(START_AREA); //jump start the fetching again +				tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;				  			}  		}		  	}			 +	if(!pause) +	{ +		updateTextures() ; //refresh texture stats. +	}  	mLoadedCallbacksPaused = pause ;  	return ;  } @@ -4226,12 +4236,14 @@ const F32  SELF_ADDITIONAL_PRI = 0.75f ;  const F32  ADDITIONAL_PRI = 0.5f;  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);	 @@ -6051,7 +6063,7 @@ void LLVOAvatar::updateMeshTextures()  		}  	} -	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures +	const BOOL self_customizing = isSelf() && !gAgentAvatarp->isUsingBakedTextures(); // 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 ;  	BOOL paused = FALSE; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 83ca299da1..4163810d6c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -1049,6 +1049,7 @@ protected: // Shared with LLVOAvatarSelf   *******************************************************************************/  }; // LLVOAvatar -extern const F32  SELF_ADDITIONAL_PRI; +extern const F32 SELF_ADDITIONAL_PRI; +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 8961d2c285..3a283e7aa6 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,13 +1622,16 @@ 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 @@ -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(SELF_ADDITIONAL_PRI) ;  			imagep->forceUpdateBindStats() ; diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index dfa7ca7136..c5042ca016 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -698,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 b614860b74..d9b2dfbec0 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -465,6 +465,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  { @@ -493,7 +516,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. @@ -505,50 +528,62 @@ 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;  } -/*virtual*/ +bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const  bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const  { -	time_t date1 = item1->getCreationDate(); +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);  	time_t date2 = item2->getCreationDate(); -	if (date1 == date2) +	if(const_it == mWearableOrder.end())  	{ -		return LLWearableItemNameComparator::doCompare(item1, item2); +		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return true;  	} -	return date1 > date2; +	return const_it->second.mSortWearableTypeByName;  }  ////////////////////////////////////////////////////////////////////////// @@ -718,13 +753,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)); diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 55f8996140..84e999cd57 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -307,33 +307,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/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/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 b6f00ef6d1..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.EnableGearSit" /> +     function="Object.EnableSit"/>    </menu_item_call>    <menu_item_call     label="Pay" 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/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e5bd549036..a0c67e3612 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 --> @@ -2102,6 +2103,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> @@ -3141,6 +3143,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... @@ -3165,6 +3168,7 @@ Abuse Report</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> 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/panel_nearby_media.xml b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml index 978ca86d62..1a6101830b 100644 --- a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml @@ -27,7 +27,7 @@  			Médias proches  		</text>  		<text name="show_text"> -			Afficher : +			Voir :  		</text>  		<combo_box name="show_combo">  			<combo_box.item label="Tout" name="All"/> 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)  { diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 2884231299..01c750487e 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -145,7 +145,7 @@ void LLCrashLoggerWindows::ProcessCaption(HWND hWnd)  	TCHAR header[MAX_STRING];  	std::string final;  	GetWindowText(hWnd, templateText, sizeof(templateText)); -	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); +	final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());  	ConvertLPCSTRToLPWSTR(final.c_str(), header);  	SetWindowText(hWnd, header);  } @@ -158,7 +158,7 @@ void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem)  	TCHAR header[MAX_STRING];  	std::string final;  	GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText)); -	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); +	final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());  	ConvertLPCSTRToLPWSTR(final.c_str(), header);  	SetDlgItemText(hWnd, nIDDlgItem, header);  } @@ -201,7 +201,7 @@ bool handle_button_click(WORD button_id)  						wbuffer, // pointer to buffer for text  						20000 // maximum size of string  						); -		std::string user_text(ll_convert_wide_to_string(wbuffer)); +		std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP));  		// Activate and show the window.  		ShowWindow(gHwndProgress, SW_SHOW);   		// Try doing this second to make the progress window go frontmost. | 
