diff options
60 files changed, 830 insertions, 300 deletions
| diff --git a/doc/contributions.txt b/doc/contributions.txt index dbb18f28bf..1f7ab9e056 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -5,11 +5,12 @@ received from them.  To see more about these contributions, visit  http://jira.secondlife.com/ and enter the issue identifier.  Alissa Sabre - VWR-81, VWR-83, VWR-414, VWR-415 +Blakar Ogre - VWR-881  blino Nakamura - VWR-17  bushing Spatula - VWR-424 -Drewan Keats - VWR-28 +Drewan Keats - VWR-28, VWR-412  Dylan Haskell - VWR-72 -Dzonatas Sol - VWR-198 +Dzonatas Sol - VWR-198, VWR-878  Eddy Stryker - VWR-15, VWR-23  Gigs Taggart - VWR-71, VWR-326  Ginko Bayliss - VWR-4 @@ -19,11 +20,14 @@ Jacek Antonelli - VWR-165, VWR-188  Joghert LeSabre - VWR-64  Kage Pixel - VWR-11  Kunnis Basiat - VWR-82 +Nicholaz Beresford - VWR-793, VWR-794, VWR-802, VWR-803, VWR-804, VWR-805, VWR-808, VWR-809, VWR-810, VWR-823, VWR-870  Paul Churchill - VWR-20  Paula Innis - VWR-30  Peekay Semyorka - VWR-7, VWR-19, VWR-49  SignpostMarv Martin - VWR-154, VWR-155 +Simon Nolan - VWR-409  SpacedOut Frye - VWR-57, VWR-94, VWR-121, VWR-123  Strife Onizuka - SVC-9, VWR-74, VWR-85, VWR-148 +Zi Ree - VWR-671, VWR-682  Zipherius Turas - VWR-76, VWR-77 diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 4d4f7ce738..66b675e34d 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -411,6 +411,7 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask)  		LLVector3		up;  		eye_look_at = *targetPos; +		has_eye_target = TRUE;  		F32 lookAtDistance = eye_look_at.normVec();  		left.setVec(skyward % eye_look_at); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 3d4deac673..5964993928 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -227,7 +227,7 @@ namespace  		LOG_CLASS(LogControlFile);  	public: -		static LogControlFile& fromDirectory(const std::string& dir); +		static LogControlFile *fromDirectory(const std::string& dir);  		virtual void loadFile(); @@ -237,7 +237,7 @@ namespace  			{ }  	}; -	LogControlFile& LogControlFile::fromDirectory(const std::string& dir) +	LogControlFile *LogControlFile::fromDirectory(const std::string& dir)  	{  		std::string dirBase = dir + "/";  			// NB: We have no abstraction in llcommon  for the "proper" @@ -253,8 +253,7 @@ namespace  			file = dirBase + "logcontrol.xml";  		} -		return * new LogControlFile(file); -			// NB: This instance is never freed +		return new LogControlFile(file);  	}  	void LogControlFile::loadFile() @@ -298,8 +297,11 @@ namespace  		static Globals& get();  			// return the one instance of the globals +		static void Globals::cleanup(); +  	private:  		CallSiteVector callSites; +		static Globals *sGlobals;  		Globals()  			:	messageStreamInUse(false) @@ -307,6 +309,8 @@ namespace  	}; +	Globals *Globals::sGlobals; +  	void Globals::addCallSite(LLError::CallSite& site)  	{  		callSites.push_back(&site); @@ -332,8 +336,16 @@ namespace  		   is.  		   See C++ FAQ Lite, sections 10.12 through 10.14  		*/ -		static Globals* globals = new Globals;		 -		return *globals; +		if (sGlobals == NULL) { +			sGlobals = new Globals; +		} + +		return *sGlobals; +	} + +	void Globals::cleanup() +	{ +		delete sGlobals;  	}  } @@ -361,6 +373,7 @@ namespace LLError  		int shouldLogCallCounter;  		static Settings& get(); +		static void cleanup();  		static void reset();  		static Settings* saveAndReset(); @@ -391,6 +404,16 @@ namespace LLError  		return *p;  	} +	void Settings::cleanup() +	{ +		Settings*& ptr = getPtr(); +		if (ptr) +		{ +			delete ptr; +			ptr = NULL; +		} +	} +  	void Settings::reset()  	{  		Globals::get().invalidateCallSites(); @@ -469,6 +492,8 @@ namespace  	} +	static LogControlFile *gLogControlFile; +  	void commonInit(const std::string& dir)  	{  		LLError::Settings::reset(); @@ -486,8 +511,8 @@ namespace  		LLError::addRecorder(new RecordToWinDebug);  #endif -		LogControlFile& e = LogControlFile::fromDirectory(dir); -		e.addToEventTimer(); +		gLogControlFile = LogControlFile::fromDirectory(dir); +		gLogControlFile->addToEventTimer();  	}  } @@ -511,6 +536,15 @@ namespace LLError  		commonInit(dir);  	} +	void cleanupLogging(void) +	{ +		delete gLogControlFile; +		gLogControlFile = NULL; + +		Settings::cleanup(); +		Globals::cleanup(); +	} +	  	void setPrintLocation(bool print)  	{  		Settings& s = Settings::get(); diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 84ac0fa7f0..d32469d0c2 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -152,6 +152,9 @@ namespace LLError  	class NoClassInfo { };  		// used to indicate no class info known for logging + +	void cleanupLogging(); +		// after this is called, no more logging is allowed  } diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 0e469e6341..a6b859ad41 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -257,7 +257,7 @@ bool CProcessor::AnalyzeIntelProcessor()  	// Only override the brand if we have it in the lookup table.  We should  	// already have a string here from GetCPUInfo().  JC -	if (CPUInfo.uiBrandID < sizeof(INTEL_BRAND)) +	if (CPUInfo.uiBrandID < (sizeof(INTEL_BRAND)/sizeof(INTEL_BRAND[0])))  	{  		strcpy(CPUInfo.strBrandID, INTEL_BRAND[CPUInfo.uiBrandID]); diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp index 96ee7ff800..325cb2a1f7 100644 --- a/indra/llinventory/llnotecard.cpp +++ b/indra/llinventory/llnotecard.cpp @@ -84,12 +84,6 @@ bool LLNotecard::importEmbeddedItemsStream(std::istream& str)  			goto import_file_failed;  		} -		if( (index < 0) ) -		{ -			llwarns << "Invalid LLEmbeddedItems file format: invalid ext char index: " << index << llendl; -			goto import_file_failed; -		} -  		str >> std::ws >> "inv_item\t0\n";  		if(str.fail())  		{ diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index c469eae33c..32ba4aaaec 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -155,7 +155,7 @@ BOOL LLSaleInfo::importFile(FILE* fp, BOOL& has_perm_mask, U32& perm_mask)  			buffer,  			" %254s %254s",  			keyword, valuestr); -		if(!keyword) +		if(!keyword[0])  		{  			continue;  		} @@ -211,7 +211,7 @@ BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_m  			buffer,  			" %254s %254s",  			keyword, valuestr); -		if(!keyword) +		if(!keyword[0])  		{  			continue;  		} diff --git a/indra/llinventory/lluserrelations.h b/indra/llinventory/lluserrelations.h index 7c24254339..ddf6767b23 100644 --- a/indra/llinventory/lluserrelations.h +++ b/indra/llinventory/lluserrelations.h @@ -18,7 +18,7 @@   * @class LLRelationship   *   * This class represents a relationship between two agents, where the - * related agent is stored and the other agent is the relationship is + * related agent is stored and the other agent in the relationship is   * implicit by container ownership.   * This is merely a cache of this information used by the sim    * and viewer. diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c779a8b714..0d95c0492c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1809,13 +1809,16 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,  				U32 x = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_width);  				U32 y = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_height); -				if (y == sculpt_height)  // clamp to bottom row +				if (y == sculpt_height)  // stitch bottom +				{  					y = sculpt_height - 1; +					x = sculpt_width / 2; +				}  				if (x == sculpt_width)   // stitch sides  					x = 0; -				if ((y == 0) || (y == sculpt_height-1))  // stitch top and bottom +				if (y == 0)  // stitch top  					x = sculpt_width / 2;  				U32 index = (x + y * sculpt_width) * sculpt_components; @@ -1827,63 +1830,69 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,  				last_index = index;  			} +		if ((F32)vertex_change / sizeS / sizeT < 0.05) // less than 5% +			data_is_empty = TRUE;  	} -	 -	if ((F32)vertex_change / sizeS / sizeT < 0.05) // less than 5% -		data_is_empty = TRUE; -	 -	  	//generate vertex positions -	// Run along the path. -	S32 s = 0, t = 0; -	S32 line = 0; -	while (s < sizeS) +	if (data_is_empty) // if empty, make a sphere  	{ -		t = 0; -		// Run along the profile. -		while (t < sizeT) -		{ -			S32 i = t + line; -			Point& pt = mMesh[i]; - -			U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); -			U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); +		S32 line = 0; -			if (y == sculpt_height)  // clamp to bottom row -				y = sculpt_height - 1; - -			if (x == sculpt_width)   // stitch sides -				x = 0; +		for (S32 s = 0; s < sizeS; s++) +		{ +			for (S32 t = 0; t < sizeT; t++) +			{ +				S32 i = t + line; +				Point& pt = mMesh[i]; -			if ((y == 0) || (y == sculpt_height-1))  // stitch top and bottom -				x = sculpt_width / 2; - -			if (data_is_empty) // if empty, make a sphere -			{  				F32 u = (F32)s/(sizeS-1);  				F32 v = (F32)t/(sizeT-1);  				const F32 RADIUS = (F32) 0.3; -				 +					  				pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);  				pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);  				pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); +  			} -			 -			else +			line += sizeT; +		} +	} +	else +	{ +		S32 line = 0; +		for (S32 s = 0; s < sizeS; s++) +		{ +			// Run along the profile. +			for (S32 t = 0; t < sizeT; t++)  			{ +				S32 i = t + line; +				Point& pt = mMesh[i]; + +				U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); +				U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + +				if (y == sculpt_height)  // stitch bottom row +				{ +					y = sculpt_height - 1; +					x = sculpt_width / 2; +				} + +				if (x == sculpt_width)   // stitch sides +					x = 0; + +				if (y == 0)  // stitch top row +					x = sculpt_width / 2; +			  				U32 index = (x + y * sculpt_width) * sculpt_components;  				pt.mPos.mV[0] = sculpt_data[index  ] / 256.f - 0.5f;  				pt.mPos.mV[1] = sculpt_data[index+1] / 256.f - 0.5f;  				pt.mPos.mV[2] = sculpt_data[index+2] / 256.f - 0.5f;  			} - -			t++; +			line += sizeT;  		} -		line += sizeT; -		s++;  	}  	for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 3c8ebaeba1..ffc15d45f7 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -322,6 +322,12 @@ namespace  		}  		return sMainMulti;  	} + +	void freeMulti() +	{ +		delete sMainMulti; +		sMainMulti = NULL; +	}  }  void @@ -342,3 +348,8 @@ LLCurl::process()  	mainMulti()->process();  } +void LLCurl::cleanup() +{ +	freeMulti(); +	curl_global_cleanup(); +} diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 4e45864cae..5335906b47 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -108,6 +108,7 @@ public:  	static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder);  	static void process(); +	static void cleanup();  };  namespace boost diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp index a2b0bc5efa..3cc17d67df 100644 --- a/indra/llmessage/llmessageconfig.cpp +++ b/indra/llmessage/llmessageconfig.cpp @@ -92,9 +92,10 @@ void LLMessageConfigFile::loadServerDefaults(const LLSD& data)  void LLMessageConfigFile::loadMessages(const LLSD& data)  { -	mMessages = data["messages"]; +	LLPointer<LLSDXMLFormatter> formatter = new LLSDXMLFormatter;  	std::ostringstream out; -	LLSDXMLFormatter *formatter = new LLSDXMLFormatter; + +	mMessages = data["messages"];  	formatter->format(mMessages, out);  	lldebugs << "loading ... " << out.str()  			<< " LLMessageConfigFile::loadMessages loaded " diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index dfc18e0b2e..a305797fd2 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -1324,12 +1324,17 @@ LLMessageSystem::~LLMessageSystem()  		end_net();  	} -	delete mMessageReader; +	delete mTemplateMessageReader; +	mTemplateMessageReader = NULL;  	mMessageReader = NULL; -	delete mMessageBuilder; +	delete mTemplateMessageBuilder; +	mTemplateMessageBuilder = NULL;  	mMessageBuilder = NULL; +	delete mLLSDMessageReader; +	mLLSDMessageReader = NULL; +  	delete mPollInfop;  	mPollInfop = NULL; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index b94f593d7f..6d0c57812d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1,3 +1,11 @@ +/**  + * @file llvertexbuffer.cpp + * @brief LLVertexBuffer implementation + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  #include "linden_common.h"  #include "llvertexbuffer.h" diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index b221d35ee3..a064081f28 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -1,3 +1,11 @@ +/**  + * @file llvertexbuffer.h + * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  #ifndef LL_LLVERTEXBUFFER_H  #define LL_LLVERTEXBUFFER_H diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 43ea584aa1..7e7999c9f9 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -137,6 +137,14 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,  {  	llassert( max_length_bytes > 0 ); +	// line history support: +	// - initialize line history list +	mLineHistory.insert( mLineHistory.end(), "" ); +	// - disable line history by default +	mHaveHistory = FALSE; +	// - reset current history line pointer +	mCurrentHistoryLine = 0; +  	if (font)  	{  		mGLFont = font; @@ -209,10 +217,33 @@ void LLLineEditor::onFocusLost()  void LLLineEditor::onCommit()  { +	// put current line into the line history +	updateHistory(); +  	LLUICtrl::onCommit();  	selectAll();  } +// line history support +void LLLineEditor::updateHistory() +{ +	// On history enabled line editors, remember committed line and +	// reset current history line number. +	// Be sure only to remember lines that are not empty and that are +	// different from the last on the list. +	if( mHaveHistory && mText.length() && ( mLineHistory.empty() || getText() != mLineHistory.back() ) ) +	{ +		// discard possible empty line at the end of the history +		// inserted by setText() +		if( !mLineHistory.back().length() ) +		{ +			mLineHistory.pop_back(); +		} +		mLineHistory.insert( mLineHistory.end(), getText() ); +		mCurrentHistoryLine = mLineHistory.size() - 1; +	} +} +  void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent)  {  	LLUICtrl::reshape(width, height, called_from_parent ); @@ -220,6 +251,10 @@ void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent)  	mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight;  } +void LLLineEditor::setEnableLineHistory( BOOL enabled ) +{ +	mHaveHistory = enabled; +}  void LLLineEditor::setEnabled(BOOL enabled)  { @@ -280,6 +315,13 @@ void LLLineEditor::setText(const LLString &new_text)  		deselect();  	}  	setCursor(llmin((S32)mText.length(), getCursor())); + +	// Newly set text goes always in the last line of history. +	// Possible empty strings (as with chat line) will be deleted later. +	mLineHistory.insert( mLineHistory.end(), new_text ); +	// Set current history line to end of history. +	mCurrentHistoryLine = mLineHistory.size() - 1; +  	mPrevText = mText;  } @@ -1066,6 +1108,45 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)  		}  		break; +	// handle ctrl-uparrow if we have a history enabled line editor. +	case KEY_UP: +		if( mHaveHistory && ( MASK_CONTROL & mask ) ) +		{ +			if( mCurrentHistoryLine > 0 ) +			{ +				mText.assign( mLineHistory[ --mCurrentHistoryLine ] ); +				setCursor(llmin((S32)mText.length(), getCursor())); +			} +			else +			{ +				reportBadKeystroke(); +			} +			handled = TRUE; +		} +		break; + +	// handle ctrl-downarrow if we have a history enabled line editor +	case KEY_DOWN: +		if( mHaveHistory  && ( MASK_CONTROL & mask ) ) +		{ +			if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.size() - 1 ) +			{ +				mText.assign( mLineHistory[ ++mCurrentHistoryLine ] ); +				setCursor(llmin((S32)mText.length(), getCursor())); +			} +			else +			{ +				reportBadKeystroke(); +			} +			handled = TRUE; +		} +		break; + +	case KEY_RETURN: +		// store sent line in history +		updateHistory(); +		break; +  	case KEY_ESCAPE:  	    if (mRevertOnEsc && mText.getString() != mPrevText)  		{ diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 27ae351d1f..b3eff3c8e2 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -16,6 +16,7 @@  //		Clipboard (cut, copy, and paste)  //		Horizontal scrolling to allow strings longer than widget size allows   //		Pre-validation (limit which keys can be used) +//		Optional line history so previous entries can be recalled by CTRL UP/DOWN  #ifndef LL_LLLINEEDITOR_H @@ -186,6 +187,10 @@ public:  	static BOOL		postvalidateFloat(const LLString &str); +	// line history support: +	void			setEnableLineHistory( BOOL enabled ); // switches line history on or off  +	void			updateHistory(); // stores current line in history +  protected:  	void			removeChar();  	void			addChar(const llwchar c); @@ -204,6 +209,11 @@ protected:  	LLString		mPrevText;				// Saved string for 'ESC' revert  	LLUIString		mLabel;					// text label that is visible when no user text provided +	// line history support: +	BOOL		mHaveHistory;				// flag for enabled line history +	std::vector<LLString> mLineHistory;		// line history storage +	U32			mCurrentHistoryLine;		// currently browsed history line +  	LLViewBorder* mBorder;  	const LLFontGL*	mGLFont;  	S32			mMaxLengthChars;			// Max number of characters diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 2b588cacce..9363415dc2 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -289,6 +289,9 @@ LLTextEditor::LLTextEditor(  {  	mSourceID.generate(); +	// reset desired x cursor position +	mDesiredXPixel = -1; +  	if (font)  	{  		mGLFont = font; @@ -894,6 +897,8 @@ void LLTextEditor::setCursorPos(S32 offset)  {  	mCursorPos = llclamp(offset, 0, (S32)getLength());  	updateScrollFromCursor(); +	// reset desired x cursor position +	mDesiredXPixel = -1;  } @@ -3078,6 +3083,9 @@ void LLTextEditor::changePage( S32 delta )  	S32 line, offset;  	getLineAndOffset( mCursorPos, &line, &offset ); +	// get desired x position to remember previous position +	S32 desired_x_pixel = mDesiredXPixel; +  	// allow one line overlap  	S32 page_size = mScrollbar->getPageSize() - 1;  	if( delta == -1 ) @@ -3092,6 +3100,10 @@ void LLTextEditor::changePage( S32 delta )  		setCursorPos(getPos( line + page_size, offset ));  		mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size );  	} + +	// put desired position into remember-buffer after setCursorPos() +	mDesiredXPixel = desired_x_pixel; +  	if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))  	{  		mOnScrollEndCallback(mOnScrollEndData); @@ -3107,9 +3119,13 @@ void LLTextEditor::changeLine( S32 delta )  	S32  line_start = getLineStart(line); -	S32 desired_x_pixel; -	 -	desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); +	// set desired x position to remembered previous position +	S32 desired_x_pixel = mDesiredXPixel; +	// if remembered position was reset (thus -1), calculate new one here +	if( desired_x_pixel == -1 ) +	{ +		desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); +	}  	S32 new_line = 0;  	if( (delta < 0) && (line > 0 ) ) @@ -3145,6 +3161,9 @@ void LLTextEditor::changeLine( S32 delta )  											  mAllowEmbeddedItems);  	setCursorPos (getPos( new_line, new_offset )); + +	// put desired position into remember-buffer after setCursorPos() +	mDesiredXPixel = desired_x_pixel;  	unbindEmbeddedChars( mGLFont );  } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index d95230f0dc..7454b192fd 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -339,6 +339,7 @@ protected:  	undo_stack_t	mUndoStack;  	S32				mCursorPos;				// I-beam is just after the mCursorPos-th character. +	S32				mDesiredXPixel;			// X pixel position where the user wants the cursor to be  	LLRect			mTextRect;				// The rect in which text is drawn.  Excludes borders.  	// List of offsets and segment index of the start of each line.  Always has at least one node (0).  	struct line_info diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index da5c77fc94..05c2247a35 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -176,6 +176,9 @@ LLView::~LLView()  		(*itor).second->clearDispatchers();  		delete (*itor).second;  	} + +	std::for_each(mFloaterControls.begin(), mFloaterControls.end(), +				  DeletePairedPointer());  }  // virtual diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index bc02ebfb63..4152de51c5 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -2211,7 +2211,13 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  	case kEventClassWindow:  		switch(evtKind) -		{ +		{		 +		case kEventWindowActivated: +			mCallbacks->handleFocus(this); +			break; +		case kEventWindowDeactivated: +			mCallbacks->handleFocusLost(this); +			break;  		case kEventWindowBoundsChanging:  			{  				Rect currentBounds; diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index 550a61d37a..12a687d713 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -12,6 +12,7 @@  #if LL_MESA_HEADLESS  #include "llwindow.h" +#include "GL/glu.h"  #include "GL/osmesa.h"  class LLWindowMesaHeadless : public LLWindow diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 6b25eabfd1..71c766db8e 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -276,9 +276,9 @@ static SDL_Surface *Load_BMP_Resource(const char *basename)  #if LL_X11  // This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM  // on this machine.  It works by searching /var/log/var/log/Xorg.?.log or -// /var/log/XFree86.?.log for a ': VideoRAM: (%d+) kB' regex, where '?' is -// the X11 display number derived from $DISPLAY -static int x11_detect_VRAM_kb_fp(FILE *fp) +// /var/log/XFree86.?.log for a ': (VideoRAM|Memory): (%d+) kB' regex, where +// '?' is the X11 display number derived from $DISPLAY +static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)  {  	const int line_buf_size = 1000;  	char line_buf[line_buf_size]; @@ -290,7 +290,7 @@ static int x11_detect_VRAM_kb_fp(FILE *fp)  		// favourite regex implementation - libboost_regex - is  		// quite a heavy and troublesome dependency for the client, so  		// it seems a shame to introduce it for such a simple task. -		const char part1_template[] = ": VideoRAM: "; +		const char *part1_template = prefix_str;  		const char part2_template[] = " kB";  		char *part1 = strstr(line_buf, part1_template);  		if (part1) // found start of matching line @@ -305,7 +305,6 @@ static int x11_detect_VRAM_kb_fp(FILE *fp)  				int rtn = 0;  				for (; part1 < part2; ++part1)  				{ -					//lldebugs << "kB" << *part1 << llendl;  					if (*part1 < '0' || *part1 > '9')  					{  						// unexpected char, abort parse @@ -325,6 +324,7 @@ static int x11_detect_VRAM_kb_fp(FILE *fp)  	}  	return 0; // 'could not detect'  } +  static int x11_detect_VRAM_kb()  {  	std::string x_log_location("/var/log/"); @@ -343,7 +343,7 @@ static int x11_detect_VRAM_kb()  	// *TODO: we could be smarter and see which of Xorg/XFree86 has the  	// freshest time-stamp. -	// Try XOrg log first +	// Try Xorg log first  	fname = x_log_location;  	fname += "Xorg.";  	fname += ('0' + display_num); @@ -351,12 +351,25 @@ static int x11_detect_VRAM_kb()  	fp = fopen(fname.c_str(), "r");  	if (fp)  	{ -		rtn = x11_detect_VRAM_kb_fp(fp); +		llinfos << "Looking in " << fname +			<< " for VRAM info..." << llendl; +		rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: ");  		fclose(fp); +		if (0 == rtn) +		{ +			fp = fopen(fname.c_str(), "r"); +			if (fp) +			{ +				rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); +				fclose(fp); +			} +		}  	} -	// Try old XFree86 log otherwise -	if (rtn == 0) +	else  	{ +		llinfos << "Could not open " << fname +			<< " - skipped." << llendl;	 +		// Try old XFree86 log otherwise  		fname = x_log_location;  		fname += "XFree86.";  		fname += ('0' + display_num); @@ -364,8 +377,24 @@ static int x11_detect_VRAM_kb()  		fp = fopen(fname.c_str(), "r");  		if (fp)  		{ -			rtn = x11_detect_VRAM_kb_fp(fp); +			llinfos << "Looking in " << fname +				<< " for VRAM info..." << llendl; +			rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: ");  			fclose(fp); +			if (0 == rtn) +			{ +				fp = fopen(fname.c_str(), "r"); +				if (fp) +				{ +					rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); +					fclose(fp); +				} +			} +		} +		else +		{ +			llinfos << "Could not open " << fname +				<< " - skipped." << llendl;  		}  	}  	return rtn; diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 4b56148f10..91bf24ec11 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -517,8 +517,7 @@ bool isDirWritable(FSRef &dir)  static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src)  { -	LLWString		wstr = utf8str_to_wstring(src); -	llutf16string	utf16str = wstring_to_utf16str(wstr); +	llutf16string	utf16str = utf8str_to_utf16str(src);  	dest->length = utf16str.size();  	if(dest->length > 255) @@ -530,6 +529,13 @@ static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src)  	memcpy(dest->unicode, utf16str.data(), sizeof(UniChar)* dest->length);		/* Flawfinder: ignore */  } +static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src) +{ +	llutf16string string16((U16*)&(src->unicode), src->length); +	std::string result = utf16str_to_utf8str(string16); +	return result; +} +  int restoreObject(const char* aside, const char* target, const char* path, const char* object)  {  	char source[PATH_MAX];		/* Flawfinder: ignore */ @@ -578,6 +584,123 @@ void filterFile(const char* filename)  	system(temp);		/* Flawfinder: ignore */  } +static bool isFSRefViewerBundle(FSRef *targetRef) +{ +	bool result = false; +	CFURLRef targetURL = NULL; +	CFBundleRef targetBundle = NULL; +	CFStringRef targetBundleID = NULL; +	 +	targetURL = CFURLCreateFromFSRef(NULL, targetRef); + +	if(targetURL == NULL) +	{ +		llinfos << "Error creating target URL." << llendl; +	} +	else +	{ +		targetBundle = CFBundleCreate(NULL, targetURL); +	} +	 +	if(targetBundle == NULL) +	{ +		llinfos << "Failed to create target bundle." << llendl; +	} +	else +	{ +		targetBundleID = CFBundleGetIdentifier(targetBundle); +	} +	 +	if(targetBundleID == NULL) +	{ +		llinfos << "Couldn't retrieve target bundle ID." << llendl; +	} +	else +	{ +		if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) +		{ +			// This is the bundle we're looking for. +			result = true; +		} +		else +		{ +			llinfos << "Target bundle ID mismatch." << llendl; +		} +	} +	 +	// Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. +	if(targetURL != NULL) +		CFRelease(targetURL); +	if(targetBundle != NULL) +		CFRelease(targetBundle); +	 +	return result; +} + +// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer. +static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) +{ +	FSIterator		iterator; +	bool			found = false; + +	OSErr err = FSOpenIterator( parent, kFSIterateFlat, &iterator ); +	if(!err) +	{ +		do +		{ +			ItemCount actualObjects = 0; +			Boolean containerChanged = false; +			FSCatalogInfo info; +			FSRef ref; +			HFSUniStr255 unicodeName; +			err = FSGetCatalogInfoBulk(  +					iterator,  +					1,  +					&actualObjects,  +					&containerChanged, +					kFSCatInfoNodeFlags,  +					&info,  +					&ref, +					NULL,  +					&unicodeName ); +			 +			if(actualObjects == 0) +				break; +				 +			if(!err) +			{ +				// Call succeeded and not done with the iteration. +				std::string name = HFSUniStr255_to_utf8str(&unicodeName); + +				llinfos << "Considering \"" << name << "\"" << llendl; + +				if(info.nodeFlags & kFSNodeIsDirectoryMask) +				{ +					// This is a directory.  See if it's a .app +					if(name.find(".app") != std::string::npos) +					{ +						// Looks promising.  Check to see if it has the right bundle identifier. +						if(isFSRefViewerBundle(&ref)) +						{ +							// This is the one.  Return it. +							*app = ref; +							found = true; +						} +					} +				} +			} +		} +		while(!err && !found); +		 +		FSCloseIterator(iterator); +	} +	 +	if(!err && !found) +		err = fnfErr; +		 +	return err; +} +  void *updatethreadproc(void*)  {  	char tempDir[PATH_MAX] = "";		/* Flawfinder: ignore */ @@ -650,57 +773,15 @@ void *updatethreadproc(void*)  			// Sanity check: make sure the target is a bundle with the right identifier  			if(err == noErr)  			{ -				CFURLRef targetURL = NULL; -				CFBundleRef targetBundle = NULL; -				CFStringRef targetBundleID = NULL; -				  				// Assume the worst...  				err = -1; -				 -				targetURL = CFURLCreateFromFSRef(NULL, &targetRef); -				if(targetURL == NULL) -				{ -					llinfos << "Error creating target URL." << llendl; -				} -				else +				if(isFSRefViewerBundle(&targetRef))  				{ -					targetBundle = CFBundleCreate(NULL, targetURL); -				} -				 -				if(targetBundle == NULL) -				{ -					llinfos << "Failed to create target bundle." << llendl; -				} -				else -				{ -					targetBundleID = CFBundleGetIdentifier(targetBundle); -				} -				 -				if(targetBundleID == NULL) -				{ -					llinfos << "Couldn't retrieve target bundle ID." << llendl; -				} -				else -				{ -					if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) -					{ -						// This is the bundle we're looking for. -						err = noErr; -						replacingTarget = true; -					} -					else -					{ -						llinfos << "Target bundle ID mismatch." << llendl; -					} +					// This is the bundle we're looking for. +					err = noErr; +					replacingTarget = true;  				} -				 -				// Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. -				if(targetURL != NULL) -					CFRelease(targetURL); -				if(targetBundle != NULL) -					CFRelease(targetBundle); -				  			}  			// Make sure the target's parent directory is writable. @@ -923,13 +1004,24 @@ void *updatethreadproc(void*)  		// Get an FSRef to the new application on the disk image  		FSRef sourceRef; -		snprintf(temp, sizeof(temp), "%s/mnt/Second Life.app", tempDir);		 +		FSRef mountRef; +		snprintf(temp, sizeof(temp), "%s/mnt", tempDir);		 -		llinfos << "Source application is: " << temp << llendl; +		llinfos << "Disk image mount point is: " << temp << llendl; -		err = FSPathMakeRef((UInt8 *)temp, &sourceRef, NULL); +		err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL);  		if(err != noErr) +		{ +			llinfos << "Couldn't make FSRef to disk image mount point." << llendl;  			throw 0; +		} + +		err = findAppBundleOnDiskImage(&mountRef, &sourceRef); +		if(err != noErr) +		{ +			llinfos << "Couldn't find application bundle on mounted disk image." << llendl; +			throw 0; +		}  		FSRef asideRef;  		char aside[MAX_PATH];		/* Flawfinder: ignore */ diff --git a/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt index a0dc048825..1892b810f1 100644 --- a/indra/newview/licenses-linux.txt +++ b/indra/newview/licenses-linux.txt @@ -514,3 +514,36 @@ jloup@gzip.org  Mark Adler   madler@alumni.caltech.edu  + +================================= +tcmalloc/Google perftools license +================================= + +Copyright (c) 2005, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +    * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +    * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +    * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c6155197f6..eb00692157 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4963,7 +4963,7 @@ BOOL LLAgent::allowOperation(PermissionBit op,  							 const LLPermissions& perm,  							 U64 group_proxy_power,  							 U8 god_minimum) -{ + {  	// Check god level.  	if (getGodLevel() >= god_minimum) return TRUE; diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 19992c201a..e93ce8bdff 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -110,6 +110,7 @@ LLAvatarTracker::~LLAvatarTracker()  {  	deleteTrackingData();  	std::for_each(mObservers.begin(), mObservers.end(), DeletePointer()); +	std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer());  }  void LLAvatarTracker::track(const LLUUID& avatar_id, const std::string& name) diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index c5e7eaa1e9..4beea0d112 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -98,8 +98,8 @@ LLChatBar::LLChatBar(const std::string& name, const LLRect& rect)  		mInputEditor->setRevertOnEsc( FALSE );  		mInputEditor->setIgnoreTab(TRUE);  		mInputEditor->setPassDelete(TRUE); -  		mInputEditor->setMaxTextLength(1023); +		mInputEditor->setEnableLineHistory(TRUE);  	}  	// Build the list of gestures @@ -426,6 +426,8 @@ void LLChatBar::sendChat( EChatType type )  	if (!text.empty())  	{ +		// store sent line in history, duplicates will get filtered +		mInputEditor->updateHistory();  		// Check if this is destined for another channel  		S32 channel = 0;  		stripChannelNumber(text, &channel); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 2b11653da0..5a7a12c38d 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -42,6 +42,7 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD  	mInitializedRes = -1;  	mSimulateRes = 0;  	mFrameNum = 0; +	mRenderRes = 1;  }//-----------------------------------------------  LLVector3 LLVolumeImplFlexible::getFramePosition() const @@ -233,7 +234,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6  {  	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))  	{ -		return TRUE; +		return FALSE; // (we are not initialized or updated)  	}  	LLFastTimer ftm(LLFastTimer::FTM_FLEXIBLE_UPDATE); @@ -241,7 +242,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6  	if (mVO->mDrawable.isNull())  	{  		// Don't do anything until we have a drawable -		return TRUE; +		return FALSE; // (we are not initialized or updated)  	}  	//flexible objects never go static @@ -326,8 +327,13 @@ void LLVolumeImplFlexible::doFlexibleUpdate()  	if (mSimulateRes == 0)  	{  		mVO->markForUpdate(TRUE); -		doIdleUpdate(gAgent, *gWorldp, 0.0); +		if (!doIdleUpdate(gAgent, *gWorldp, 0.0)) +		{ +			return;	// we did not get updated or initialized, proceeding without can be dangerous +		}  	} + +	llassert_always(mInitialized);  	S32 num_sections = 1 << mSimulateRes; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 622af2b473..a838948a1c 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -39,7 +39,7 @@ LLFloaterBuy::LLFloaterBuy()  	childSetAction("cancel_btn", onClickCancel, this);  	childSetAction("buy_btn", onClickBuy, this); -	setDefaultBtn("buy_btn"); +	setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)  }  LLFloaterBuy::~LLFloaterBuy() diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 3745de6552..8c85a6fe5a 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -44,7 +44,7 @@ LLFloaterBuyContents::LLFloaterBuyContents()  	childDisable("buy_btn");  	childDisable("wear_check"); -	setDefaultBtn("buy_btn"); +	setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)  }  LLFloaterBuyContents::~LLFloaterBuyContents() diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 80da7b63ed..233357453d 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -1,3 +1,11 @@ +/**  + * @file llfloaterinspect.cpp + * @brief Floater for object inspection tool + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  #include "llviewerprecompiledheaders.h"  #include "llfloateravatarinfo.h"  #include "llfloaterinspect.h" diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index d7717dffc3..588fb1dac0 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -129,7 +129,6 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton  	mPrefsIM->getPanel()->setDefaultBtn(default_btn);  	mMsgPanel = new LLPanelMsgs(); -	gUICtrlFactory->buildPanel(mMsgPanel, "panel_settings_msgbox.xml");  	mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer);  	mMsgPanel->setDefaultBtn(default_btn); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 21b2bbb02e..14a4d7dc00 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1901,7 +1901,7 @@ void LLFolderViewFolder::requestArrange(BOOL include_descendants)  {   	mLastArrangeGeneration = -1;   	// flag all items up to root -	if (mParentFolder && !mParentFolder->needsArrange()) +	if (mParentFolder)  	{  		mParentFolder->requestArrange();  	} diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 00108650ef..18993e56fa 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -29,6 +29,7 @@  #include "llviewerwindow.h"  #include "llfloaterdirectory.h"  #include "llfloatergroupinfo.h" +#include "lluictrlfactory.h"  LLGroupMgr sGroupMgr; // use local instance so that it gets cleaned up on application exit  LLGroupMgr* gGroupMgr = &sGroupMgr; @@ -1709,21 +1710,28 @@ void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id)  //static  bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)  { -	LLXmlTree xml_tree; -	LLString xml_file = LLUI::locateSkin(xml_filename); -	BOOL success = xml_tree.parseFile(xml_file, TRUE ); -	LLXmlTreeNode* root = xml_tree.getRoot(); +	LLXMLNodePtr root; + +	BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);	 +	  	if (!success || !root || !root->hasName( "role_actions" ))  	{  		llerrs << "Problem reading UI role_actions file: " << xml_filename << llendl;  		return false;  	} -	for (LLXmlTreeNode* action_set = root->getChildByName("action_set"); -		action_set != NULL; action_set = root->getNextNamedChild()) +	LLXMLNodeList role_list; +	LLXMLNodeList::iterator role_iter; + +	root->getChildren("action_set", role_list, false); +	 +	for (role_iter = role_list.begin(); role_iter != role_list.end(); ++role_iter)  	{ +		LLXMLNodePtr action_set = role_iter->second; +  		LLRoleActionSet* role_action_set = new LLRoleActionSet();  		LLRoleAction* role_action_data = new LLRoleAction(); +		  		// name=  		LLString action_set_name;  		if (action_set->getAttributeString("name", action_set_name)) @@ -1754,9 +1762,15 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)  		// power mask=  		U64 set_power_mask = 0; -		for (LLXmlTreeNode* action = action_set->getChildByName("action"); -			action != NULL; action = action_set->getNextNamedChild()) +		LLXMLNodeList action_list; +		LLXMLNodeList::iterator action_iter; + +		action_set->getChildren("action", action_list, false); + +		for (action_iter = action_list.begin(); action_iter != action_list.end(); ++action_iter)  		{ +			LLXMLNodePtr action = action_iter->second; +  			LLRoleAction* role_action = new LLRoleAction();  			// name= diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 7c03500f85..0484027455 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -199,19 +199,21 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name,  void LLFloaterIMPanel::init(const LLString& session_label)  {  	gUICtrlFactory->buildFloater(this, -								 "floater_instant_message.xml", -								 NULL, -								 FALSE); - +				     "floater_instant_message.xml", +				     NULL, +				     FALSE); +	  	setLabel(session_label);  	setTitle(session_label);  	mInputEditor->setMaxTextLength(1023); +	// enable line history support for instant message bar +	mInputEditor->setEnableLineHistory(TRUE);  	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )  	{  		LLLogChat::loadHistory(session_label, -							   &chatFromLogFile, -							   (void *)this); +				       &chatFromLogFile, +				       (void *)this);  	}  	if(IM_SESSION_911_START == mDialog) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 13d13031b6..badab645b9 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -802,7 +802,7 @@ LLString LLItemBridge::getLabelSuffix() const  	if(item)   	{  		// it's a bit confusing to put nocopy/nomod/etc on calling cards. -		if(LLAssetType::AT_CALLINGCARD != item->getType() +		if( LLAssetType::AT_CALLINGCARD != item->getType()  		   && item->getPermissions().getOwner() == gAgent.getID())  		{  			BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); @@ -814,14 +814,32 @@ LLString LLItemBridge::getLabelSuffix() const  			const char* NO_MOD = " (no modify)";  			const char* NO_XFER = " (no transfer)";  			const char* scopy; -			if(copy) scopy = EMPTY; -			else scopy = NO_COPY; +			if(copy) +			{ +				scopy = EMPTY; +			} +			else +			{ +				scopy = NO_COPY; +			};  			const char* smod; -			if(mod) smod = EMPTY; -			else smod = NO_MOD; +			if(mod) +			{ +				smod = EMPTY; +			} +			else +			{ +				smod = NO_MOD; +			};  			const char* sxfer; -			if(xfer) sxfer = EMPTY; -			else sxfer = NO_XFER; +			if(xfer) +			{ +				sxfer = EMPTY; +			} +			else +			{ +				sxfer = NO_XFER; +			};  			char buffer[MAX_STRING];		/*Flawfinder: ignore*/  			snprintf(						/* Flawfinder: ignore */  				buffer, @@ -2490,14 +2508,14 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod  	else LLItemBridge::performAction(folder, model, action);  } -void open_landmark(const LLUUID& item_id,  +void open_landmark(LLViewerInventoryItem* inv_item,  				   const LLString& title,  				   BOOL show_keep_discard,  				   const LLUUID& source_id,  				   BOOL take_focus)  {  	// See if we can bring an exiting preview to the front -	if( !LLPreview::show( item_id, take_focus ) ) +	if( !LLPreview::show( inv_item->getUUID(), take_focus ) )  	{  		// There isn't one, so make a new preview  		S32 left, top; @@ -2505,11 +2523,12 @@ void open_landmark(const LLUUID& item_id,  		LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect");  		rect.translate( left - rect.mLeft, top - rect.mTop ); -		LLPreviewLandmark* preview = new LLPreviewLandmark("preview landmark", +		LLPreviewLandmark* preview = new LLPreviewLandmark(title,  								  rect,  								  title, -								  item_id, -								  show_keep_discard); +								  inv_item->getUUID(), +								  show_keep_discard, +								  inv_item);  		preview->setSourceID(source_id);  		if(take_focus) preview->setFocus(TRUE);  		// keep onscreen @@ -2522,7 +2541,7 @@ void LLLandmarkBridge::openItem()  	LLViewerInventoryItem* item = getItem();  	if( item )  	{ -		open_landmark(mUUID, LLString("  ") + getPrefix() + item->getName(), FALSE); +		open_landmark(item, LLString("  ") + getPrefix() + item->getName(), FALSE);  	}  } @@ -2749,14 +2768,15 @@ LLViewerImage* LLNotecardBridge::getIcon() const  	return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);  } -void open_notecard(const LLUUID& item_id,  +void open_notecard(LLViewerInventoryItem* inv_item,  				   const LLString& title, +				   const LLUUID& object_id,  				   BOOL show_keep_discard,  				   const LLUUID& source_id,  				   BOOL take_focus)  {  	// See if we can bring an existing preview to the front -	if(!LLPreview::show(item_id, take_focus)) +	if(!LLPreview::show(inv_item->getUUID(), take_focus))  	{  		// There isn't one, so make a new preview  		S32 left, top; @@ -2764,13 +2784,9 @@ void open_notecard(const LLUUID& item_id,  		LLRect rect = gSavedSettings.getRect("NotecardEditorRect");  		rect.translate(left - rect.mLeft, top - rect.mTop);  		LLPreviewNotecard* preview; -		preview = new LLPreviewNotecard("preview notecard", -										  rect, -										  title, -										  item_id, -										  LLUUID::null, -										  LLUUID::null, -										  show_keep_discard); +		preview = new LLPreviewNotecard("preview notecard", rect, title, +						inv_item->getUUID(), object_id, inv_item->getAssetUUID(), +						show_keep_discard, inv_item);  		preview->setSourceID(source_id);  		if(take_focus) preview->setFocus(TRUE);  		// Force to be entirely onscreen. @@ -2789,23 +2805,22 @@ void open_notecard(const LLUUID& item_id,  		//		{  		//			// create new multipreview if it doesn't exist  		//			LLMultiPreview* preview_hostp = new LLMultiPreview(existing_preview->getRect()); -  		//			preview_hostp->addFloater(existing_preview);  		//		}  		//		// add this preview to existing host  		//		preview_hostp->addFloater(preview);  		//	}  		//} -  	}  } +  void LLNotecardBridge::openItem()  {  	LLViewerInventoryItem* item = getItem();  	if (item)  	{ -		open_notecard(mUUID, getPrefix() + item->getName(), FALSE); +		open_notecard(item, getPrefix() + item->getName(), LLUUID::null, FALSE);  	}  } diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 7ba0ccad3a..75be1be4a6 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -165,12 +165,7 @@ BOOL LLMuteList::isLinden(const LLString& name) const  	if (token_iter == tokens.end()) return FALSE;  	LLString last_name = *token_iter; -	 -	if (last_name == "Linden") -	{ -		return TRUE; -	} -	return FALSE; +	return last_name == "Linden";  } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index b2fc91f536..daea084759 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -845,14 +845,44 @@ void LLPanelAvatarClassified::refresh()  	bool allow_delete = (tab_count > 0);  	bool show_help = (tab_count == 0); -	childSetEnabled("New...",self && allow_new); -	childSetEnabled("Delete...",self && allow_delete); +	// *HACK: Don't allow making new classifieds from inside the directory. +	// The logic for save/don't save when closing is too hairy, and the  +	// directory is conceptually read-only. JC +	bool in_directory = false; +	LLView* view = this; +	while (view) +	{ +		if (view->getName() == "directory") +		{ +			in_directory = true; +			break; +		} +		view = view->getParent(); +	} +	childSetEnabled("New...", self && !in_directory && allow_new); +	childSetVisible("New...", !in_directory); +	childSetEnabled("Delete...", self && !in_directory && allow_delete); +	childSetVisible("Delete...", !in_directory);  	childSetVisible("classified tab",!show_help);  	sendAvatarProfileRequestIfNeeded("avatarclassifiedsrequest");  } +BOOL LLPanelAvatarClassified::canClose() +{ +	LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); +	for (S32 i = 0; i < tabs->getTabCount(); i++) +	{ +		LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i); +		if (!panel->canClose()) +		{ +			return FALSE; +		} +	} +	return TRUE; +} +  BOOL LLPanelAvatarClassified::titleIsValid()  {  	LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); @@ -1280,6 +1310,11 @@ LLPanelAvatar::~LLPanelAvatar()  } +BOOL LLPanelAvatar::canClose() +{ +	return mPanelClassified && mPanelClassified->canClose(); +} +  void LLPanelAvatar::setAvatar(LLViewerObject *avatarp)  {  	// find the avatar and grab the name diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index f54da2538f..cbc4c55b52 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -194,6 +194,10 @@ public:  	/*virtual*/ void refresh(); +	// If can close, return TRUE.  If cannot close, pop save/discard dialog +	// and return FALSE. +	BOOL canClose(); +  	void apply();  	BOOL titleIsValid(); @@ -247,6 +251,10 @@ public:  	/*virtual*/ BOOL	postBuild(void); +	// If can close, return TRUE.  If cannot close, pop save/discard dialog +	// and return FALSE. +	BOOL canClose(); +  	void setAvatar(LLViewerObject *avatarp);  	// Fill in the avatar ID and handle some field fill-in, as well as  diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 95ed517794..b9b9cda4e8 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -40,6 +40,7 @@  #include "llfloaterworldmap.h"  #include "llviewergenericmessage.h"	// send_generic_message  #include "llviewerwindow.h"	// for window width, height +#include "viewer.h"	// app_abort_quit()  const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$ @@ -77,11 +78,12 @@ std::list<LLPanelClassified*> LLPanelClassified::sAllPanels;  LLPanelClassified::LLPanelClassified(BOOL in_finder)  :	LLPanel("Classified Panel"),  	mInFinder(in_finder), +	mDirty(false), +	mForceClose(false),  	mClassifiedID(),  	mCreatorID(),  	mPriceForListing(0),  	mDataRequested(FALSE), -	mEnableCommit(FALSE),  	mPaidFor(FALSE),      mPosGlobal(),      mSnapshotCtrl(NULL), @@ -132,7 +134,7 @@ void LLPanelClassified::reset()  	// Don't request data, this isn't valid  	mDataRequested = TRUE; -	mEnableCommit = FALSE; +	mDirty = false;  	mPaidFor = FALSE;  	mPosGlobal.clearVec(); @@ -215,7 +217,6 @@ BOOL LLPanelClassified::postBuild()  	mUpdateBtn = LLUICtrlFactory::getButtonByName(this, "classified_update_btn");      mUpdateBtn->setClickedCallback(onClickUpdate);      mUpdateBtn->setCallbackUserData(this); -	mEnableCommit = TRUE;  	if (!mInFinder)  	{ @@ -248,12 +249,58 @@ void LLPanelClassified::apply()  {  	// Apply is used for automatically saving results, so only  	// do that if there is a difference, and this is a save not create. -	if (mEnableCommit && mPaidFor) +	if (mDirty && mPaidFor)  	{  		sendClassifiedInfoUpdate();  	}  } + +// static +void LLPanelClassified::saveCallback(S32 option, void* data) +{ +	LLPanelClassified* self = (LLPanelClassified*)data; +	switch(option) +	{ +		case 0: // Save +			self->sendClassifiedInfoUpdate(); +			// fall through to close + +		case 1: // Don't Save +			{ +				self->mForceClose = true; +				// Close containing floater +				LLView* view = self; +				while (view) +				{ +					if (view->getWidgetType() == WIDGET_TYPE_FLOATER) +					{ +						LLFloater* f = (LLFloater*)view; +						f->close(); +						break; +					} +					view = view->getParent(); +				} +			} +			break; + +		case 2: // Cancel +		default: +			app_abort_quit(); +			break; +	} +} + +BOOL LLPanelClassified::canClose() +{ +	if (mForceClose || !mDirty) return TRUE; + +	LLString::format_map_t args; +	args["[NAME]"] = mNameEditor->getText(); +	LLAlertDialog::showXml("ClassifiedSave", args, saveCallback, this); +	return FALSE; +} +  // Fill in some reasonable defaults for a new classified.  void LLPanelClassified::initNewClassified()  { @@ -396,6 +443,8 @@ void LLPanelClassified::sendClassifiedInfoUpdate()  	msg->addU8Fast(_PREHASH_ClassifiedFlags, flags);  	msg->addS32("PriceForListing", mPriceForListing);  	gAgent.sendReliableMessage(); + +	mDirty = false;  } @@ -607,7 +656,7 @@ void LLPanelClassified::refresh()  		mSetBtn->setVisible(is_self);  		mSetBtn->setEnabled(is_self); -		mUpdateBtn->setEnabled(is_self && mEnableCommit); +		mUpdateBtn->setEnabled(is_self && mDirty);  		mUpdateBtn->setVisible(is_self);  	}  } @@ -690,7 +739,6 @@ void LLPanelClassified::callbackConfirmPublish(S32 option, void* data)  		LLTabContainerVertical* tab = (LLTabContainerVertical*)self->getParent();  		tab->setCurrentTabName(self->mNameEditor->getText());  	} -	self->mEnableCommit = FALSE;  }  // static @@ -769,14 +817,14 @@ void LLPanelClassified::onCommitAny(LLUICtrl* ctrl, void* data)  	LLPanelClassified* self = (LLPanelClassified*)data;  	if (self)  	{ -		self->mEnableCommit = TRUE; +		self->mDirty = true;  	}  }  // static  void LLPanelClassified::onFocusReceived(LLUICtrl* ctrl, void* data)  { -	// first, allow the data to be saved +	// allow the data to be saved  	onCommitAny(ctrl, data);  } diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h index c959c0f82f..ca6a05eb31 100644 --- a/indra/newview/llpanelclassified.h +++ b/indra/newview/llpanelclassified.h @@ -43,10 +43,14 @@ public:      /*virtual*/ void draw(); -	void refresh(); +	/*virtual*/ void refresh();  	void apply(); +	// If can close, return TRUE.  If cannot close, pop save/discard dialog +	// and return FALSE. +	BOOL canClose(); +  	// Setup a new classified, including creating an id, giving a sane  	// initial position, etc.  	void initNewClassified(); @@ -74,6 +78,8 @@ public:  	static void callbackConfirmPublish(S32 option, void* data);  protected: +	static void saveCallback(S32 option, void* data); +  	static void onClickUpdate(void* data);      static void onClickTeleport(void* data);      static void onClickMap(void* data); @@ -87,6 +93,8 @@ protected:  protected:  	BOOL mInFinder; +	bool mDirty; +	bool mForceClose;      LLUUID mClassifiedID;      LLUUID mRequestedID;  	LLUUID mCreatorID; @@ -95,7 +103,6 @@ protected:  	// Data will be requested on first draw  	BOOL mDataRequested; -	BOOL mEnableCommit;  	// For avatar panel classifieds only, has the user been charged  	// yet for this classified?  That is, have they saved once? diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 7c00742122..562e4c37c1 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -50,7 +50,7 @@ LLPreview::LLPreview(const std::string& name) :  	mAutoFocus = FALSE;  } -LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize, S32 min_width, S32 min_height ) +LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize, S32 min_width, S32 min_height, LLViewerInventoryItem* inv_item )  :	LLFloater(name, rect, title, allow_resize, min_width, min_height ),  	mItemUUID(item_uuid),  	mSourceID(LLUUID::null), @@ -59,7 +59,8 @@ LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::str  	mForceClose( FALSE ),  	mUserResized(FALSE),  	mCloseAfterSave(FALSE), -	mAssetStatus(PREVIEW_ASSET_UNLOADED) +	mAssetStatus(PREVIEW_ASSET_UNLOADED), +	mItem(inv_item)  {  	mAuxItem = new LLInventoryItem;  	// don't necessarily steal focus on creation -- sometimes these guys pop up without user action @@ -136,6 +137,8 @@ void LLPreview::setSourceID(const LLUUID& source_id)  LLViewerInventoryItem* LLPreview::getItem() const  { +	if(mItem != NULL) +		return mItem;  	LLViewerInventoryItem* item = NULL;  	if(mObjectUUID.isNull())  	{ diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h index 5c7d6f30d0..1b7c0fd9c8 100644 --- a/indra/newview/llpreview.h +++ b/indra/newview/llpreview.h @@ -51,13 +51,13 @@ public:  public:  	// Used for XML-based construction.  	LLPreview(const std::string& name); -	LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize = FALSE, S32 min_width = 0, S32 min_height = 0 ); +	LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize = FALSE, S32 min_width = 0, S32 min_height = 0, LLViewerInventoryItem* inv_item = NULL );  	virtual ~LLPreview();  	void setItemID(const LLUUID& item_id);  	void setObjectID(const LLUUID& object_id);  	void setSourceID(const LLUUID& source_id); -	LLViewerInventoryItem* getItem() const; +	LLViewerInventoryItem* getItem() const; // searches if not constructed with it  	static LLPreview* find(const LLUUID& item_uuid);  	static LLPreview*	show(const LLUUID& item_uuid, BOOL take_focus = TRUE ); @@ -134,6 +134,7 @@ protected:  	static preview_map_t sInstances;  	LLUUID mNotecardInventoryID;  	LLUUID mObjectID; +	LLViewerInventoryItem* mItem;  }; diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 1cba69b566..e5dfb9ae76 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -61,10 +61,12 @@ LLPreviewNotecard::LLPreviewNotecard(const std::string& name,  									 const LLUUID& item_id,   									 const LLUUID& object_id,  									 const LLUUID& asset_id, -									 BOOL show_keep_discard) : +									 BOOL show_keep_discard, +									 LLViewerInventoryItem* inv_item) :  	LLPreview(name, rect, title, item_id, object_id, TRUE,  			  PREVIEW_MIN_WIDTH, -			  PREVIEW_MIN_HEIGHT), +			  PREVIEW_MIN_HEIGHT, +			  inv_item),  	mAssetID( asset_id ),  	mNotecardItemID(item_id),  	mObjectID(object_id) diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 730c56833a..908d4da98c 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -29,7 +29,8 @@ public:  					  const LLUUID& item_id,  					  const LLUUID& object_id = LLUUID::null,  					  const LLUUID& asset_id = LLUUID::null, -					  BOOL show_keep_discard = FALSE); +					  BOOL show_keep_discard = FALSE, +					  LLViewerInventoryItem* inv_item = NULL);  	// llpreview	  	virtual bool saveItem(LLPointer<LLInventoryItem>* itemptr); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index e8dc281c6f..ce5649e06e 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1237,6 +1237,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded)  	: LLWorkerThread("TextureFetch", threaded),  	  mDebugCount(0),  	  mDebugPause(FALSE), +	  mPacketCount(0), +	  mBadPacketCount(0),  	  mQueueMutex(getAPRPool()),  	  mTextureCache(cache)  { diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index a1c51cfe44..f3b253a4e5 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -226,7 +226,14 @@ void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask)  		{  			gEditMenuHandler = gSelectMgr;  		} -		if(	LLManip::LL_NO_PART != gToolTranslate->mManip->getHighlightedPart() ) + +		BOOL can_move = gToolTranslate->mManip->getSelection()->getObjectCount() != 0; +		for (LLViewerObject* objectp = gToolTranslate->mManip->getSelection()->getFirstObject(); objectp; objectp = gToolTranslate->mManip->getSelection()->getNextObject()) +		{ +			can_move = can_move && objectp->permMove() && (objectp->permModify() || gSavedSettings.getBOOL("SelectLinkedSet")); +		} + +		if(	LLManip::LL_NO_PART != gToolTranslate->mManip->getHighlightedPart() && can_move)  		{  			gToolTranslate->setCurrentTool( gToolTranslate->mManip );  			gToolTranslate->mManip->handleMouseDownOnPart( x, y, mask ); diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 7c9cd1b199..40e8a3e1fa 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -186,6 +186,9 @@ LLToolMgr::~LLToolMgr()  	delete gToolPie;  	gToolPie = NULL; +	delete gToolInspect; +	gToolInspect = NULL; +  	delete gToolGun;  	gToolGun = NULL; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5a6ff851c4..c8b62146d6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1415,6 +1415,30 @@ void cleanup_menus()  {  	delete gMenuParcelObserver;  	gMenuParcelObserver = NULL; + +	delete gPieSelf; +	gPieSelf = NULL; + +	delete gPieAvatar; +	gPieAvatar = NULL; + +	delete gPieObject; +	gPieObject = NULL; + +	delete gPieAttachment; +	gPieAttachment = NULL; + +	delete gPieLand; +	gPieLand = NULL; + +	delete gMenuBarView; +	gMenuBarView = NULL; + +	delete gPopupMenuView; +	gPopupMenuView = NULL; + +	delete gMenuHolder; +	gMenuHolder = NULL;   }  //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a43bb4bb5b..18f5e54154 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -772,10 +772,10 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)  			switch(item->getType())  			{  			case LLAssetType::AT_NOTECARD: -				open_notecard(*it, LLString("Note: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); +				open_notecard((LLViewerInventoryItem*)item, LLString("Note: ") + item->getName(), LLUUID::null, show_keep_discard, LLUUID::null, FALSE);  				break;  			case LLAssetType::AT_LANDMARK: -				open_landmark(*it, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); +				open_landmark((LLViewerInventoryItem*)item, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);  				break;  			case LLAssetType::AT_TEXTURE:  				open_texture(*it, LLString("Texture: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); @@ -830,7 +830,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,  								   const char* first_name,  								   const char* last_name,  								   BOOL is_group, -								   void*) +								   void* user_data)  {  	LLString from_name;  	LLMute::EType type; @@ -854,10 +854,35 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,  		gFloaterMute->show();  		gFloaterMute->selectMute(blocked_id);  	} + +	// purge the offer queue of any previously queued inventory offers from the same source. +	LLView::child_list_t notification_queue(*(gNotifyBoxView->getChildList())); +	for(LLView::child_list_iter_t iter = notification_queue.begin(); +		iter != notification_queue.end(); +		iter++) +	{ +		LLNotifyBox* notification = (LLNotifyBox*)*iter; +		// scan for other inventory offers (i.e. ignore other types of notifications). +		// we can tell by looking for the associated callback they were created with. +		if(notification->getNotifyCallback() == inventory_offer_callback) +		{ +			// found one. +			// safe to downcast user data because we know it's associated with offer callback. +			LLOfferInfo* offer_data = (LLOfferInfo*)notification->getUserData(); +			if(offer_data == user_data) +			{ +				continue; // don't remove the msg triggering us. it will be dequeued normally. +			} +			if(offer_data->mFromID == blocked_id)  +			{ +				gNotifyBoxView->removeChild(notification); +			} +		} +	}  } -void inventory_offer_callback(S32 option, void* user_data) -{ +void inventory_offer_callback(S32 button, void* user_data) + {  	LLChat chat;  	LLString log_message; @@ -869,9 +894,9 @@ void inventory_offer_callback(S32 option, void* user_data)  	// * callback may be called immediately,  	// * adding the mute sends a message,  	// * we can't build two messages at once.  JC -	if (option == 2) +	if (2 == button)  	{ -		gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, NULL); +		gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, user_data);  	}  	LLMessageSystem* msg = gMessageSystem; @@ -902,7 +927,8 @@ void inventory_offer_callback(S32 option, void* user_data)  	}  	// XUI:translate -	LLString from_string; +	LLString from_string; // Used in the pop-up. +	LLString chatHistory_string;  // Used in chat history.  	if (info->mFromObject == TRUE)  	{  		if (info->mFromGroup) @@ -911,10 +937,12 @@ void inventory_offer_callback(S32 option, void* user_data)  			if (gCacheName->getGroupName(info->mFromID, group_name))  			{  				from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'"; +				chatHistory_string = info->mFromName + " owned by the group '" + group_name + "'";  			}  			else  			{  				from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown group"; +				chatHistory_string = info->mFromName + " owned by an unknown group";  			}  		}  		else @@ -924,21 +952,23 @@ void inventory_offer_callback(S32 option, void* user_data)  			if (gCacheName->getName(info->mFromID, first_name, last_name))  			{  				from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; +				chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name;  			}  			else  			{  				from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown user"; +				chatHistory_string = info->mFromName + " owned by an unknown user";  			}  		}  	}  	else  	{ -		from_string = info->mFromName; +		from_string = chatHistory_string = info->mFromName;  	}  	bool busy=FALSE; -	switch(option) +	switch(button)  	{  	case IOR_ACCEPT:  		// ACCEPT. The math for the dialog works, because the accept @@ -955,7 +985,7 @@ void inventory_offer_callback(S32 option, void* user_data)  		//don't spam them if they are getting flooded  		if (check_offer_throttle(info->mFromName, true))  		{ - 			log_message = info->mFromName + " gave you " + info->mDesc + "."; +			log_message = chatHistory_string + " gave you " + info->mDesc + ".";   			chat.mText = log_message;   			LLFloaterChat::addChatHistory(chat);  		} @@ -997,7 +1027,7 @@ void inventory_offer_callback(S32 option, void* user_data)  		default:  			llwarns << "inventory_offer_callback: unknown offer type" << llendl;  			break; -		} +		}	// end switch (info->mIM)  		break;  	case IOR_BUSY: @@ -1020,6 +1050,10 @@ void inventory_offer_callback(S32 option, void* user_data)  		log_message = "You decline " + info->mDesc + " from " + info->mFromName + ".";  		chat.mText = log_message; +		if( gMuteListp->isMuted(info->mFromID ) && ! gMuteListp->isLinden(info->mFromName) )  // muting for SL-42269 +		{ +			chat.mMuted = TRUE; +		}  		LLFloaterChat::addChatHistory(chat);  		// If it's from an agent, we have to fetch the item to throw @@ -1066,7 +1100,6 @@ void inventory_offer_callback(S32 option, void* user_data)  void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)  { -  	//Until throttling is implmented, busy mode should reject inventory instead of silently  	//accepting it.  SEE SL-39554  	if (gAgent.getBusy()) @@ -1081,15 +1114,15 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)  		inventory_offer_callback(IOR_MUTE, info);  		return;  	} -	 -	if (gSavedSettings.getBOOL("ShowNewInventory") + +	// Avoid the Accept/Discard dialog if the user so desires. JC +	if (gSavedSettings.getBOOL("AutoAcceptNewInventory")  		&& (info->mType == LLAssetType::AT_NOTECARD  			|| info->mType == LLAssetType::AT_LANDMARK  			|| info->mType == LLAssetType::AT_TEXTURE))  	{  		// For certain types, just accept the items into the inventory, -		// and we'll automatically open them on receipt. -		// 0 = accept button +		// and possibly open them on receipt depending upon "ShowNewInventory".  		inventory_offer_callback(IOR_ACCEPT, info);  		return;  	} diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 279dfe2923..e15f5da537 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -208,6 +208,12 @@ LLViewerObject::~LLViewerObject()  		mJointInfo = NULL;  	} +	if (mPartSourcep) +	{ +		mPartSourcep->setDead(); +		mPartSourcep = NULL; +	} +  	// Delete memory associated with extra parameters.  	std::map<U16, ExtraParameter*>::iterator iter;  	for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index cb0df92386..6d4e8bfeff 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -501,6 +501,7 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)  		llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl;  		llinfos << groupp->getCenterAgent() << llendl;  		llinfos << part->mPosAgent << llendl; +		delete groupp;  		return NULL;  	}  	return groupp; @@ -673,6 +674,7 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp)  		if ((*iter)->getRegion() == regionp)  		{ +			delete *iter;  			i = mViewerPartGroups.erase(iter);			  		}  	} diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index b14a82e3f1..6a92ba5087 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -302,6 +302,7 @@ LLViewerPartSourceScript *LLViewerPartSourceScript::unpackPSS(LLViewerObject *so  		LLViewerPartSourceScript *new_pssp = new LLViewerPartSourceScript(source_objp);  		if (!new_pssp->mPartSysData.unpackBlock(block_num))  		{ +			delete new_pssp;  			return NULL;  		}  		if (new_pssp->mPartSysData.mTargetUUID.notNull()) @@ -340,6 +341,7 @@ LLViewerPartSourceScript *LLViewerPartSourceScript::unpackPSS(LLViewerObject *so  		LLViewerPartSourceScript *new_pssp = new LLViewerPartSourceScript(source_objp);  		if (!new_pssp->mPartSysData.unpack(dp))  		{ +			delete new_pssp;  			return NULL;  		}  		if (new_pssp->mPartSysData.mTargetUUID.notNull()) @@ -747,3 +749,4 @@ void LLViewerPartSourceChat::setColor(const LLColor4 &color)  	mColor = color;  } + diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index d81454fa8d..cc0345b79a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1199,7 +1199,7 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, BOOL saved)  		return TRUE;  	case LLAssetType::AT_LANDMARK: -		showLandmarkDialog( item ); +		openEmbeddedLandmark( item );  		return TRUE;  	case LLAssetType::AT_LSL_TEXT: @@ -1253,35 +1253,28 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item )  	showCopyToInvDialog( item );  } -/* +  void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item )  { -	// See if we can bring an existing preview to the front -	if( !LLPreview::show( item->getUUID() ) ) -	{ -		// There isn't one, so make a new preview -		S32 left, top; -		gFloaterView->getNewFloaterPosition(&left, &top); -		LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect"); -		rect.translate( left - rect.mLeft, top - rect.mTop ); - -		LLPreviewLandmark* preview = new LLPreviewLandmark( -			"preview landmark", -			rect, -			item->getName(), -			item->getUUID()); -		preview->setAuxItem( item ); -		preview->addCopyToInvButton(); -		preview->open(); -	} -}*/ +	open_landmark((LLViewerInventoryItem*)item, "   preview landmark", FALSE, item->getUUID(), TRUE); +} +  void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, BOOL saved )  {  	if (saved)  	{ -		// Copy to inventory -		copyInventory(item); +		// Pop-up the notecard floater. +		// Note: Previously would copy to inventory and rely on autodisplay to view. +		// Now that autodisplay can be turned off, we need to make this case display always.  +		// besides, there's no point adding to inventory -MG +		open_notecard( +			(LLViewerInventoryItem*)item, +			LLString("Embedded Note: ") + item->getName(), // title +			mObjectID, +			FALSE, // show_keep_discard +			LLUUID::null, // source_id +			TRUE); // take_focus  	}  	else  	{ @@ -1304,59 +1297,6 @@ void LLViewerTextEditor::onNotecardDialog( S32 option, void* userdata )  } -void LLViewerTextEditor::showLandmarkDialog( LLInventoryItem* item ) -{ -	LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item); -	gViewerWindow->alertXml("ConfirmLandmarkCopy",		 -		LLViewerTextEditor::onLandmarkDialog, (void*)info); -} - -// static -void LLViewerTextEditor::onLandmarkDialog( S32 option, void* userdata ) -{ -	LLNotecardCopyInfo *info = (LLNotecardCopyInfo *)userdata; -	if( option == 0 ) -	{ -		// Copy to inventory -		info->mTextEd->copyInventory(info->mItem); -		/* -		 * XXXPAM -		 * -		 * Yes, this is broken.  We don't show the map yet. -		 * -		LLInventoryItem* orig_item = (LLInventoryItem*)userdata; - -		// Copy to inventory -		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem; -		cloneInventoryItemToViewer(orig_item, new_item); -		U32 flags = new_item->getFlags(); -		flags &= ~LLInventoryItem::II_FLAGS_LANDMARK_VISITED; -		new_item->setFlags(flags); -		new_item->updateServer(TRUE); -		gInventory.updateItem(new_item); -		gInventory.notifyObservers(); - -		LLInventoryView* view = LLInventoryView::getActiveInventory(); -		if(view) -		{ -			view->getPanel()->setSelection(new_item->getUUID(), TAKE_FOCUS_NO); -		} - -		if( (0 == option) && gFloaterWorldMap ) -		{ -			// Note: there's a minor race condition here. -			// If the user immediately tries to teleport to the landmark, the dataserver may -			// not yet know that the user has the landmark in his inventory and so may  -			// disallow the teleport.  However, the user will need to be pretty fast to make -			// this happen, and, if it does, they haven't lost anything.  Once the dataserver -			// knows about the new item, the user will be able to teleport to it successfully. -			gFloaterWorldMap->trackLandmark(new_item->getUUID()); -			LLFloaterWorldMap::show(NULL, TRUE); -		}*/ -	} -	delete info; -} -  void LLViewerTextEditor::showCopyToInvDialog( LLInventoryItem* item )  { diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index de57b68e7d..a57b3fec7e 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -89,14 +89,12 @@ protected:  	void			openEmbeddedTexture( LLInventoryItem* item );  	void			openEmbeddedSound( LLInventoryItem* item ); -	//void			openEmbeddedLandmark( LLInventoryItem* item ); +	void			openEmbeddedLandmark( LLInventoryItem* item );  	void			openEmbeddedNotecard( LLInventoryItem* item, BOOL saved );  	void			showCopyToInvDialog( LLInventoryItem* item ); -	void			showLandmarkDialog( LLInventoryItem* item );  	static void		onCopyToInvDialog( S32 option, void* userdata );  	static void		onNotecardDialog( S32 option, void* userdata ); -	static void		onLandmarkDialog( S32 option, void* userdata );  protected:  	LLPointer<LLInventoryItem> mDragItem; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a9ed98e9db..682490440c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1559,8 +1559,6 @@ LLViewerWindow::LLViewerWindow(  	// Can't have spaces in settings.ini strings, so use underscores instead and convert them.  	LLString::replaceChar(mOverlayTitle, '_', ' '); -	gAwayTimer.stop(); -  	LLAlertDialog::setDisplayCallback(alertCallback); // call this before calling any modal dialogs  	// sync the keyboard's setting with the saved setting @@ -1857,6 +1855,7 @@ void LLViewerWindow::initWorldUI()  	gIMView = new LLIMView("gIMView", LLRect() );  	gIMView->setFollowsAll(); +	mRootView->addChild(gIMView);  	LLRect morph_view_rect = full_window;  	morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); @@ -2380,7 +2379,17 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  				case KEY_LEFT:  				case KEY_RIGHT:  				case KEY_UP: +					// let CTRL UP through for chat line history +					if( MASK_CONTROL & mask ) +					{ +						break; +					}  				case KEY_DOWN: +					// let CTRL DOWN through for chat line history +					if( MASK_CONTROL & mask ) +					{ +						break; +					}  				case KEY_PAGE_UP:  				case KEY_PAGE_DOWN:  				case KEY_HOME: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1f1145624b..0236abf127 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8013,7 +8013,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	}  	else  	{ -		llwarns << "AvatarAppearance msg received without any parameters" << llendl; +		llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;  	}  	setCompositeUpdatesEnabled( TRUE ); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index a708b735db..c03ec75081 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -412,6 +412,8 @@ class Linux_i686Manifest(LinuxManifest):                          self.path("libelfio.so")                          self.path("libuuid.so", "libuuid.so.1")                          self.path("libSDL-1.2.so.0") +                        self.path("libtcmalloc.so.0") +                        self.path("libstacktrace.so.0")                          self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason                          self.end_prefix("lib") diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp index c139d2f55c..92e2cb066a 100644 --- a/indra/win_updater/updater.cpp +++ b/indra/win_updater/updater.cpp @@ -148,7 +148,7 @@ int WINAPI get_url_into_file(WCHAR *uri, char *path, int *cancelled)  		}  #endif -		if (!data) +		if (!data[0])  		{  #if _DEBUG  			fprintf(logfile,"InternetReadFile Returned NULL data, bytes_read = %d.\n",bytes_read); | 
