diff options
Diffstat (limited to 'indra')
111 files changed, 1843 insertions, 1171 deletions
| diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index de46d89d6f..a55915af35 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1650,24 +1650,8 @@ void LLFloater::draw()  	}  	else  	{ -		//FIXME: get rid of this hack -		// draw children -		LLView* focused_child = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus()); -		BOOL focused_child_visible = FALSE; -		if (focused_child && focused_child->getParent() == this) -		{ -			focused_child_visible = focused_child->getVisible(); -			focused_child->setVisible(FALSE); -		} -  		// don't call LLPanel::draw() since we've implemented custom background rendering  		LLView::draw(); - -		if (focused_child_visible) -		{ -			focused_child->setVisible(TRUE); -		} -		drawChild(focused_child);  	}  	// update tearoff button for torn off floaters @@ -2579,6 +2563,8 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list)  			view->pushVisible(visible);  		}  	} + +	LLFloaterReg::blockShowFloaters(true);  }  void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) @@ -2596,6 +2582,8 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)  			view->popVisible();  		}  	} + +	LLFloaterReg::blockShowFloaters(false);  }  void LLFloater::setInstanceName(const std::string& name) diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index eb67e3a561..5de3934c8a 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -34,6 +34,7 @@  #include "llfloaterreg.h" +//#include "llagent.h"   #include "llfloater.h"  #include "llmultifloater.h"  #include "llfloaterreglistener.h" @@ -45,6 +46,7 @@ LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList;  LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;  LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;  std::map<std::string,std::string> LLFloaterReg::sGroupMap; +bool LLFloaterReg::sBlockShowFloaters = false;  static LLFloaterRegListener sFloaterRegListener; @@ -217,6 +219,8 @@ LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::str  //static  LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)   { +	if( sBlockShowFloaters ) +		return 0;//  	LLFloater* instance = getInstance(name, key);   	if (instance)   	{ diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index 634a235926..8a11d5c3f2 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -75,6 +75,7 @@ private:  	static instance_map_t sInstanceMap;  	static build_map_t sBuildMap;  	static std::map<std::string,std::string> sGroupMap; +	static bool sBlockShowFloaters;  public:  	// Registration @@ -152,6 +153,8 @@ public:  	{  		return dynamic_cast<T*>(showInstance(name, key, focus));  	} + +	static void blockShowFloaters(bool value) { sBlockShowFloaters = value;}  }; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index cb5aea272d..eb2b4f7705 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -70,7 +70,7 @@ const S32   SCROLL_INCREMENT_DEL = 4;	// make space for baskspacing  const F32   AUTO_SCROLL_TIME = 0.05f;  const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click. *TODO: make this equal to the double click interval? -const std::string PASSWORD_ASTERISK( "\xE2\x97\x8F" ); // U+25CF BLACK CIRCLE +const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET  static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor"); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 259522a932..75ca6d8895 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -185,7 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)  	mWriteableBgColor(p.bg_writeable_color),  	mReadOnlyBgColor(p.bg_readonly_color),  	mFocusBgColor(p.bg_focus_color), -	mReflowNeeded(FALSE), +	mReflowIndex(S32_MAX),  	mCursorPos( 0 ),  	mScrollNeeded(FALSE),  	mDesiredXPixel(-1), @@ -660,7 +660,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s  	}  	onValueChange(pos, pos + insert_len); -	needsReflow(); +	needsReflow(pos);  	return insert_len;  } @@ -720,7 +720,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)  	createDefaultSegment();  	onValueChange(pos, pos); -	needsReflow(); +	needsReflow(pos);  	return -length;	// This will be wrong if someone calls removeStringNoUndo with an excessive length  } @@ -736,7 +736,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)      getViewModel()->setDisplay(text);  	onValueChange(pos, pos + 1); -	needsReflow(); +	needsReflow(pos);  	return 1;  } @@ -762,15 +762,18 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)  	}  	segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart()); +	S32 reflow_start_index = 0;  	if (cur_seg_iter == mSegments.end())  	{  		mSegments.insert(segment_to_insert);  		segment_to_insert->linkToDocument(this); +		reflow_start_index = segment_to_insert->getStart();  	}  	else  	{  		LLTextSegmentPtr cur_segmentp = *cur_seg_iter; +		reflow_start_index = cur_segmentp->getStart();  		if (cur_segmentp->getStart() < segment_to_insert->getStart())  		{  			S32 old_segment_end = cur_segmentp->getEnd(); @@ -829,7 +832,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)  	}  	// layout potentially changed -	needsReflow(); +	needsReflow(reflow_start_index);  }  BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) @@ -1024,6 +1027,16 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)  }  //virtual +void LLTextBase::handleVisibilityChange( BOOL new_visibility ) +{ +	if(!new_visibility && mPopupMenu) +	{ +		mPopupMenu->hide(); +	} +	LLUICtrl::handleVisibilityChange(new_visibility); +} + +//virtual  void LLTextBase::setValue(const LLSD& value )  {  	setText(value.asString()); @@ -1074,15 +1087,16 @@ S32 LLTextBase::getLeftOffset(S32 width)  static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow"); -void LLTextBase::reflow(S32 start_index) +void LLTextBase::reflow()  {  	LLFastTimer ft(FTM_TEXT_REFLOW);  	updateSegments(); -	while(mReflowNeeded) +	while(mReflowIndex < S32_MAX)  	{ -		mReflowNeeded = false; +		S32 start_index = mReflowIndex; +		mReflowIndex = S32_MAX;  		// shrink document to minimum size (visible portion of text widget)  		// to force inlined widgets with follows set to shrink @@ -1609,6 +1623,12 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c  	}  } +void LLTextBase::needsReflow(S32 index) +{ +	lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl; +	mReflowIndex = llmin(mReflowIndex, index); +} +  void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params)  {  	if (new_text.empty()) return;                                                                                  @@ -2250,7 +2270,7 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e  	LLUIImagePtr image = mStyle->getImage();  	if (image.notNull())  	{ -		mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor)); +		mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor, start));  	}  } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index b5c7fab67a..3dda6f4cc8 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -122,6 +122,7 @@ public:  	/*virtual*/ BOOL		acceptsTextInput() const { return !mReadOnly; }  	/*virtual*/ void		setColor( const LLColor4& c );  	virtual     void 		setReadOnlyColor(const LLColor4 &c); +	virtual	    void		handleVisibilityChange( BOOL new_visibility );  	/*virtual*/ void		setValue(const LLSD& value );  	/*virtual*/ LLTextViewModel* getViewModel() const; @@ -149,7 +150,7 @@ public:  	void					appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());  	// force reflow of text -	void					needsReflow() { mReflowNeeded = TRUE; } +	void					needsReflow(S32 index = 0);  	S32						getLength() const { return getWText().length(); }  	S32						getLineCount() const { return mLineInfoList.size(); } @@ -291,7 +292,7 @@ protected:  	S32								getFirstVisibleLine() const;  	std::pair<S32, S32>				getVisibleLines(bool fully_visible = false);  	S32								getLeftOffset(S32 width); -	void							reflow(S32 start_index = 0); +	void							reflow();  	// cursor  	void							updateCursorXPos(); @@ -361,7 +362,7 @@ protected:  	class LLScrollContainer*	mScroller;  	// transient state -	bool						mReflowNeeded;		// need to reflow text because of change to text contents or display region +	S32							mReflowIndex;		// index at which to start reflow.  S32_MAX indicates no reflow needed.  	bool						mScrollNeeded;		// need to change scroll region because of change to cursor position  	S32							mScrollIndex;		// index of first character to keep visible in scroll region diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index e76fee9f17..7a19b7427c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1285,8 +1285,6 @@ void LLTextEditor::cut()  	gClipboard.copyFromSubstring( getWText(), left_pos, length, mSourceID );  	deleteSelection( FALSE ); -	needsReflow(); -  	onKeyStroke();  } @@ -1391,8 +1389,6 @@ void LLTextEditor::pasteHelper(bool is_primary)  	setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr()));  	deselect(); -	needsReflow(); -  	onKeyStroke();  } @@ -1787,8 +1783,6 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )  		if(text_may_have_changed)  		{ -			needsReflow(); -  			onKeyStroke();  		}  		needsScroll(); @@ -1831,8 +1825,6 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)  		// Most keystrokes will make the selection box go away, but not all will.  		deselect(); -		needsReflow(); -  		onKeyStroke();  	} @@ -1891,8 +1883,6 @@ void LLTextEditor::doDelete()  	}  	onKeyStroke(); - -	needsReflow();  }  //---------------------------------------------------------------------------- @@ -1935,8 +1925,6 @@ void LLTextEditor::undo()  		setCursorPos(pos); -	needsReflow(); -  	onKeyStroke();  } @@ -1979,8 +1967,6 @@ void LLTextEditor::redo()  		setCursorPos(pos); -	needsReflow(); -  	onKeyStroke();  } @@ -2339,8 +2325,6 @@ void LLTextEditor::insertText(const std::string &new_text)  	setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE, LLTextSegmentPtr() )); -	needsReflow(); -  	setEnabled( enabled );  } @@ -2363,8 +2347,6 @@ void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const  	LLTextSegmentPtr segment = new LLInlineViewSegment(params, old_length, old_length + widget_wide_text.size());  	insert(getLength(), widget_wide_text, FALSE, segment); -	needsReflow(); -	  	// Set the cursor and scroll position  	if( selection_start != selection_end )  	{ @@ -2389,52 +2371,6 @@ void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const  	}  } - -void LLTextEditor::replaceUrlLabel(const std::string &url, -								   const std::string &label) -{ -	// get the full (wide) text for the editor so we can change it -	LLWString text = getWText(); -	LLWString wlabel = utf8str_to_wstring(label); -	bool modified = false; -	S32 seg_start = 0; - -	// iterate through each segment looking for ones styled as links -	segment_set_t::iterator it; -	for (it = mSegments.begin(); it != mSegments.end(); ++it) -	{ -		LLTextSegment *seg = *it; -		LLStyleConstSP style = seg->getStyle(); - -		// update segment start/end length in case we replaced text earlier -		S32 seg_length = seg->getEnd() - seg->getStart(); -		seg->setStart(seg_start); -		seg->setEnd(seg_start + seg_length); - -		// if we find a link with our Url, then replace the label -		if (style->isLink() && style->getLinkHREF() == url) -		{ -			S32 start = seg->getStart(); -			S32 end = seg->getEnd(); -			text = text.substr(0, start) + wlabel + text.substr(end, text.size() - end + 1); -			seg->setEnd(start + wlabel.size()); -			modified = true; -		} - -		// work out the character offset for the next segment -		seg_start = seg->getEnd(); -	} - -	// update the editor with the new (wide) text string -	if (modified) -	{ -		getViewModel()->setDisplay(text); -		deselect(); -		setCursorPos(mCursorPos); -		needsReflow(); -	} -} -  void LLTextEditor::removeTextFromEnd(S32 num_chars)  {  	if (num_chars <= 0) return; @@ -2446,7 +2382,6 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars)  	mSelectionStart = llclamp(mSelectionStart, 0, len);  	mSelectionEnd = llclamp(mSelectionEnd, 0, len); -	needsReflow();  	needsScroll();  } @@ -2505,8 +2440,6 @@ BOOL LLTextEditor::tryToRevertToPristineState()  				i--;  			}  		} - -		needsReflow();  	}  	return isPristine(); // TRUE => success @@ -2681,7 +2614,6 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )  	startOfDoc();  	deselect(); -	needsReflow();  	return success;  } @@ -2785,7 +2717,6 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,  	mPreeditStandouts = preedit_standouts; -	needsReflow();  	setCursorPos(insert_preedit_at + caret_position);  	// Update of the preedit should be caused by some key strokes. diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 043dda8fa6..a136f9ccce 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -149,7 +149,6 @@ public:  	void			selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);  	BOOL			replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);  	void			replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); -	void			replaceUrlLabel(const std::string &url, const std::string &label);  	// Undo/redo stack  	void			blockUndo(); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 7c384b5996..77c94e7b0c 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -52,7 +52,7 @@ LLUrlEntryBase::~LLUrlEntryBase()  {  } -std::string LLUrlEntryBase::getUrl(const std::string &string) +std::string LLUrlEntryBase::getUrl(const std::string &string) const  {  	return escapeUrl(string);  } @@ -92,7 +92,7 @@ std::string LLUrlEntryBase::escapeUrl(const std::string &url) const  	return LLURI::escape(url, no_escape_chars, true);  } -std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url) +std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url) const  {  	// return the label part from [http://www.example.org Label]  	const char *text = url.c_str(); @@ -108,7 +108,7 @@ std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url)  	return unescapeUrl(url.substr(start, url.size()-start-1));  } -std::string LLUrlEntryBase::getUrlFromWikiLink(const std::string &string) +std::string LLUrlEntryBase::getUrlFromWikiLink(const std::string &string) const  {  	// return the url part from [http://www.example.org Label]  	const char *text = string.c_str(); @@ -195,7 +195,7 @@ std::string LLUrlEntryHTTPLabel::getLabel(const std::string &url, const LLUrlLab  	return getLabelFromWikiLink(url);  } -std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) +std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const  {  	return getUrlFromWikiLink(string);  } @@ -220,7 +220,7 @@ std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLU  	return unescapeUrl(url);  } -std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) +std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const  {  	if (string.find("://") == std::string::npos)  	{ @@ -610,7 +610,7 @@ std::string LLUrlEntrySLLabel::getLabel(const std::string &url, const LLUrlLabel  	return getLabelFromWikiLink(url);  } -std::string LLUrlEntrySLLabel::getUrl(const std::string &string) +std::string LLUrlEntrySLLabel::getUrl(const std::string &string) const  {  	return getUrlFromWikiLink(string);  } @@ -661,14 +661,18 @@ std::string LLUrlEntryWorldMap::getLocation(const std::string &url) const  //  LLUrlEntryNoLink::LLUrlEntryNoLink()  { -	mPattern = boost::regex("<nolink>[^[:space:]<]+</nolink>", +	mPattern = boost::regex("<nolink>[^<]*</nolink>",  							boost::regex::perl|boost::regex::icase);  	mDisabledLink = true;  } -std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +std::string LLUrlEntryNoLink::getUrl(const std::string &url) const  {  	// return the text between the <nolink> and </nolink> tags  	return url.substr(8, url.size()-8-9);  } +std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ +	return getUrl(url); +} diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 94455ac247..3abada0f24 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -71,7 +71,7 @@ public:  	boost::regex getPattern() const { return mPattern; }  	/// Return the url from a string that matched the regex -	virtual std::string getUrl(const std::string &string); +	virtual std::string getUrl(const std::string &string) const;  	/// Given a matched Url, return a label for the Url  	virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; } @@ -98,8 +98,8 @@ protected:  	std::string getIDStringFromUrl(const std::string &url) const;  	std::string escapeUrl(const std::string &url) const;  	std::string unescapeUrl(const std::string &url) const; -	std::string getLabelFromWikiLink(const std::string &url); -	std::string getUrlFromWikiLink(const std::string &string); +	std::string getLabelFromWikiLink(const std::string &url) const; +	std::string getUrlFromWikiLink(const std::string &string) const;  	void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb);   	void callObservers(const std::string &id, const std::string &label); @@ -135,7 +135,7 @@ class LLUrlEntryHTTPLabel : public LLUrlEntryBase  public:  	LLUrlEntryHTTPLabel();  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); -	/*virtual*/ std::string getUrl(const std::string &string); +	/*virtual*/ std::string getUrl(const std::string &string) const;  };  /// @@ -146,7 +146,7 @@ class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase  public:  	LLUrlEntryHTTPNoProtocol();  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); -	/*virtual*/ std::string getUrl(const std::string &string); +	/*virtual*/ std::string getUrl(const std::string &string) const;  };  /// @@ -256,7 +256,7 @@ class LLUrlEntrySLLabel : public LLUrlEntryBase  public:  	LLUrlEntrySLLabel();  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); -	/*virtual*/ std::string getUrl(const std::string &string); +	/*virtual*/ std::string getUrl(const std::string &string) const;  };  /// @@ -279,6 +279,7 @@ class LLUrlEntryNoLink : public LLUrlEntryBase  public:  	LLUrlEntryNoLink();  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +	/*virtual*/ std::string getUrl(const std::string &string) const;  };  #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 55eb8950e9..722dbe41b3 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -132,7 +132,8 @@ static bool stringHasUrl(const std::string &text)  			text.find(".com") != std::string::npos ||  			text.find(".net") != std::string::npos ||  			text.find(".edu") != std::string::npos || -			text.find(".org") != std::string::npos); +			text.find(".org") != std::string::npos || +			text.find("<nolink>") != std::string::npos);  }  bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 8d50dfe6c5..3a1985fc56 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -52,9 +52,10 @@ namespace  namespace tut  { -	void testRegex(const std::string &testname, boost::regex regex, +	void testRegex(const std::string &testname, LLUrlEntryBase &entry,  				   const char *text, const std::string &expected)  	{ +		boost::regex regex = entry.getPattern();  		std::string url = "";  		boost::cmatch result;  		bool found = boost::regex_search(text, result, regex); @@ -62,7 +63,7 @@ namespace tut  		{  			S32 start = static_cast<U32>(result[0].first - text);  			S32 end = static_cast<U32>(result[0].second - text); -			url = std::string(text+start, end-start); +			url = entry.getUrl(std::string(text+start, end-start));  		}  		ensure_equals(testname, url, expected);  	} @@ -74,74 +75,73 @@ namespace tut  		// test LLUrlEntryHTTP - standard http Urls  		//  		LLUrlEntryHTTP url; -		boost::regex r = url.getPattern(); -		testRegex("no valid url", r, +		testRegex("no valid url", url,  				  "htp://slurl.com/",  				  ""); -		testRegex("simple http (1)", r, +		testRegex("simple http (1)", url,  				  "http://slurl.com/",  				  "http://slurl.com/"); -		testRegex("simple http (2)", r, +		testRegex("simple http (2)", url,  				  "http://slurl.com",  				  "http://slurl.com"); -		testRegex("simple http (3)", r, +		testRegex("simple http (3)", url,  				  "http://slurl.com/about.php",  				  "http://slurl.com/about.php"); -		testRegex("simple https", r, +		testRegex("simple https", url,  				  "https://slurl.com/about.php",  				  "https://slurl.com/about.php"); -		testRegex("http in text (1)", r, +		testRegex("http in text (1)", url,  				  "XX http://slurl.com/ XX",  				  "http://slurl.com/"); -		testRegex("http in text (2)", r, +		testRegex("http in text (2)", url,  				  "XX http://slurl.com/about.php XX",  				  "http://slurl.com/about.php"); -		testRegex("https in text", r, +		testRegex("https in text", url,  				  "XX https://slurl.com/about.php XX",  				  "https://slurl.com/about.php"); -		testRegex("two http urls", r, +		testRegex("two http urls", url,  				  "XX http://slurl.com/about.php http://secondlife.com/ XX",  				  "http://slurl.com/about.php"); -		testRegex("http url with port and username", r, +		testRegex("http url with port and username", url,  				  "XX http://nobody@slurl.com:80/about.php http://secondlife.com/ XX",  				  "http://nobody@slurl.com:80/about.php"); -		testRegex("http url with port, username, and query string", r, +		testRegex("http url with port, username, and query string", url,  				  "XX http://nobody@slurl.com:80/about.php?title=hi%20there http://secondlife.com/ XX",  				  "http://nobody@slurl.com:80/about.php?title=hi%20there");  		// note: terminating commas will be removed by LLUrlRegistry:findUrl() -		testRegex("http url with commas in middle and terminating", r, +		testRegex("http url with commas in middle and terminating", url,  				  "XX http://slurl.com/?title=Hi,There, XX",  				  "http://slurl.com/?title=Hi,There,");  		// note: terminating periods will be removed by LLUrlRegistry:findUrl() -		testRegex("http url with periods in middle and terminating", r, +		testRegex("http url with periods in middle and terminating", url,  				  "XX http://slurl.com/index.php. XX",  				  "http://slurl.com/index.php.");  		// DEV-19842: Closing parenthesis ")" breaks urls -		testRegex("http url with brackets (1)", r, +		testRegex("http url with brackets (1)", url,  				  "XX http://en.wikipedia.org/wiki/JIRA_(software) XX",  				  "http://en.wikipedia.org/wiki/JIRA_(software)");  		// DEV-19842: Closing parenthesis ")" breaks urls -		testRegex("http url with brackets (2)", r,  +		testRegex("http url with brackets (2)", url,   				  "XX http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg XX",  				  "http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg");  		// DEV-10353: URLs in chat log terminated incorrectly when newline in chat -		testRegex("http url with newlines", r, +		testRegex("http url with newlines", url,  				  "XX\nhttp://www.secondlife.com/\nXX",  				  "http://www.secondlife.com/");  	} @@ -153,39 +153,38 @@ namespace tut  		// test LLUrlEntryHTTPLabel - wiki-style http Urls with labels  		//  		LLUrlEntryHTTPLabel url; -		boost::regex r = url.getPattern(); -		testRegex("invalid wiki url [1]", r, +		testRegex("invalid wiki url [1]", url,  				  "[http://www.example.org]",  				  ""); -		testRegex("invalid wiki url [2]", r, +		testRegex("invalid wiki url [2]", url,  				  "[http://www.example.org",  				  ""); -		testRegex("invalid wiki url [3]", r, +		testRegex("invalid wiki url [3]", url,  				  "[http://www.example.org Label",  				  ""); -		testRegex("example.org with label (spaces)", r, +		testRegex("example.org with label (spaces)", url,  				  "[http://www.example.org  Text]", -				  "[http://www.example.org  Text]"); +				  "http://www.example.org"); -		testRegex("example.org with label (tabs)", r, +		testRegex("example.org with label (tabs)", url,  				  "[http://www.example.org\t Text]", -				  "[http://www.example.org\t Text]"); +				  "http://www.example.org"); -		testRegex("SL http URL with label", r, +		testRegex("SL http URL with label", url,  				  "[http://www.secondlife.com/ Second Life]", -				  "[http://www.secondlife.com/ Second Life]"); +				  "http://www.secondlife.com/"); -		testRegex("SL https URL with label", r, +		testRegex("SL https URL with label", url,  				  "XXX [https://www.secondlife.com/ Second Life] YYY", -				  "[https://www.secondlife.com/ Second Life]"); +				  "https://www.secondlife.com/"); -		testRegex("SL http URL with label", r, +		testRegex("SL http URL with label", url,  				  "[http://www.secondlife.com/?test=Hi%20There Second Life]", -				  "[http://www.secondlife.com/?test=Hi%20There Second Life]"); +				  "http://www.secondlife.com/?test=Hi%20There");  	}  	template<> template<> @@ -195,69 +194,68 @@ namespace tut  		// test LLUrlEntrySLURL - second life URLs  		//  		LLUrlEntrySLURL url; -		boost::regex r = url.getPattern(); -		testRegex("no valid slurl [1]", r, +		testRegex("no valid slurl [1]", url,  				  "htp://slurl.com/secondlife/Ahern/50/50/50/",  				  ""); -		testRegex("no valid slurl [2]", r, +		testRegex("no valid slurl [2]", url,  				  "http://slurl.com/secondlife/",  				  ""); -		testRegex("no valid slurl [3]", r, +		testRegex("no valid slurl [3]", url,  				  "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/",  				  ""); -		testRegex("Ahern (50,50,50) [1]", r, +		testRegex("Ahern (50,50,50) [1]", url,  				  "http://slurl.com/secondlife/Ahern/50/50/50/",  				  "http://slurl.com/secondlife/Ahern/50/50/50/"); -		testRegex("Ahern (50,50,50) [2]", r, +		testRegex("Ahern (50,50,50) [2]", url,  				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/ XXX",  				  "http://slurl.com/secondlife/Ahern/50/50/50/"); -		testRegex("Ahern (50,50,50) [3]", r, +		testRegex("Ahern (50,50,50) [3]", url,  				  "XXX http://slurl.com/secondlife/Ahern/50/50/50 XXX",  				  "http://slurl.com/secondlife/Ahern/50/50/50"); -		testRegex("Ahern (50,50,50) multicase", r, +		testRegex("Ahern (50,50,50) multicase", url,  				  "XXX http://SLUrl.com/SecondLife/Ahern/50/50/50/ XXX",  				  "http://SLUrl.com/SecondLife/Ahern/50/50/50/"); -		testRegex("Ahern (50,50) [1]", r, +		testRegex("Ahern (50,50) [1]", url,  				  "XXX http://slurl.com/secondlife/Ahern/50/50/ XXX",  				  "http://slurl.com/secondlife/Ahern/50/50/"); -		testRegex("Ahern (50,50) [2]", r, +		testRegex("Ahern (50,50) [2]", url,  				  "XXX http://slurl.com/secondlife/Ahern/50/50 XXX",  				  "http://slurl.com/secondlife/Ahern/50/50"); -		testRegex("Ahern (50)", r, +		testRegex("Ahern (50)", url,  				  "XXX http://slurl.com/secondlife/Ahern/50 XXX",  				  "http://slurl.com/secondlife/Ahern/50"); -		testRegex("Ahern", r, +		testRegex("Ahern", url,  				  "XXX http://slurl.com/secondlife/Ahern/ XXX",  				  "http://slurl.com/secondlife/Ahern/"); -		testRegex("Ahern SLURL with title", r, +		testRegex("Ahern SLURL with title", url,  				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX",  				  "http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!"); -		testRegex("Ahern SLURL with msg", r, +		testRegex("Ahern SLURL with msg", url,  				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here. XXX",  				  "http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here.");  		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat -		testRegex("SLURL with brackets", r, +		testRegex("SLURL with brackets", url,  				  "XXX http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30 XXX",  				  "http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30");  		// DEV-35459: SLURLs and teleport Links not parsed properly -		testRegex("SLURL with quote", r, +		testRegex("SLURL with quote", url,  				  "XXX http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701 XXX", -				  "http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701"); +				  "http://slurl.com/secondlife/A%27ksha%20Oasis/41/166/701");  	}  	template<> template<> @@ -267,33 +265,32 @@ namespace tut  		// test LLUrlEntryAgent - secondlife://app/agent Urls  		//  		LLUrlEntryAgent url; -		boost::regex r = url.getPattern(); -		testRegex("Invalid Agent Url", r, +		testRegex("Invalid Agent Url", url,  				  "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about",  				  ""); -		testRegex("Agent Url ", r, +		testRegex("Agent Url ", url,  				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",  				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); -		testRegex("Agent Url in text", r, +		testRegex("Agent Url in text", url,  				  "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX",  				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); -		testRegex("Agent Url multicase", r, +		testRegex("Agent Url multicase", url,  				  "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX",  				  "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About"); -		testRegex("Agent Url alternate command", r, +		testRegex("Agent Url alternate command", url,  				  "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",  				  "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar"); -		testRegex("Nebraska Agent Url ", r, +		testRegex("Nebraska Agent Url ", url,  				  "x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",  				  "x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		 -		testRegex("Nebraska Agent Url Multicase with Text", r, +		testRegex("Nebraska Agent Url Multicase with Text", url,  				  "M x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",  				  "x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		  	} @@ -305,33 +302,32 @@ namespace tut  		// test LLUrlEntryGroup - secondlife://app/group Urls  		//  		LLUrlEntryGroup url; -		boost::regex r = url.getPattern(); -		testRegex("Invalid Group Url", r, +		testRegex("Invalid Group Url", url,  				  "secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about",  				  ""); -		testRegex("Group Url ", r, +		testRegex("Group Url ", url,  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about",  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about"); -		testRegex("Group Url ", r, +		testRegex("Group Url ", url,  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect",  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect"); -		testRegex("Group Url in text", r, +		testRegex("Group Url in text", url,  				  "XXX secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about XXX",  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about"); -		testRegex("Group Url multicase", r, +		testRegex("Group Url multicase", url,  				  "XXX secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About XXX",  				  "secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About"); -		testRegex("Nebraska Group Url ", r, +		testRegex("Nebraska Group Url ", url,  				  "x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",  				  "x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		 -		testRegex("Nebraska Group Url Multicase ith Text", r, +		testRegex("Nebraska Group Url Multicase ith Text", url,  				  "M x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",  				  "x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		 @@ -344,47 +340,46 @@ namespace tut  		// test LLUrlEntryPlace - secondlife://<location> URLs  		//  		LLUrlEntryPlace url; -		boost::regex r = url.getPattern(); -		testRegex("no valid slurl [1]", r, +		testRegex("no valid slurl [1]", url,  				  "secondlife://Ahern/FOO/50/",  				  ""); -		testRegex("Ahern (50,50,50) [1]", r, +		testRegex("Ahern (50,50,50) [1]", url,  				  "secondlife://Ahern/50/50/50/",  				  "secondlife://Ahern/50/50/50/"); -		testRegex("Ahern (50,50,50) [2]", r, +		testRegex("Ahern (50,50,50) [2]", url,  				  "XXX secondlife://Ahern/50/50/50/ XXX",  				  "secondlife://Ahern/50/50/50/"); -		testRegex("Ahern (50,50,50) [3]", r, +		testRegex("Ahern (50,50,50) [3]", url,  				  "XXX secondlife://Ahern/50/50/50 XXX",  				  "secondlife://Ahern/50/50/50"); -		testRegex("Ahern (50,50,50) multicase", r, +		testRegex("Ahern (50,50,50) multicase", url,  				  "XXX SecondLife://Ahern/50/50/50/ XXX",  				  "SecondLife://Ahern/50/50/50/"); -		testRegex("Ahern (50,50) [1]", r, +		testRegex("Ahern (50,50) [1]", url,  				  "XXX secondlife://Ahern/50/50/ XXX",  				  "secondlife://Ahern/50/50/"); -		testRegex("Ahern (50,50) [2]", r, +		testRegex("Ahern (50,50) [2]", url,  				  "XXX secondlife://Ahern/50/50 XXX",  				  "secondlife://Ahern/50/50");  		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat -		testRegex("SLURL with brackets", r, +		testRegex("SLURL with brackets", url,  				  "XXX secondlife://Burning%20Life%20(Hyper)/27/210/30 XXX",  				  "secondlife://Burning%20Life%20(Hyper)/27/210/30");  		// DEV-35459: SLURLs and teleport Links not parsed properly -		testRegex("SLURL with quote", r, +		testRegex("SLURL with quote", url,  				  "XXX secondlife://A'ksha%20Oasis/41/166/701 XXX", -				  "secondlife://A'ksha%20Oasis/41/166/701"); +			          "secondlife://A%27ksha%20Oasis/41/166/701"); -		testRegex("Nebraska All Hands (50,50) [2] with text", r, +		testRegex("Nebraska All Hands (50,50) [2] with text", url,  				  "XXX x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50 XXX",  				  "x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50");		  	} @@ -396,21 +391,20 @@ namespace tut  		// test LLUrlEntryParcel - secondlife://app/parcel Urls  		//  		LLUrlEntryParcel url; -		boost::regex r = url.getPattern(); -		testRegex("Invalid Classified Url", r, +		testRegex("Invalid Classified Url", url,  				  "secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about",  				  ""); -		testRegex("Classified Url ", r, +		testRegex("Classified Url ", url,  				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about",  				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about"); -		testRegex("Classified Url in text", r, +		testRegex("Classified Url in text", url,  				  "XXX secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about XXX",  				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about"); -		testRegex("Classified Url multicase", r, +		testRegex("Classified Url multicase", url,  				  "XXX secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About XXX",  				  "secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About");  	} @@ -421,75 +415,74 @@ namespace tut  		// test LLUrlEntryTeleport - secondlife://app/teleport URLs  		//  		LLUrlEntryTeleport url; -		boost::regex r = url.getPattern(); -		testRegex("no valid teleport [1]", r, +		testRegex("no valid teleport [1]", url,  				  "http://slurl.com/secondlife/Ahern/50/50/50/",  				  ""); -		testRegex("no valid teleport [2]", r, +		testRegex("no valid teleport [2]", url,  				  "secondlife:///app/teleport/",  				  ""); -		testRegex("no valid teleport [3]", r, +		testRegex("no valid teleport [3]", url,  				  "second-life:///app/teleport/Ahern/50/50/50/",  				  ""); -		testRegex("no valid teleport [3]", r, +		testRegex("no valid teleport [3]", url,  				  "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/",  				  ""); -		testRegex("Ahern (50,50,50) [1]", r, +		testRegex("Ahern (50,50,50) [1]", url,  				  "secondlife:///app/teleport/Ahern/50/50/50/",  				  "secondlife:///app/teleport/Ahern/50/50/50/"); -		testRegex("Ahern (50,50,50) [2]", r, +		testRegex("Ahern (50,50,50) [2]", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX",  				  "secondlife:///app/teleport/Ahern/50/50/50/"); -		testRegex("Ahern (50,50,50) [3]", r, +		testRegex("Ahern (50,50,50) [3]", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50/50 XXX",  				  "secondlife:///app/teleport/Ahern/50/50/50"); -		testRegex("Ahern (50,50,50) multicase", r, +		testRegex("Ahern (50,50,50) multicase", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX",  				  "secondlife:///app/teleport/Ahern/50/50/50/"); -		testRegex("Ahern (50,50) [1]", r, +		testRegex("Ahern (50,50) [1]", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50/ XXX",  				  "secondlife:///app/teleport/Ahern/50/50/"); -		testRegex("Ahern (50,50) [2]", r, +		testRegex("Ahern (50,50) [2]", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50 XXX",  				  "secondlife:///app/teleport/Ahern/50/50"); -		testRegex("Ahern (50)", r, +		testRegex("Ahern (50)", url,  				  "XXX secondlife:///app/teleport/Ahern/50 XXX",  				  "secondlife:///app/teleport/Ahern/50"); -		testRegex("Ahern", r, +		testRegex("Ahern", url,  				  "XXX secondlife:///app/teleport/Ahern/ XXX",  				  "secondlife:///app/teleport/Ahern/"); -		testRegex("Ahern teleport with title", r, +		testRegex("Ahern teleport with title", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX",  				  "secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!"); -		testRegex("Ahern teleport with msg", r, +		testRegex("Ahern teleport with msg", url,  				  "XXX secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here. XXX",  				  "secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here.");  		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat -		testRegex("Teleport with brackets", r, +		testRegex("Teleport with brackets", url,  				  "XXX secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30 XXX",  				  "secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30");  		// DEV-35459: SLURLs and teleport Links not parsed properly -		testRegex("Teleport url with quote", r, +		testRegex("Teleport url with quote", url,  				  "XXX secondlife:///app/teleport/A'ksha%20Oasis/41/166/701 XXX", -				  "secondlife:///app/teleport/A'ksha%20Oasis/41/166/701"); +				  "secondlife:///app/teleport/A%27ksha%20Oasis/41/166/701"); -		testRegex("Nebraska All Hands", r, +		testRegex("Nebraska All Hands", url,  				  "XXX x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50 XXX",  				  "x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50");		  	} @@ -501,33 +494,32 @@ namespace tut  		// test LLUrlEntrySL - general secondlife:// URLs  		//  		LLUrlEntrySL url; -		boost::regex r = url.getPattern(); -		testRegex("no valid slapp [1]", r, +		testRegex("no valid slapp [1]", url,  				  "http:///app/",  				  ""); -		testRegex("valid slapp [1]", r, +		testRegex("valid slapp [1]", url,  				  "secondlife:///app/",  				  "secondlife:///app/"); -		testRegex("valid slapp [2]", r, +		testRegex("valid slapp [2]", url,  				  "secondlife:///app/teleport/Ahern/50/50/50/",  				  "secondlife:///app/teleport/Ahern/50/50/50/"); -		testRegex("valid slapp [3]", r, +		testRegex("valid slapp [3]", url,  				  "secondlife:///app/foo",  				  "secondlife:///app/foo"); -		testRegex("valid slapp [4]", r, +		testRegex("valid slapp [4]", url,  				  "secondlife:///APP/foo?title=Hi%20There",  				  "secondlife:///APP/foo?title=Hi%20There"); -		testRegex("valid slapp [5]", r, +		testRegex("valid slapp [5]", url,  				  "secondlife://host/app/",  				  "secondlife://host/app/"); -		testRegex("valid slapp [6]", r, +		testRegex("valid slapp [6]", url,  				  "secondlife://host:8080/foo/bar",  				  "secondlife://host:8080/foo/bar");  	} @@ -539,35 +531,34 @@ namespace tut  		// test LLUrlEntrySLLabel - general secondlife:// URLs with labels  		//  		LLUrlEntrySLLabel url; -		boost::regex r = url.getPattern(); -		testRegex("invalid wiki url [1]", r, +		testRegex("invalid wiki url [1]", url,  				  "[secondlife:///app/]",  				  ""); -		testRegex("invalid wiki url [2]", r, +		testRegex("invalid wiki url [2]", url,  				  "[secondlife:///app/",  				  ""); -		testRegex("invalid wiki url [3]", r, +		testRegex("invalid wiki url [3]", url,  				  "[secondlife:///app/ Label",  				  ""); -		testRegex("agent slurl with label (spaces)", r, +		testRegex("agent slurl with label (spaces)", url,  				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  Text]", -				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  Text]"); +				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); -		testRegex("agent slurl with label (tabs)", r, +		testRegex("agent slurl with label (tabs)", url,  				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]", -				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]"); +				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); -		testRegex("agent slurl with label", r, +		testRegex("agent slurl with label", url,  				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]", -				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]"); +				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); -		testRegex("teleport slurl with label", r, +		testRegex("teleport slurl with label", url,  				  "XXX [secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern] YYY", -				  "[secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern]"); +				  "secondlife:///app/teleport/Ahern/50/50/50/");  	}  	template<> template<> @@ -577,70 +568,98 @@ namespace tut  		// test LLUrlEntryHTTPNoProtocol - general URLs without a protocol  		//  		LLUrlEntryHTTPNoProtocol url; -		boost::regex r = url.getPattern(); -		testRegex("naked .com URL", r, +		testRegex("naked .com URL", url,  				  "see google.com", -				  "google.com"); +				  "http://google.com"); -		testRegex("naked .org URL", r, +		testRegex("naked .org URL", url,  				  "see en.wikipedia.org for details", -				  "en.wikipedia.org"); +				  "http://en.wikipedia.org"); -		testRegex("naked .net URL", r, +		testRegex("naked .net URL", url,  				  "example.net", -				  "example.net"); +				  "http://example.net"); -		testRegex("naked .edu URL (2 instances)", r, +		testRegex("naked .edu URL (2 instances)", url,  				  "MIT web site is at web.mit.edu and also www.mit.edu", -				  "web.mit.edu"); +				  "http://web.mit.edu"); -		testRegex("don't match e-mail addresses", r, +		testRegex("don't match e-mail addresses", url,  				  "test@lindenlab.com",  				  ""); -		testRegex(".com URL with path", r, +		testRegex(".com URL with path", url,  				  "see secondlife.com/status for grid status", -				  "secondlife.com/status"); +				  "http://secondlife.com/status"); -		testRegex(".com URL with port", r, +		testRegex(".com URL with port", url,  				  "secondlife.com:80", -				  "secondlife.com:80"); +				  "http://secondlife.com:80"); -		testRegex(".com URL with port and path", r, +		testRegex(".com URL with port and path", url,  				  "see secondlife.com:80/status", -				  "secondlife.com:80/status"); +				  "http://secondlife.com:80/status"); -		testRegex("www.*.com URL with port and path", r, +		testRegex("www.*.com URL with port and path", url,  				  "see www.secondlife.com:80/status", -				  "www.secondlife.com:80/status"); +				  "http://www.secondlife.com:80/status"); -		testRegex("invalid .com URL [1]", r, +		testRegex("invalid .com URL [1]", url,  				  "..com",  				  ""); -		testRegex("invalid .com URL [2]", r, +		testRegex("invalid .com URL [2]", url,  				  "you.come",  				  ""); -		testRegex("invalid .com URL [3]", r, +		testRegex("invalid .com URL [3]", url,  				  "recommended",  				  ""); -		testRegex("invalid .edu URL", r, +		testRegex("invalid .edu URL", url,  				  "hi there scheduled maitenance has begun",  				  ""); -		testRegex("invalid .net URL", r, +		testRegex("invalid .net URL", url,  				  "foo.netty",  				  ""); -		testRegex("XML tags around URL [1]", r, +		testRegex("XML tags around URL [1]", url,  				  "<foo>secondlife.com</foo>", -				  "secondlife.com"); +				  "http://secondlife.com"); -		testRegex("XML tags around URL [2]", r, +		testRegex("XML tags around URL [2]", url,  				  "<foo>secondlife.com/status?bar=1</foo>", -				  "secondlife.com/status?bar=1"); +				  "http://secondlife.com/status?bar=1"); +	} + +	template<> template<> +	void object::test<12>() +	{ +		// +		// test LLUrlEntryNoLink - turn off hyperlinking +		// +		LLUrlEntryNoLink url; + +		testRegex("<nolink> [1]", url, +				  "<nolink>google.com</nolink>", +				  "google.com"); + +		testRegex("<nolink> [2]", url, +				  "<nolink>google.com", +				  ""); + +		testRegex("<nolink> [3]", url, +				  "google.com</nolink>", +				  ""); + +		testRegex("<nolink> [4]", url, +				  "<nolink>Hello World</nolink>", +				  "Hello World"); + +		testRegex("<nolink> [5]", url, +				  "<nolink>My Object</nolink>", +				  "My Object");  	}  } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9e561bdf96..fe3d7b7c60 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7835,7 +7835,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>1</integer> +      <integer>0</integer>      </map>      <key>ShowCrosshairs</key>      <map> diff --git a/indra/newview/installers/darwin/firstlook-dmg/_DS_Store b/indra/newview/installers/darwin/firstlook-dmg/_DS_StoreBinary files differ index 9d9fd897e7..495ec37f53 100644 --- a/indra/newview/installers/darwin/firstlook-dmg/_DS_Store +++ b/indra/newview/installers/darwin/firstlook-dmg/_DS_Store diff --git a/indra/newview/installers/darwin/fix_application_icon_position.sh b/indra/newview/installers/darwin/fix_application_icon_position.sh index a0b72a89f2..c6b92589db 100644 --- a/indra/newview/installers/darwin/fix_application_icon_position.sh +++ b/indra/newview/installers/darwin/fix_application_icon_position.sh @@ -4,11 +4,14 @@ cp -r ./../../../build-darwin-i386/newview/*.dmg ~/Desktop/TempBuild.dmg  hdid ~/Desktop/TempBuild.dmg  open -a finder /Volumes/Second\ Life\ Installer  osascript dmg-cleanup.applescript -cp /Volumes/Second\ Life\ Installer/.DS_Store ~/Desktop/_DS_Store -chflags nohidden ~/Desktop/_DS_Store -cp ~/Desktop/_DS_Store ./firstlook-dmg/_DS_Store -cp ~/Desktop/_DS_Store ./publicnightly-dmg/_DS_Store -cp ~/Desktop/_DS_Store ./release-dmg/_DS_Store -cp ~/Desktop/_DS_Store ./releasecandidate-dmg/_DS_Store  umount /Volumes/Second\ Life\ Installer/ -rm ~/Desktop/_DS_Store ~/Desktop/TempBuild.dmg +hdid ~/Desktop/TempBuild.dmg +open -a finder /Volumes/Second\ Life\ Installer +#cp /Volumes/Second\ Life\ Installer/.DS_Store ~/Desktop/_DS_Store +#chflags nohidden ~/Desktop/_DS_Store +#cp ~/Desktop/_DS_Store ./firstlook-dmg/_DS_Store +#cp ~/Desktop/_DS_Store ./publicnightly-dmg/_DS_Store +#cp ~/Desktop/_DS_Store ./release-dmg/_DS_Store +#cp ~/Desktop/_DS_Store ./releasecandidate-dmg/_DS_Store +#umount /Volumes/Second\ Life\ Installer/ +#rm ~/Desktop/_DS_Store ~/Desktop/TempBuild.dmg diff --git a/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store b/indra/newview/installers/darwin/publicnightly-dmg/_DS_StoreBinary files differ index 9d9fd897e7..495ec37f53 100644 --- a/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store +++ b/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store diff --git a/indra/newview/installers/darwin/release-dmg/_DS_Store b/indra/newview/installers/darwin/release-dmg/_DS_StoreBinary files differ index 9d9fd897e7..495ec37f53 100644 --- a/indra/newview/installers/darwin/release-dmg/_DS_Store +++ b/indra/newview/installers/darwin/release-dmg/_DS_Store diff --git a/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store b/indra/newview/installers/darwin/releasecandidate-dmg/_DS_StoreBinary files differ index 9d9fd897e7..495ec37f53 100644 --- a/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store +++ b/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index ca50201742..e4e0256000 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -474,6 +474,7 @@ void LLBottomTray::onContextMenuItemClicked(const LLSD& userdata)  	else if (item == "paste")  	{  		edit_box->paste(); +		edit_box->setFocus(TRUE);  	}  	else if (item == "delete")  	{ diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index d11859767f..f344aa2929 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -53,8 +53,11 @@  #include "llagent.h"  #include "llnotificationsutil.h"  #include "lltoastnotifypanel.h" +#include "lltooltip.h"  #include "llviewerregion.h" +#include "llviewertexteditor.h"  #include "llworld.h" +#include "lluiconstants.h"  #include "llsidetray.h"//for blocked objects panel @@ -110,6 +113,34 @@ public:  		return LLPanel::handleMouseUp(x,y,mask);  	} +	//*TODO remake it using mouse enter/leave and static LLHandle<LLIconCtrl> to add/remove as a child +	BOOL handleToolTip(S32 x, S32 y, MASK mask) +	{ +		LLViewerTextEditor* name = getChild<LLViewerTextEditor>("user_name"); +		if (name && name->parentPointInView(x, y) && mAvatarID.notNull() && SYSTEM_FROM != mFrom) +		{ + +			// Spawn at right side of the name textbox. +			LLRect sticky_rect = name->calcScreenRect(); +			S32 icon_x = llmin(sticky_rect.mLeft + name->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3); + +			LLToolTip::Params params; +			params.background_visible(false); +			params.click_callback(boost::bind(&LLChatHistoryHeader::onHeaderPanelClick, this, 0, 0, 0)); +			params.delay_time(0.0f);		// spawn instantly on hover +			params.image(LLUI::getUIImage("Info_Small")); +			params.message(""); +			params.padding(0); +			params.pos(LLCoordGL(icon_x, sticky_rect.mTop - 2)); +			params.sticky_rect(sticky_rect); + +			LLToolTipMgr::getInstance()->show(params); +			return TRUE; +		} + +		return LLPanel::handleToolTip(x, y, mask); +	} +  	void onObjectIconContextMenuItemClicked(const LLSD& userdata)  	{  		std::string level = userdata.asString(); @@ -579,18 +610,25 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  				url += "?name=" + chat.mFromName;  				url += "&owner=" + args["owner_id"].asString(); -				LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); -				if (region) +				std::string slurl = args["slurl"].asString(); +				if (slurl.empty())  				{ +				    LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); +				    if(region) +				      {  					LLSLURL region_slurl(region->getName(), chat.mPosAgent); -					url += "&slurl=" + region_slurl.getLocationString(); +					slurl = region_slurl.getLocationString(); +				      }  				} +				url += "&slurl=" + slurl;  				// set the link for the object name to be the objectim SLapp +				// (don't let object names with hyperlinks override our objectim Url)  				LLStyle::Params link_params(style_params);  				link_params.color.control = "HTMLLinkColor";  				link_params.link_href = url; -				mEditor->appendText(chat.mFromName + delimiter, false, link_params); +				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>"  + delimiter, +									false, link_params);  			}  			else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() )  			{ @@ -663,8 +701,36 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  		{  			LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(  					notification); +			//we can't set follows in xml since it broke toasts behavior  			notify_box->setFollowsLeft();  			notify_box->setFollowsRight(); +			notify_box->setFollowsTop(); + +			LLButton* accept_button = notify_box->getChild<LLButton> ("Accept", +					TRUE); +			if (accept_button != NULL) +			{ +				accept_button->setFollowsNone(); +				accept_button->setOrigin(2*HPAD, accept_button->getRect().mBottom); +			} + +			LLButton* decline_button = notify_box->getChild<LLButton> ( +					"Decline", TRUE); +			if (accept_button != NULL && decline_button != NULL) +			{ +				decline_button->setFollowsNone(); +				decline_button->setOrigin(4*HPAD +						+ accept_button->getRect().getWidth(), +						decline_button->getRect().mBottom); +			} + +			LLTextEditor* text_editor = notify_box->getChild<LLTextEditor>("text_editor_box", TRUE); +			S32 text_heigth = 0; +			if(text_editor != NULL) +			{ +				text_heigth = text_editor->getTextBoundingRect().getHeight(); +			} +  			//Prepare the rect for the view  			LLRect target_rect = mEditor->getDocumentView()->getRect();  			// squeeze down the widget by subtracting padding off left and right @@ -674,6 +740,15 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  					notify_box->getRect().getHeight());  			notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom); +			if (text_editor != NULL) +			{ +				S32 text_heigth_delta = +						text_editor->getTextBoundingRect().getHeight() +								- text_heigth; +				notify_box->reshape(target_rect.getWidth(), +								notify_box->getRect().getHeight() + text_heigth_delta); +			} +  			LLInlineViewSegment::Params params;  			params.view = notify_box;  			params.left_pad = mLeftWidgetPad; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index f7f7ee83af..f772aea4bd 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -258,8 +258,12 @@ BOOL	LLNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)  BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)  { +	/* +	fix for request  EXT-4780 +	leaving this commented since I don't remember why ew block those messages...  	if(mSourceType != CHAT_SOURCE_AGENT)  		return LLPanel::handleMouseUp(x,y,mask); +    */  	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);  	S32 local_x = x - text_box->getRect().mLeft; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 5a10b688da..651dabff9e 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -44,7 +44,6 @@  #include "llquaternion.h"  #include "xform.h"  #include "llmemtype.h" -#include "llprimitive.h"  #include "lldarray.h"  #include "llviewerobject.h"  #include "llrect.h" diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index e0a9e080fa..3818ee6f78 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -116,7 +116,7 @@ LLExpandableTextBox::LLTextBoxEx::Params::Params()  }  LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p) -:	LLTextBox(p), +:	LLTextEditor(p),  	mExpanderLabel(p.more_label),  	mExpanderVisible(false)  { @@ -127,7 +127,7 @@ LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p)  void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL called_from_parent)  {  	hideExpandText(); -	LLTextBox::reshape(width, height, called_from_parent); +	LLTextEditor::reshape(width, height, called_from_parent);  	if (getTextPixelHeight() > getRect().getHeight())  	{ @@ -140,7 +140,7 @@ void LLExpandableTextBox::LLTextBoxEx::setText(const LLStringExplicit& text,cons  	// LLTextBox::setText will obliterate the expander segment, so make sure  	// we generate it again by clearing mExpanderVisible  	mExpanderVisible = false; -	LLTextBox::setText(text, input_params); +	LLTextEditor::setText(text, input_params);  	// text contents have changed, segments are cleared out  	// so hide the expander and determine if we need it @@ -201,6 +201,11 @@ S32 LLExpandableTextBox::LLTextBoxEx::getVerticalTextDelta()  	return text_height - textbox_height;  } +S32 LLExpandableTextBox::LLTextBoxEx::getTextPixelHeight() +{ +	return getTextBoundingRect().getHeight(); +} +  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index 2b4f9e527c..58316ddb98 100644 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -33,7 +33,7 @@  #ifndef LL_LLEXPANDABLETEXTBOX_H  #define LL_LLEXPANDABLETEXTBOX_H -#include "lltextbox.h" +#include "lltexteditor.h"  #include "llscrollcontainer.h"  /** @@ -49,10 +49,10 @@ protected:  	 * Extended text box. "More" link will appear at end of text if   	 * text is too long to fit into text box size.  	 */ -	class LLTextBoxEx : public LLTextBox +	class LLTextBoxEx : public LLTextEditor  	{  	public: -		struct Params :	public LLInitParam::Block<Params, LLTextBox::Params> +		struct Params :	public LLInitParam::Block<Params, LLTextEditor::Params>  		{  			Mandatory<std::string> more_label;  			Params(); @@ -70,6 +70,11 @@ protected:  		virtual S32 getVerticalTextDelta();  		/** +		 * Returns the height of text rect. +		 */ +		S32 getTextPixelHeight(); + +		/**  		 * Shows "More" link  		 */  		void showExpandText(); diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 60f150bd96..904655cdc8 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -86,38 +86,40 @@ const F32 BASE_ANIM_TIME_OFFSET = 5.f;  std::string STATUS[] =  { -  "E_ST_OK", -  "E_ST_EOF", -  "E_ST_NO_CONSTRAINT", -  "E_ST_NO_FILE", -"E_ST_NO_HIER", -"E_ST_NO_JOINT", -"E_ST_NO_NAME", -"E_ST_NO_OFFSET", -"E_ST_NO_CHANNELS", -"E_ST_NO_ROTATION", -"E_ST_NO_AXIS", -"E_ST_NO_MOTION", -"E_ST_NO_FRAMES", -"E_ST_NO_FRAME_TIME", -"E_ST_NO_POS", -"E_ST_NO_ROT", -"E_ST_NO_XLT_FILE", -"E_ST_NO_XLT_HEADER", -"E_ST_NO_XLT_NAME", -"E_ST_NO_XLT_IGNORE", -"E_ST_NO_XLT_RELATIVE", -"E_ST_NO_XLT_OUTNAME", -"E_ST_NO_XLT_MATRIX", -"E_ST_NO_XLT_MERGECHILD", -"E_ST_NO_XLT_MERGEPARENT", -"E_ST_NO_XLT_PRIORITY", -"E_ST_NO_XLT_LOOP", -"E_ST_NO_XLT_EASEIN", -"E_ST_NO_XLT_EASEOUT", -"E_ST_NO_XLT_HAND", -"E_ST_NO_XLT_EMOTE", +	"E_ST_OK", +	"E_ST_EOF", +	"E_ST_NO_CONSTRAINT", +	"E_ST_NO_FILE", +	"E_ST_NO_HIER", +	"E_ST_NO_JOINT", +	"E_ST_NO_NAME", +	"E_ST_NO_OFFSET", +	"E_ST_NO_CHANNELS", +	"E_ST_NO_ROTATION", +	"E_ST_NO_AXIS", +	"E_ST_NO_MOTION", +	"E_ST_NO_FRAMES", +	"E_ST_NO_FRAME_TIME", +	"E_ST_NO_POS", +	"E_ST_NO_ROT", +	"E_ST_NO_XLT_FILE", +	"E_ST_NO_XLT_HEADER", +	"E_ST_NO_XLT_NAME", +	"E_ST_NO_XLT_IGNORE", +	"E_ST_NO_XLT_RELATIVE", +	"E_ST_NO_XLT_OUTNAME", +	"E_ST_NO_XLT_MATRIX", +	"E_ST_NO_XLT_MERGECHILD", +	"E_ST_NO_XLT_MERGEPARENT", +	"E_ST_NO_XLT_PRIORITY", +	"E_ST_NO_XLT_LOOP", +	"E_ST_NO_XLT_EASEIN", +	"E_ST_NO_XLT_EASEOUT", +	"E_ST_NO_XLT_HAND", +	"E_ST_NO_XLT_EMOTE", +	"E_ST_BAD_ROOT"  }; +  //-----------------------------------------------------------------------------  // LLFloaterAnimPreview()  //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 1d177d8dba..0e9b52b0d5 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -426,8 +426,26 @@ BOOL LLPanelLandGeneral::postBuild()  	mBtnBuyLand = getChild<LLButton>("Buy Land...");  	mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND); -	mBtnScriptLimits = getChild<LLButton>("Scripts..."); -	mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this); +	// note: on region change this will not be re checked, should not matter on Agni as +	// 99% of the time all regions will return the same caps. In case of an erroneous setting +	// to enabled the floater will just throw an error when trying to get it's cap +	std::string url = gAgent.getRegion()->getCapability("LandResources"); +	if (!url.empty()) +	{ +		mBtnScriptLimits = getChild<LLButton>("Scripts..."); +		if(mBtnScriptLimits) +		{ +			mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this); +		} +	} +	else +	{ +		mBtnScriptLimits = getChild<LLButton>("Scripts..."); +		if(mBtnScriptLimits) +		{ +			mBtnScriptLimits->setVisible(false); +		} +	}  	mBtnBuyGroupLand = getChild<LLButton>("Buy For Group...");  	mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND); diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 8875e35821..4194416a01 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -59,10 +59,30 @@  /// LLFloaterScriptLimits  ///---------------------------------------------------------------------------- -// due to server side bugs the full summary display is not possible -// until they are fixed this define creates a simple version of the -// summary which only shows available & correct information -#define USE_SIMPLE_SUMMARY +// debug switches, won't work in release +#ifndef LL_RELEASE_FOR_DOWNLOAD + +// dump responder replies to llinfos for debugging +//#define DUMP_REPLIES_TO_LLINFOS + +#ifdef DUMP_REPLIES_TO_LLINFOS +#include "llsdserialize.h" +#include "llwindow.h" +#endif + +// use fake LLSD responses to check the viewer side is working correctly +// I'm syncing this with the server side efforts so hopfully we can keep +// the to-ing and fro-ing between the two teams to a minimum +//#define USE_FAKE_RESPONSES + +#ifdef USE_FAKE_RESPONSES +const S32 FAKE_NUMBER_OF_URLS = 329; +const S32 FAKE_AVAILABLE_URLS = 731; +const S32 FAKE_AMOUNT_OF_MEMORY = 66741; +const S32 FAKE_AVAILABLE_MEMORY = 895577; +#endif + +#endif  const S32 SIZE_OF_ONE_KB = 1024; @@ -87,32 +107,41 @@ BOOL LLFloaterScriptLimits::postBuild()  	}  	mTab = getChild<LLTabContainer>("scriptlimits_panels"); +	 +	if(!mTab) +	{ +		llinfos << "Error! couldn't get scriptlimits_panels, aborting Script Information setup" << llendl; +		return FALSE; +	}  	// contruct the panels -	LLPanelScriptLimitsRegionMemory* panel_memory; -	panel_memory = new LLPanelScriptLimitsRegionMemory; -	mInfoPanels.push_back(panel_memory); +	std::string land_url = gAgent.getRegion()->getCapability("LandResources"); +	if (!land_url.empty()) +	{ +		LLPanelScriptLimitsRegionMemory* panel_memory; +		panel_memory = new LLPanelScriptLimitsRegionMemory; +		mInfoPanels.push_back(panel_memory); +		LLUICtrlFactory::getInstance()->buildPanel(panel_memory, "panel_script_limits_region_memory.xml"); +		mTab->addTabPanel(panel_memory); +	} -	LLUICtrlFactory::getInstance()->buildPanel(panel_memory, "panel_script_limits_region_memory.xml"); -	mTab->addTabPanel(panel_memory); - -	LLPanelScriptLimitsRegionURLs* panel_urls = new LLPanelScriptLimitsRegionURLs; -	mInfoPanels.push_back(panel_urls); -	LLUICtrlFactory::getInstance()->buildPanel(panel_urls, "panel_script_limits_region_urls.xml"); -	mTab->addTabPanel(panel_urls); - -	LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; -	mInfoPanels.push_back(panel_attachments); -	LLUICtrlFactory::getInstance()->buildPanel(panel_attachments, "panel_script_limits_my_avatar.xml"); -	mTab->addTabPanel(panel_attachments); - -	if(selectParcelPanel) +	std::string attachment_url = gAgent.getRegion()->getCapability("AttachmentResources"); +	if (!attachment_url.empty()) +	{ +		LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; +		mInfoPanels.push_back(panel_attachments); +		LLUICtrlFactory::getInstance()->buildPanel(panel_attachments, "panel_script_limits_my_avatar.xml"); +		mTab->addTabPanel(panel_attachments); +	} +	 +	if(mInfoPanels.size() > 0)  	{  		mTab->selectTab(0);  	} -	else + +	if(!selectParcelPanel && (mInfoPanels.size() > 1))  	{ -		mTab->selectTab(2); +		mTab->selectTab(1);  	}  	return TRUE; @@ -160,6 +189,20 @@ void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr)  void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)  { +	//we don't need to test with a fake respose here (shouldn't anyway) + +#ifdef DUMP_REPLIES_TO_LLINFOS + +	LLSDNotationStreamer notation_streamer(content); +	std::ostringstream nice_llsd; +	nice_llsd << notation_streamer; + +	OSMessageBox(nice_llsd.str(), "main cap response:", 0); + +	llinfos << "main cap response:" << content << llendl; + +#endif +  	// at this point we have an llsd which should contain ether one or two urls to the services we want.  	// first we look for the details service:  	if(content.has("ScriptResourceDetails")) @@ -173,24 +216,6 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)  		{  			llinfos << "Failed to get llfloaterscriptlimits instance" << llendl;  		} -		else -		{ - -// temp - only show info if we get details - there's nothing to show if not until the sim gets fixed -#ifdef USE_SIMPLE_SUMMARY - -			LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -			std::string msg = LLTrans::getString("ScriptLimitsRequestDontOwnParcel"); -			panel_memory->childSetValue("loading_text", LLSD(msg)); -			LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); -			panel_urls->childSetValue("loading_text", LLSD(msg)); -			 -			// intentional early out as we dont want the resource summary if we are using the "simple summary" -			// and the details are missing -			return; -#endif -		}  	}  	// then the summary service: @@ -205,8 +230,61 @@ void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string&  	llinfos << "Error from responder " << reason << llendl;  } -void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content) +void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)  { +#ifdef USE_FAKE_RESPONSES + +	LLSD fake_content; +	LLSD summary = LLSD::emptyMap(); +	LLSD available = LLSD::emptyArray(); +	LLSD available_urls = LLSD::emptyMap(); +	LLSD available_memory = LLSD::emptyMap(); +	LLSD used = LLSD::emptyArray(); +	LLSD used_urls = LLSD::emptyMap(); +	LLSD used_memory = LLSD::emptyMap(); + +	used_urls["type"] = "urls"; +	used_urls["amount"] = FAKE_NUMBER_OF_URLS; +	available_urls["type"] = "urls"; +	available_urls["amount"] = FAKE_AVAILABLE_URLS; +	used_memory["type"] = "memory"; +	used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY; +	available_memory["type"] = "memory"; +	available_memory["amount"] = FAKE_AVAILABLE_MEMORY; + +//summary response:{'summary':{'available':[{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'},{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'}],'used':[{'amount':i329,'type':'urls'},{'amount':i66741,'type':'memory'}]}} + +	used.append(used_urls); +	used.append(used_memory); +	available.append(available_urls); +	available.append(available_memory); + +	summary["available"] = available; +	summary["used"] = used; +	 +	fake_content["summary"] = summary; + +	const LLSD& content = fake_content; + +#else + +	const LLSD& content = content_ref; + +#endif + + +#ifdef DUMP_REPLIES_TO_LLINFOS + +	LLSDNotationStreamer notation_streamer(content); +	std::ostringstream nice_llsd; +	nice_llsd << notation_streamer; + +	OSMessageBox(nice_llsd.str(), "summary response:", 0); + +	llinfos << "summary response:" << *content << llendl; + +#endif +  	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");  	if(!instance)  	{ @@ -217,8 +295,6 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content)  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");  		LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");  		panel_memory->setRegionSummary(content); -		LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); -		panel_urls->setRegionSummary(content);  	}  } @@ -227,8 +303,82 @@ void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::strin  	llinfos << "Error from responder " << reason << llendl;  } -void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content) +void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref)  { +#ifdef USE_FAKE_RESPONSES +/* +Updated detail service, ** denotes field added: + +result (map) ++-parcels (array of maps) +  +-id (uuid) +  +-local_id (S32)** +  +-name (string) +  +-owner_id (uuid) (in ERS as owner, but owner_id in code) +  +-objects (array of maps) +    +-id (uuid) +    +-name (string) +	+-owner_id (uuid) (in ERS as owner, in code as owner_id) +	+-owner_name (sting)** +	+-location (map)** +	  +-x (float) +	  +-y (float) +	  +-z (float) +    +-resources (map) (this is wrong in the ERS but right in code) +      +-type (string) +      +-amount (int) +*/ +	LLSD fake_content; +	LLSD resource = LLSD::emptyMap(); +	LLSD location = LLSD::emptyMap(); +	LLSD object = LLSD::emptyMap(); +	LLSD objects = LLSD::emptyArray(); +	LLSD parcel = LLSD::emptyMap(); +	LLSD parcels = LLSD::emptyArray(); + +	resource["urls"] = FAKE_NUMBER_OF_URLS; +	resource["memory"] = FAKE_AMOUNT_OF_MEMORY; +	 +	location["x"] = 128.0f; +	location["y"] = 128.0f; +	location["z"] = 0.0f; +	 +	object["id"] = LLUUID("d574a375-0c6c-fe3d-5733-da669465afc7"); +	object["name"] = "Gabs fake Object!"; +	object["owner_id"] = LLUUID("8dbf2d41-69a0-4e5e-9787-0c9d297bc570"); +	object["owner_name"] = "Gabs Linden"; +	object["location"] = location; +	object["resources"] = resource; + +	objects.append(object); + +	parcel["id"] = LLUUID("da05fb28-0d20-e593-2728-bddb42dd0160"); +	parcel["local_id"] = 42; +	parcel["name"] = "Gabriel Linden\'s Sub Plot"; +	parcel["objects"] = objects; +	parcels.append(parcel); + +	fake_content["parcels"] = parcels; +	const LLSD& content = fake_content; + +#else + +	const LLSD& content = content_ref; + +#endif + +#ifdef DUMP_REPLIES_TO_LLINFOS + +	LLSDNotationStreamer notation_streamer(content); +	std::ostringstream nice_llsd; +	nice_llsd << notation_streamer; + +	OSMessageBox(nice_llsd.str(), "details response:", 0); + +	llinfos << "details response:" << content << llendl; + +#endif +  	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");  	if(!instance) @@ -238,11 +388,22 @@ void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content)  	else  	{  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		panel_memory->setRegionDetails(content); -		 -		LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); -		panel_urls->setRegionDetails(content); +		if(tab) +		{ +			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); +			if(panel_memory) +			{ +				panel_memory->setRegionDetails(content); +			} +			else +			{ +				llinfos << "Failed to get scriptlimits memory panel" << llendl; +			} +		} +		else +		{ +			llinfos << "Failed to get scriptlimits_panels" << llendl; +		}  	}  } @@ -251,8 +412,61 @@ void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::strin  	llinfos << "Error from responder " << reason << llendl;  } -void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content) +void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)  { + +#ifdef USE_FAKE_RESPONSES + +	// just add the summary, as that's all I'm testing currently! +	LLSD fake_content = LLSD::emptyMap(); +	LLSD summary = LLSD::emptyMap(); +	LLSD available = LLSD::emptyArray(); +	LLSD available_urls = LLSD::emptyMap(); +	LLSD available_memory = LLSD::emptyMap(); +	LLSD used = LLSD::emptyArray(); +	LLSD used_urls = LLSD::emptyMap(); +	LLSD used_memory = LLSD::emptyMap(); + +	used_urls["type"] = "urls"; +	used_urls["amount"] = FAKE_NUMBER_OF_URLS; +	available_urls["type"] = "urls"; +	available_urls["amount"] = FAKE_AVAILABLE_URLS; +	used_memory["type"] = "memory"; +	used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY; +	available_memory["type"] = "memory"; +	available_memory["amount"] = FAKE_AVAILABLE_MEMORY; + +	used.append(used_urls); +	used.append(used_memory); +	available.append(available_urls); +	available.append(available_memory); + +	summary["available"] = available; +	summary["used"] = used; +	 +	fake_content["summary"] = summary; +	fake_content["attachments"] = content_ref["attachments"]; + +	const LLSD& content = fake_content; + +#else + +	const LLSD& content = content_ref; + +#endif + +#ifdef DUMP_REPLIES_TO_LLINFOS + +	LLSDNotationStreamer notation_streamer(content); +	std::ostringstream nice_llsd; +	nice_llsd << notation_streamer; + +	OSMessageBox(nice_llsd.str(), "attachment response:", 0); +	 +	llinfos << "attachment response:" << content << llendl; + +#endif +  	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");  	if(!instance) @@ -262,8 +476,22 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content)  	else  	{  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel"); -		panel->setAttachmentDetails(content); +		if(tab) +		{ +			LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel"); +			if(panel) +			{ +				panel->setAttachmentDetails(content); +			} +			else +			{ +				llinfos << "Failed to get script_limits_my_avatar_panel" << llendl; +			} +		} +		else +		{ +			llinfos << "Failed to get scriptlimits_panels" << llendl; +		}  	}  } @@ -309,7 +537,7 @@ void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parc  	{  		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");  		childSetValue("loading_text", LLSD(msg_waiting)); -	}	 +	}  }  void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id) @@ -341,6 +569,11 @@ void LLPanelScriptLimitsRegionMemory::onNameCache(  	std::string name = first_name + " " + last_name;  	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");	 +	if(!list) +	{ +		return; +	} +	  	std::vector<LLSD>::iterator id_itor;  	for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)  	{ @@ -351,33 +584,8 @@ void LLPanelScriptLimitsRegionMemory::onNameCache(  			if(item)  			{ -				item->getColumn(2)->setValue(LLSD(name)); -				element["columns"][2]["value"] = name; -			} -		} -	} - -	// fill in the url's tab if needed, all urls must have memory so we can do it all here -	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); -	if(instance) -	{ -		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - -		LLScrollListCtrl *list = panel->getChild<LLScrollListCtrl>("scripts_list");	 -		std::vector<LLSD>::iterator id_itor; -		for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) -		{ -			LLSD element = *id_itor; -			if(element["owner_id"].asUUID() == id) -			{ -				LLScrollListItem* item = list->getItem(element["id"].asUUID()); - -				if(item) -				{ -					item->getColumn(2)->setValue(LLSD(name)); -					element["columns"][2]["value"] = name; -				} +				item->getColumn(3)->setValue(LLSD(name)); +				element["columns"][3]["value"] = name;  			}  		}  	} @@ -386,6 +594,12 @@ void LLPanelScriptLimitsRegionMemory::onNameCache(  void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)  {  	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); +	 +	if(!list) +	{ +		llinfos << "Error getting the scripts_list control" << llendl; +		return; +	}  	S32 number_parcels = content["parcels"].size(); @@ -394,130 +608,197 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)  	std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels);  	childSetValue("parcels_listed", LLSD(msg_parcels)); -	S32 total_objects = 0; -	S32 total_size = 0; -  	std::vector<LLUUID> names_requested; +	// This makes the assumption that all objects will have the same set +	// of attributes, ie they will all have, or none will have locations +	// This is a pretty safe assumption as it's reliant on server version. +	bool has_locations = false; +	bool has_local_ids = false; +  	for(S32 i = 0; i < number_parcels; i++)  	{  		std::string parcel_name = content["parcels"][i]["name"].asString();  		LLUUID parcel_id = content["parcels"][i]["id"].asUUID();  		S32 number_objects = content["parcels"][i]["objects"].size(); + +		S32 local_id = 0; +		if(content["parcels"][i].has("local_id")) +		{ +			// if any locations are found flag that we can use them and turn on the highlight button +			has_local_ids = true; +			local_id = content["parcels"][i]["local_id"].asInteger(); +		} +  		for(S32 j = 0; j < number_objects; j++)  		{  			S32 size = content["parcels"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; -			total_size += size; +			 +			S32 urls = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger();  			std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString();  			LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID();  			LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); -			 + +			F32 location_x = 0.0f; +			F32 location_y = 0.0f; +			F32 location_z = 0.0f; + +			if(content["parcels"][i]["objects"][j].has("location")) +			{ +				// if any locations are found flag that we can use them and turn on the highlight button +				LLVector3 vec = ll_vector3_from_sd(content["parcels"][i]["objects"][j]["location"]); +				has_locations = true; +				location_x = vec.mV[0]; +				location_y = vec.mV[1]; +				location_z = vec.mV[2]; +			} +  			std::string owner_buf; -			 -			BOOL name_is_cached = gCacheName->getFullName(owner_id, owner_buf); -			if(!name_is_cached) + +			// in the future the server will give us owner names, so see if we're there yet: +			if(content["parcels"][i]["objects"][j].has("owner_name")) +			{ +				owner_buf = content["parcels"][i]["objects"][j]["owner_name"].asString(); +			} +			// ...and if not use the slightly more painful method of disovery: +			else  			{ -				if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) +				BOOL name_is_cached = gCacheName->getFullName(owner_id, owner_buf); +				if(!name_is_cached)  				{ -					names_requested.push_back(owner_id); -					gCacheName->get(owner_id, TRUE, -					boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, -						this, _1, _2, _3)); +					if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) +					{ +						names_requested.push_back(owner_id); +						gCacheName->get(owner_id, TRUE, +						boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, +							this, _1, _2, _3)); +					}  				}  			}  			LLSD element;  			element["id"] = task_id; -			element["owner_id"] = owner_id;  			element["columns"][0]["column"] = "size";  			element["columns"][0]["value"] = llformat("%d", size);  			element["columns"][0]["font"] = "SANSSERIF"; -			element["columns"][1]["column"] = "name"; -			element["columns"][1]["value"] = name_buf; +			element["columns"][1]["column"] = "urls"; +			element["columns"][1]["value"] = llformat("%d", urls);  			element["columns"][1]["font"] = "SANSSERIF"; -			element["columns"][2]["column"] = "owner"; -			element["columns"][2]["value"] = owner_buf; +			element["columns"][2]["column"] = "name"; +			element["columns"][2]["value"] = name_buf;  			element["columns"][2]["font"] = "SANSSERIF"; -			element["columns"][3]["column"] = "location"; -			element["columns"][3]["value"] = parcel_name; +			element["columns"][3]["column"] = "owner"; +			element["columns"][3]["value"] = owner_buf;  			element["columns"][3]["font"] = "SANSSERIF"; +			element["columns"][4]["column"] = "parcel"; +			element["columns"][4]["value"] = parcel_name; +			element["columns"][4]["font"] = "SANSSERIF"; +			element["columns"][5]["column"] = "location"; +			if(has_locations) +			{ +				element["columns"][5]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); +			} +			else +			{ +				element["columns"][5]["value"] = ""; +			} +			element["columns"][5]["font"] = "SANSSERIF";  			list->addElement(element, ADD_SORTED); +			 +			element["owner_id"] = owner_id; +			element["local_id"] = local_id;  			mObjectListItems.push_back(element); -			total_objects++;  		}  	} -	mParcelMemoryUsed =total_size; -	mGotParcelMemoryUsed = TRUE; -	populateParcelMemoryText(); -} +	if (has_locations) +	{ +		LLButton* btn = getChild<LLButton>("highlight_btn"); +		if(btn) +		{ +			btn->setVisible(true); +		} +	} -void LLPanelScriptLimitsRegionMemory::populateParcelMemoryText() -{ -	if(mGotParcelMemoryUsed && mGotParcelMemoryMax) +	if (has_local_ids)  	{ -#ifdef USE_SIMPLE_SUMMARY -		LLStringUtil::format_map_t args_parcel_memory; -		args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); -		std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsedSimple", args_parcel_memory); -		childSetValue("memory_used", LLSD(msg_parcel_memory)); -#else -		S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; +		LLButton* btn = getChild<LLButton>("return_btn"); +		if(btn) +		{ +			btn->setVisible(true); +		} +	} -		LLStringUtil::format_map_t args_parcel_memory; -		args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); -		args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); -		args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); -		std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory); -		childSetValue("memory_used", LLSD(msg_parcel_memory)); -#endif +	// save the structure to make object return easier +	mContent = content; -		childSetValue("loading_text", LLSD(std::string(""))); -	} +	childSetValue("loading_text", LLSD(std::string("")));  }  void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content)  { -	if(content["summary"]["available"][0]["type"].asString() == std::string("memory")) +	if(content["summary"]["used"][0]["type"].asString() == std::string("memory"))  	{ -		mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger(); -		mGotParcelMemoryMax = TRUE; +		mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mGotParcelMemoryUsed = TRUE;  	} -	else if(content["summary"]["available"][1]["type"].asString() == std::string("memory")) +	else if(content["summary"]["used"][1]["type"].asString() == std::string("memory"))  	{ -		mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger(); -		mGotParcelMemoryMax = TRUE; +		mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mGotParcelMemoryUsed = TRUE;  	}  	else  	{  		llinfos << "summary doesn't contain memory info" << llendl;  		return;  	} -/* -	currently this is broken on the server, so we get this value from the details section -	and update via populateParcelMemoryText() when both sets of information have been returned - -	when the sim is fixed this should be used instead: -	if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) +	 +	if(content["summary"]["used"][0]["type"].asString() == std::string("urls"))  	{ -		mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger(); -		mGotParcelMemoryUsed = TRUE; +		mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); +		mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger(); +		mGotParcelURLsUsed = TRUE;  	} -	else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) +	else if(content["summary"]["used"][1]["type"].asString() == std::string("urls"))  	{ -		mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger(); -		mGotParcelMemoryUsed = TRUE; +		mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); +		mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger(); +		mGotParcelURLsUsed = TRUE;  	}  	else  	{ -		//ERROR!!! +		llinfos << "summary doesn't contain urls info" << llendl;  		return; -	}*/ +	} -	populateParcelMemoryText(); +	if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0)) +	{ +		S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; + +		LLStringUtil::format_map_t args_parcel_memory; +		args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); +		args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); +		args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); +		std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory); +		childSetValue("memory_used", LLSD(msg_parcel_memory)); +	} + +	if((mParcelURLsUsed >= 0) && (mParcelURLsMax >= 0)) +	{ +		S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed; + +		LLStringUtil::format_map_t args_parcel_urls; +		args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); +		args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax); +		args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available); +		std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls); +		childSetValue("urls_used", LLSD(msg_parcel_urls)); +	}  }  BOOL LLPanelScriptLimitsRegionMemory::postBuild() @@ -530,6 +811,10 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild()  	childSetValue("loading_text", LLSD(msg_waiting));  	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); +	if(!list) +	{ +		return FALSE; +	}  	//set all columns to resizable mode even if some columns will be empty  	for(S32 column = 0; column < list->getNumColumns(); column++) @@ -548,18 +833,11 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain()  	LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");  	if(!instance)  	{ -		//this isnt really an error... -//		llinfos << "Failed to get about land instance" << llendl; -//		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError");  		childSetValue("loading_text", LLSD(std::string("")));  		//might have to do parent post build here  		//if not logic below could use early outs  		return FALSE;  	} - -	LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -	LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); -  	LLParcel* parcel = instance->getCurrentSelectedParcel();  	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); @@ -575,7 +853,6 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain()  		{  			std::string msg_wrong_region = LLTrans::getString("ScriptLimitsRequestWrongRegion");  			childSetValue("loading_text", LLSD(msg_wrong_region)); -			panel_urls->childSetValue("loading_text", LLSD(msg_wrong_region));  			return FALSE;  		} @@ -605,14 +882,12 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain()  			std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError");  			childSetValue("loading_text", LLSD(msg_waiting)); -			panel_urls->childSetValue("loading_text", LLSD(msg_waiting));  		}  	}  	else  	{ -		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); +		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestNoParcelSelected");  		childSetValue("loading_text", LLSD(msg_waiting)); -		panel_urls->childSetValue("loading_text", LLSD(msg_waiting));  	}  	return LLPanelScriptLimitsInfo::postBuild(); @@ -629,10 +904,13 @@ void LLPanelScriptLimitsRegionMemory::clearList()  	mGotParcelMemoryUsed = FALSE;  	mGotParcelMemoryMax = FALSE; +	mGotParcelURLsUsed = FALSE; +	mGotParcelURLsMax = FALSE;  	LLStringUtil::format_map_t args_parcel_memory;  	std::string msg_empty_string("");  	childSetValue("memory_used", LLSD(msg_empty_string)); +	childSetValue("urls_used", LLSD(msg_empty_string));  	childSetValue("parcels_listed", LLSD(msg_empty_string));  	mObjectListItems.clear(); @@ -647,13 +925,16 @@ void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata)  	if(instance)  	{  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		panel_memory->clearList(); - -		LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); -		panel_urls->clearList(); +		if(tab) +		{ +			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); +			if(panel_memory) +			{ +				panel_memory->clearList(); -		panel_memory->StartRequestChain(); +				panel_memory->StartRequestChain(); +			} +		}  		return;  	}  	else @@ -665,78 +946,80 @@ void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata)  void LLPanelScriptLimitsRegionMemory::showBeacon()  {	 -/*	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); +	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list");  	if (!list) return;  	LLScrollListItem* first_selected = list->getFirstSelected();  	if (!first_selected) return; -	std::string name = first_selected->getColumn(1)->getValue().asString(); -	std::string pos_string =  first_selected->getColumn(3)->getValue().asString(); +	std::string name = first_selected->getColumn(2)->getValue().asString(); +	std::string pos_string =  first_selected->getColumn(5)->getValue().asString(); -	llinfos << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" <<llendl; -	llinfos << "name = " << name << " pos = " << pos_string << llendl; -  	F32 x, y, z;  	S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);  	if (matched != 3) return;  	LLVector3 pos_agent(x, y, z);  	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); -	llinfos << "name = " << name << " pos = " << pos_string << llendl; +  	std::string tooltip(""); -	LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);*/ +	LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);  }  // static  void LLPanelScriptLimitsRegionMemory::onClickHighlight(void* userdata)  { -/*	llinfos << "LLPanelRegionGeneralInfo::onClickHighlight" << llendl; +	llinfos << "LLPanelRegionGeneralInfo::onClickHighlight" << llendl;  	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");  	if(instance)  	{  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		panel->showBeacon(); +		if(tab) +		{ +			LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); +			if(panel) +			{ +				panel->showBeacon(); +			} +		}  		return;  	}  	else  	{  		llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -//		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -//		panel->childSetValue("loading_text", LLSD(msg_waiting));  		return; -	}*/ +	}  } -void LLPanelScriptLimitsRegionMemory::returnObjects() +void LLPanelScriptLimitsRegionMemory::returnObjectsFromParcel(S32 local_id)  { -/*	llinfos << "started" << llendl;  	LLMessageSystem *msg = gMessageSystem;  	LLViewerRegion* region = gAgent.getRegion();  	if (!region) return; -	llinfos << "got region" << llendl;  	LLCtrlListInterface *list = childGetListInterface("scripts_list");  	if (!list || list->getItemCount() == 0) return; -	llinfos << "got list" << llendl; -	std::vector<LLUUID>::iterator id_itor; +	std::vector<LLSD>::iterator id_itor;  	bool start_message = true; -	for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor) +	for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)  	{ -		LLUUID task_id = *id_itor; -		llinfos << task_id << llendl; -		if (!list->isSelected(task_id)) +		LLSD element = *id_itor; +		if (!list->isSelected(element["id"].asUUID()))  		{ -			llinfos << "not selected" << llendl;  			// Selected only  			continue;  		} -		llinfos << "selected" << llendl; +		 +		if(element["local_id"].asInteger() != local_id) +		{ +			// Not the parcel we are looking for +			continue; +		} +  		if (start_message)  		{  			msg->newMessageFast(_PREHASH_ParcelReturnObjects); @@ -744,285 +1027,74 @@ void LLPanelScriptLimitsRegionMemory::returnObjects()  			msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());  			msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());  			msg->nextBlockFast(_PREHASH_ParcelData); -			msg->addS32Fast(_PREHASH_LocalID, -1); // Whole region -			msg->addS32Fast(_PREHASH_ReturnType, RT_LIST); +			msg->addS32Fast(_PREHASH_LocalID, element["local_id"].asInteger()); +			msg->addU32Fast(_PREHASH_ReturnType, RT_LIST);  			start_message = false; -			llinfos << "start message" << llendl;  		}  		msg->nextBlockFast(_PREHASH_TaskIDs); -		msg->addUUIDFast(_PREHASH_TaskID, task_id); -		llinfos << "added id" << llendl; +		msg->addUUIDFast(_PREHASH_TaskID, element["id"].asUUID());  		if (msg->isSendFullFast(_PREHASH_TaskIDs))  		{  			msg->sendReliable(region->getHost());  			start_message = true; -			llinfos << "sent 1" << llendl;  		}  	}  	if (!start_message)  	{  		msg->sendReliable(region->getHost()); -		llinfos << "sent 2" << llendl; -	}*/ +	}  } -// static -void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata) +void LLPanelScriptLimitsRegionMemory::returnObjects()  { -/*	llinfos << "LLPanelRegionGeneralInfo::onClickReturn" << llendl; -	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); -	if(instance) +	if(!mContent.has("parcels"))  	{ -		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		panel->returnObjects();  		return;  	} -	else -	{ -		llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -//		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -//		panel->childSetValue("loading_text", LLSD(msg_waiting)); -		return; -	}*/ -} - -///---------------------------------------------------------------------------- -// URLs Panel -///---------------------------------------------------------------------------- - -void LLPanelScriptLimitsRegionURLs::setRegionDetails(LLSD content) -{ -	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); - -	S32 number_parcels = content["parcels"].size(); - -	LLStringUtil::format_map_t args_parcels; -	args_parcels["[PARCELS]"] = llformat ("%d", number_parcels); -	std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels); -	childSetValue("parcels_listed", LLSD(msg_parcels)); - -	S32 total_objects = 0; -	S32 total_size = 0; +	S32 number_parcels = mContent["parcels"].size(); + +	// a message per parcel containing all objects to be returned from that parcel  	for(S32 i = 0; i < number_parcels; i++)  	{ -		std::string parcel_name = content["parcels"][i]["name"].asString(); -		llinfos << parcel_name << llendl; - -		S32 number_objects = content["parcels"][i]["objects"].size(); -		for(S32 j = 0; j < number_objects; j++) +		S32 local_id = 0; +		if(mContent["parcels"][i].has("local_id"))  		{ -			if(content["parcels"][i]["objects"][j]["resources"].has("urls")) -			{ -				S32 size = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger(); -				total_size += size; -				 -				std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString(); -				LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID(); -				LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); - -				std::string owner_buf; -				gCacheName->getFullName(owner_id, owner_buf); //dont care if this fails as the memory tab will request and fill the field - -				LLSD element; - -				element["id"] = task_id; -				element["columns"][0]["column"] = "urls"; -				element["columns"][0]["value"] = llformat("%d", size); -				element["columns"][0]["font"] = "SANSSERIF"; -				element["columns"][1]["column"] = "name"; -				element["columns"][1]["value"] = name_buf; -				element["columns"][1]["font"] = "SANSSERIF"; -				element["columns"][2]["column"] = "owner"; -				element["columns"][2]["value"] = owner_buf; -				element["columns"][2]["font"] = "SANSSERIF"; -				element["columns"][3]["column"] = "location"; -				element["columns"][3]["value"] = parcel_name; -				element["columns"][3]["font"] = "SANSSERIF"; - -				list->addElement(element); -				mObjectListItems.push_back(element); -				total_objects++; -			} +			local_id = mContent["parcels"][i]["local_id"].asInteger(); +			returnObjectsFromParcel(local_id);  		}  	} -	 -	mParcelURLsUsed =total_size; -	mGotParcelURLsUsed = TRUE; -	populateParcelURLsText(); -} - -void LLPanelScriptLimitsRegionURLs::populateParcelURLsText() -{ -	if(mGotParcelURLsUsed && mGotParcelURLsMax) -	{ - -#ifdef USE_SIMPLE_SUMMARY -		LLStringUtil::format_map_t args_parcel_urls; -		args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); -		std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsedSimple", args_parcel_urls); -		childSetValue("urls_used", LLSD(msg_parcel_urls)); -#else -		S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed; -		LLStringUtil::format_map_t args_parcel_urls; -		args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); -		args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax); -		args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available); -		std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls); -		childSetValue("urls_used", LLSD(msg_parcel_urls)); -#endif - -		childSetValue("loading_text", LLSD(std::string(""))); - -	} +	onClickRefresh(NULL);  } -void LLPanelScriptLimitsRegionURLs::setRegionSummary(LLSD content) -{ -	if(content["summary"]["available"][0]["type"].asString() == std::string("urls")) -	{ -		mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger(); -		mGotParcelURLsMax = TRUE; -	} -	else if(content["summary"]["available"][1]["type"].asString() == std::string("urls")) -	{ -		mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger(); -		mGotParcelURLsMax = TRUE; -	} -	else -	{ -		llinfos << "summary contains no url info" << llendl; -		return; -	} -/* -	currently this is broken on the server, so we get this value from the details section -	and update via populateParcelMemoryText() when both sets of information have been returned - -	when the sim is fixed this should be used instead: -	if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) -	{ -		mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); -		mGotParcelURLsUsed = TRUE; -	} -	else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) -	{ -		mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); -		mGotParcelURLsUsed = TRUE; -	} -	else -	{ -		//ERROR!!! -		return; -	}*/ - -	populateParcelURLsText(); -} - -BOOL LLPanelScriptLimitsRegionURLs::postBuild() -{ -	childSetAction("refresh_list_btn", onClickRefresh, this); -	childSetAction("highlight_btn", onClickHighlight, this); -	childSetAction("return_btn", onClickReturn, this); -		 -	std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); -	childSetValue("loading_text", LLSD(msg_waiting)); -	return FALSE; -} - -void LLPanelScriptLimitsRegionURLs::clearList() -{ -	LLCtrlListInterface *list = childGetListInterface("scripts_list"); - -	if (list) -	{ -		list->operateOnAll(LLCtrlListInterface::OP_DELETE); -	} - -	mGotParcelURLsUsed = FALSE; -	mGotParcelURLsMax = FALSE; -	 -	LLStringUtil::format_map_t args_parcel_urls; -	std::string msg_empty_string(""); -	childSetValue("urls_used", LLSD(msg_empty_string)); -	childSetValue("parcels_listed", LLSD(msg_empty_string)); - -	mObjectListItems.clear(); -} - -// static -void LLPanelScriptLimitsRegionURLs::onClickRefresh(void* userdata) -{ -	llinfos << "Refresh clicked" << llendl; -	 -	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); -	if(instance) -	{ -		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		// use the memory panel to re-request all the info -		panel_memory->clearList(); - -		LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); -		// but the urls panel to clear itself -		panel_urls->clearList(); - -		panel_memory->StartRequestChain(); -		return; -	} -	else -	{ -		llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << llendl; -		return; -	} -}  // static -void LLPanelScriptLimitsRegionURLs::onClickHighlight(void* userdata) +void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata)  { -/*	llinfos << "Highlight clicked" << llendl; +	llinfos << "LLPanelRegionGeneralInfo::onClickReturn" << llendl;  	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");  	if(instance)  	{  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		// use the beacon function from the memory panel -		panel->showBeacon(); +		if(tab) +		{ +			LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); +			if(panel) +			{ +				panel->returnObjects(); +			} +		}  		return;  	}  	else  	{  		llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -//		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -//		panel->childSetValue("loading_text", LLSD(msg_waiting)); -		return; -	}*/ -} - -// static -void LLPanelScriptLimitsRegionURLs::onClickReturn(void* userdata) -{ -/*	llinfos << "Return clicked" << llendl; -	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); -	if(instance) -	{ -		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); -		LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); -		// use the return function from the memory panel -		panel->returnObjects();  		return;  	} -	else -	{ -		llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -//		std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -//		panel->childSetValue("loading_text", LLSD(msg_waiting)); -		return; -	}*/  }  ///---------------------------------------------------------------------------- @@ -1047,6 +1119,12 @@ BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()  void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content)  {  	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); +	 +	if(!list) +	{ +		return; +	} +	  	S32 number_attachments = content["attachments"].size();  	for(int i = 0; i < number_attachments; i++) @@ -1096,6 +1174,8 @@ void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content)  			list->addElement(element);  		}  	} +	 +	setAttachmentSummary(content);  	childSetValue("loading_text", LLSD(std::string("")));  } @@ -1122,6 +1202,69 @@ void LLPanelScriptLimitsAttachment::clearList()  	childSetValue("loading_text", LLSD(msg_waiting));  } +void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content) +{ +	if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) +	{ +		mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mGotAttachmentMemoryUsed = TRUE; +	} +	else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) +	{ +		mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; +		mGotAttachmentMemoryUsed = TRUE; +	} +	else +	{ +		llinfos << "attachment details don't contain memory summary info" << llendl; +		return; +	} +	 +	if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) +	{ +		mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); +		mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger(); +		mGotAttachmentURLsUsed = TRUE; +	} +	else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) +	{ +		mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); +		mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger(); +		mGotAttachmentURLsUsed = TRUE; +	} +	else +	{ +		llinfos << "attachment details don't contain urls summary info" << llendl; +		return; +	} + +	if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) +	{ +		S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; + +		LLStringUtil::format_map_t args_attachment_memory; +		args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); +		args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); +		args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); +		std::string msg_attachment_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_attachment_memory); +		childSetValue("memory_used", LLSD(msg_attachment_memory)); +	} + +	if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) +	{ +		S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed; + +		LLStringUtil::format_map_t args_attachment_urls; +		args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed); +		args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax); +		args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available); +		std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls); +		childSetValue("urls_used", LLSD(msg_attachment_urls)); +	} +} +  // static  void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata)  { diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index e675d14515..4c1ecc1019 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -166,10 +166,10 @@ public:  	BOOL StartRequestChain(); -	void populateParcelMemoryText();  	BOOL getLandScriptResources();  	void clearList();  	void showBeacon(); +	void returnObjectsFromParcel(S32 local_id);  	void returnObjects();  private: @@ -178,69 +178,30 @@ private:  			 const std::string& first_name,  			 const std::string& last_name); +	LLSD mContent;  	LLUUID mParcelId;  	BOOL mGotParcelMemoryUsed; +	BOOL mGotParcelMemoryUsedDetails;  	BOOL mGotParcelMemoryMax;  	S32 mParcelMemoryMax;  	S32 mParcelMemoryUsed; +	S32 mParcelMemoryUsedDetails; -	std::vector<LLSD> mObjectListItems; -		 -protected: - -// LLRemoteParcelInfoObserver interface: -/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); -/*virtual*/ void setParcelID(const LLUUID& parcel_id); -/*virtual*/ void setErrorStatus(U32 status, const std::string& reason); -	 -	static void onClickRefresh(void* userdata); -	static void onClickHighlight(void* userdata); -	static void onClickReturn(void* userdata); -}; - -///////////////////////////////////////////////////////////////////////////// -// URLs panel -///////////////////////////////////////////////////////////////////////////// - -class LLPanelScriptLimitsRegionURLs : public LLPanelScriptLimitsInfo -{ -	 -public: -	LLPanelScriptLimitsRegionURLs() -		: LLPanelScriptLimitsInfo(), - -		mParcelId(LLUUID()), -		mGotParcelURLsUsed(FALSE), -		mGotParcelURLsMax(FALSE), -		mParcelURLsMax(0), -		mParcelURLsUsed(0) -		{ -		}; - -	~LLPanelScriptLimitsRegionURLs() -	{ -	}; -	 -	// LLPanel -	virtual BOOL postBuild(); - -	void setRegionDetails(LLSD content); -	void setRegionSummary(LLSD content); - -	void populateParcelURLsText(); -	void clearList(); - -private: - -	LLUUID mParcelId;  	BOOL mGotParcelURLsUsed; +	BOOL mGotParcelURLsUsedDetails;  	BOOL mGotParcelURLsMax;  	S32 mParcelURLsMax;  	S32 mParcelURLsUsed; +	S32 mParcelURLsUsedDetails;  	std::vector<LLSD> mObjectListItems;  protected: + +// LLRemoteParcelInfoObserver interface: +/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); +/*virtual*/ void setParcelID(const LLUUID& parcel_id); +/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);  	static void onClickRefresh(void* userdata);  	static void onClickHighlight(void* userdata); @@ -266,11 +227,26 @@ public:  	void setAttachmentDetails(LLSD content); +	void setAttachmentSummary(LLSD content);  	BOOL requestAttachmentDetails();  	void clearList();  private: +	BOOL mGotAttachmentMemoryUsed; +	BOOL mGotAttachmentMemoryUsedDetails; +	BOOL mGotAttachmentMemoryMax; +	S32 mAttachmentMemoryMax; +	S32 mAttachmentMemoryUsed; +	S32 mAttachmentMemoryUsedDetails; +	 +	BOOL mGotAttachmentURLsUsed; +	BOOL mGotAttachmentURLsUsedDetails; +	BOOL mGotAttachmentURLsMax; +	S32 mAttachmentURLsMax; +	S32 mAttachmentURLsUsed; +	S32 mAttachmentURLsUsedDetails; +  protected:  	static void onClickRefresh(void* userdata); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index b05eb84e52..f154de39c9 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -2540,13 +2540,11 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  	{  		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); -		static const LLUUID& landmarks_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);  		LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID();  		LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID(); -		if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id) || -			(a_uuid == landmarks_folder_id && b_uuid == landmarks_folder_id)) +		if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))  		{  			// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem  			// or to LLInvFVBridge diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index b8b9fe2742..b396abf677 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -72,6 +72,8 @@ public:  static const LLGroupComparator GROUP_COMPARATOR;  LLGroupList::Params::Params() +: no_groups_msg("no_groups_msg") +, no_filtered_groups_msg("no_filtered_groups_msg")  {  } @@ -79,15 +81,14 @@ LLGroupList::Params::Params()  LLGroupList::LLGroupList(const Params& p)  :	LLFlatListView(p)  	, mDirty(true) // to force initial update +	, mNoFilteredGroupsMsg(p.no_filtered_groups_msg) +	, mNoGroupsMsg(p.no_groups_msg)  {  	// Listen for agent group changes.  	gAgent.addListener(this, "new group");  	mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");  	setCommitOnSelectionChange(true); -	// TODO: implement context menu -	// display a context menu appropriate for a list of group names -//	setContextMenu(LLScrollListCtrl::MENU_GROUP);  	// Set default sort order.  	setComparator(&GROUP_COMPARATOR); @@ -158,6 +159,18 @@ void LLGroupList::refresh()  	LLUUID				id;  	bool				have_filter		= !mNameFilter.empty(); +	// set no items message depend on filter state & total count of groups +	if (have_filter) +	{ +		// groups were filtered +		setNoItemsCommentText(mNoFilteredGroupsMsg); +	} +	else if (0 == count) +	{ +		// user is not a member of any group +		setNoItemsCommentText(mNoGroupsMsg); +	} +  	clear();  	for(S32 i = 0; i < count; ++i) @@ -173,7 +186,8 @@ void LLGroupList::refresh()  	sort();  	// Add "none" to list at top if filter not set (what's the point of filtering "none"?). -	if (!have_filter) +	// but only if some real groups exists. EXT-4838 +	if (!have_filter && count > 0)  	{  		std::string loc_none = LLTrans::getString("GroupsNone");  		addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP); diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index f7afe0c0b2..f3ac676edd 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -53,6 +53,15 @@ class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener  public:  	struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>   	{ +		/** +		 * Contains a message for empty list when user is not a member of any group +		 */ +		Optional<std::string>	no_groups_msg; + +		/** +		 * Contains a message for empty list when all groups don't match passed filter +		 */ +		Optional<std::string>	no_filtered_groups_msg;  		Params();  	}; @@ -80,6 +89,8 @@ private:  	bool mShowIcons;  	bool mDirty;  	std::string mNameFilter; +	std::string mNoFilteredGroupsMsg; +	std::string mNoGroupsMsg;  };  class LLButton; diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 8bd0e520c3..72a52ba13b 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1714,6 +1714,8 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,  	for (std::vector<LLUUID>::iterator it = member_ids.begin();  		 it != member_ids.end(); ++it)  	{ +		LLUUID& ejected_member_id = (*it); +		  		// Can't use 'eject' to leave a group.  		if ((*it) == gAgent.getID()) continue; @@ -1734,7 +1736,7 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,  			}  			msg->nextBlock("EjectData"); -			msg->addUUID("EjecteeID",(*it)); +			msg->addUUID("EjecteeID",ejected_member_id);  			if (msg->isSendFull())  			{ @@ -1746,13 +1748,15 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,  			for (LLGroupMemberData::role_list_t::iterator rit = (*mit).second->roleBegin();  				 rit != (*mit).second->roleEnd(); ++rit)  			{ -				if ((*rit).first.notNull()) +				if ((*rit).first.notNull() && (*rit).second!=0)  				{ -					(*rit).second->removeMember(*it); +					(*rit).second->removeMember(ejected_member_id);  				}  			} -			delete (*mit).second; +			  			group_datap->mMembers.erase(*it); +			 +			delete (*mit).second;  		}  	} diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 753e0c71a6..777dd350df 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -514,7 +514,7 @@ BOOL LLIMFloater::getVisible()  	if(isChatMultiTab())  	{  		LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); -		// Tabbed IM window is "visible" when we minimize it. +		// getVisible() returns TRUE when Tabbed IM window is minimized.  		return !im_container->isMinimized() && im_container->getVisible();  	}  	else @@ -571,6 +571,12 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)  		setKey(im_session_id);  		mControlPanel->setSessionId(im_session_id);  	} + +	// updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796) +	if(gAgent.isInGroup(im_session_id)) +	{ +		mControlPanel->updateCallButton(); +	}  	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 784c2eaaf9..22eb9a51d2 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -52,6 +52,7 @@ LLIMFloaterContainer::~LLIMFloaterContainer(){}  BOOL LLIMFloaterContainer::postBuild()  { +	LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));  	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button  	// mTabContainer will be initialized in LLMultiFloater::addChild()  	return TRUE; @@ -162,6 +163,21 @@ void LLIMFloaterContainer::onCloseFloater(LLUUID id)  {  	LLAvatarPropertiesProcessor::instance().removeObserver(id, this);  	LLGroupMgr::instance().removeObserver(id, this); + +} + +void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data) +{ +	LLUUID session_id = data["from_id"].asUUID(); +	LLFloater* floaterp = get_ptr_in_map(mSessions, session_id); +	LLFloater* current_floater = LLMultiFloater::getActiveFloater(); + +	if(floaterp && current_floater && floaterp != current_floater) +	{ +		if(LLMultiFloater::isFloaterFlashing(floaterp)) +			LLMultiFloater::setFloaterFlashing(floaterp, FALSE); +		LLMultiFloater::setFloaterFlashing(floaterp, TRUE); +	}  }  LLIMFloaterContainer* LLIMFloaterContainer::findInstance() diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index e4a32dbe1d..bc06f0cbd3 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -66,10 +66,12 @@ public:  	static LLIMFloaterContainer* getInstance();  private: -	typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t; +	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;  	avatarID_panel_map_t mSessions;  	void onCloseFloater(LLUUID avatar_id); + +	void onNewMessageReceived(const LLSD& data);  };  #endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d2155d58f9..7f0eb88cb3 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1709,6 +1709,8 @@ BOOL LLOutgoingCallDialog::postBuild()  	childSetAction("Cancel", onCancel, this); +	setCanDrag(FALSE); +  	return success;  } @@ -1812,6 +1814,8 @@ BOOL LLIncomingCallDialog::postBuild()  		mLifetimeTimer.stop();  	} +	setCanDrag(FALSE); +  	return TRUE;  } @@ -2986,48 +2990,6 @@ public:  	}  }; -LLCallInfoDialog::LLCallInfoDialog(const LLSD& payload) : LLCallDialog(payload) -{ -} - -BOOL LLCallInfoDialog::postBuild() -{ -	// init notification's lifetime -	std::istringstream ss( getString("lifetime") ); -	if (!(ss >> mLifetime)) -	{ -		mLifetime = DEFAULT_LIFETIME; -	} -	return LLCallDialog::postBuild(); -} - -void LLCallInfoDialog::onOpen(const LLSD& key) -{ -	if(key.has("msg")) -	{ -		std::string msg = key["msg"]; -		getChild<LLTextBox>("msg")->setValue(msg); -	} - -	mLifetimeTimer.start(); -} - -void LLCallInfoDialog::show(const std::string& status_name, const LLSD& args) -{ -	LLUIString message = LLTrans::getString(status_name); -	message.setArgs(args); - -	LLSD payload; -	payload["msg"] = message; -	LLFloater* inst = LLFloaterReg::findInstance("call_info"); - -	// avoid recreate instance with the same message -	if (inst == NULL || message.getString() != inst->getChild<LLTextBox>("msg")->getValue()) -	{ -		LLFloaterReg::showInstance("call_info", payload); -	} -} -  LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>     gHTTPRegistrationMessageChatterboxsessionstartreply(  	   "/message/ChatterBoxSessionStartReply"); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index b573490fa3..1c7aaa3f1b 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -530,16 +530,6 @@ private:  	void hideAllText();  }; -class LLCallInfoDialog : public LLCallDialog -{ -public: -	LLCallInfoDialog(const LLSD& payload); -	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onOpen(const LLSD& key); - -	static void show(const std::string& status_name, const LLSD& args); -}; -  // Globals  extern LLIMMgr *gIMMgr; diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp index c7b8db9635..c7b651f37c 100644 --- a/indra/newview/llinspect.cpp +++ b/indra/newview/llinspect.cpp @@ -34,6 +34,7 @@  #include "llcontrol.h"	// LLCachedControl  #include "llui.h"		// LLUI::sSettingsGroups +#include "llviewermenu.h"  LLInspect::LLInspect(const LLSD& key)  :	LLFloater(key), @@ -108,3 +109,26 @@ void LLInspect::onMouseLeave(S32 x, S32 y, MASK mask)  {  	mOpenTimer.unpause();  } + +bool LLInspect::childHasVisiblePopupMenu() +{ +	// Child text-box may spawn a pop-up menu, if mouse is over the menu, Inspector  +	// will hide(which is not expected). +	// This is an attempt to find out if child control has spawned a menu. + +	LLView* child_menu = gMenuHolder->getVisibleMenu(); +	if(child_menu) +	{ +		LLRect floater_rc = calcScreenRect(); +		LLRect menu_screen_rc = child_menu->calcScreenRect(); +		S32 mx, my; +		LLUI::getMousePositionScreen(&mx, &my); + +		// This works wrong if we spawn a menu near Inspector and menu overlaps Inspector. +		if(floater_rc.overlaps(menu_screen_rc) && menu_screen_rc.pointInRect(mx, my)) +		{ +			return true; +		} +	} +	return false; +} diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h index a1cb9cd71c..f8c86618d2 100644 --- a/indra/newview/llinspect.h +++ b/indra/newview/llinspect.h @@ -56,6 +56,9 @@ public:  	/*virtual*/ void onFocusLost();  protected: + +	virtual bool childHasVisiblePopupMenu(); +  	LLFrameTimer		mCloseTimer;  	LLFrameTimer		mOpenTimer;  }; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 857abed811..1da81ae019 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -393,11 +393,18 @@ void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask)  {  	LLMenuGL* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu();  	LLMenuGL* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu(); -	if ( !(gear_menu && gear_menu->getVisible()) && -		 !(gear_menu_self && gear_menu_self->getVisible())) +	if ( gear_menu && gear_menu->getVisible() && +		 gear_menu_self && gear_menu_self->getVisible() )  	{ -		mOpenTimer.unpause(); +		return; +	} + +	if(childHasVisiblePopupMenu()) +	{ +		return;  	} + +	mOpenTimer.unpause();  }  void LLInspectAvatar::updateModeratorPanel() diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index e4ee953eae..c0b6f32cb8 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -575,10 +575,17 @@ void LLInspectObject::updateSecureBrowsing()  void LLInspectObject::onMouseLeave(S32 x, S32 y, MASK mask)  {  	LLMenuGL* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu(); -	if ( !(gear_menu && gear_menu->getVisible())) +	if ( gear_menu && gear_menu->getVisible() )  	{ -		mOpenTimer.unpause(); +		return; +	} + +	if(childHasVisiblePopupMenu()) +	{ +		return;  	} + +	mOpenTimer.unpause();  }  void LLInspectObject::onClickBuy() diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp index 892dce588f..97ff771658 100644 --- a/indra/newview/llinspectremoteobject.cpp +++ b/indra/newview/llinspectremoteobject.cpp @@ -167,7 +167,8 @@ void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& fi  void LLInspectRemoteObject::update()  {  	// show the object name as the inspector's title -	getChild<LLUICtrl>("object_name")->setValue(mName); +	// (don't hyperlink URLs in object names) +	getChild<LLUICtrl>("object_name")->setValue("<nolink>" + mName + "</nolink>");  	// show the object's owner - click it to show profile  	std::string owner = mOwner; @@ -192,7 +193,7 @@ void LLInspectRemoteObject::update()  	std::string url;  	if (! mSLurl.empty())  	{ -		std::string url = "secondlife:///app/teleport/" + mSLurl; +		url = "secondlife:///app/teleport/" + mSLurl;  	}  	getChild<LLUICtrl>("object_slurl")->setValue(url); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e8a4899a0b..f68550d8fd 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3773,6 +3773,21 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode  		gInventory.updateItem(item);  		gInventory.notifyObservers();  	} +	else if("play" == action) +	{ +		if(!LLGestureManager::instance().isGestureActive(mUUID)) +		{ +			// we need to inform server about gesture activating to be consistent with LLPreviewGesture and  LLGestureComboList. +			BOOL inform_server = TRUE; +			BOOL deactivate_similar = FALSE; +			LLGestureManager::instance().setGestureLoadedCallback(mUUID, boost::bind(&LLGestureBridge::playGesture, mUUID)); +			LLGestureManager::instance().activateGestureWithAsset(mUUID, gInventory.getItem(mUUID)->getAssetUUID(), inform_server, deactivate_similar); +		} +		else +		{ +			playGesture(mUUID); +		} +	}  	else LLItemBridge::performAction(folder, model, action);  } @@ -3858,6 +3873,20 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	hide_context_entries(menu, items, disabled_items);  } +// static +void LLGestureBridge::playGesture(const LLUUID& item_id) +{ +	if (LLGestureManager::instance().isGesturePlaying(item_id)) +	{ +		LLGestureManager::instance().stopGesture(item_id); +	} +	else +	{ +		LLGestureManager::instance().playGesture(item_id); +	} +} + +  // +=================================================+  // |        LLAnimationBridge                        |  // +=================================================+ diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index eeb8246b11..6fffec96a0 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -491,6 +491,8 @@ public:  	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +	static void playGesture(const LLUUID& item_id); +  protected:  	LLGestureBridge(LLInventoryPanel* inventory, const LLUUID& uuid)  	:	LLItemBridge(inventory, uuid) {} diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 0af584e7dc..44d1f639ee 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -142,105 +142,6 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)  	return rv;  } -/* -This namespace contains a functionality to remove LM prefixes were used to store sort order of -Favorite Landmarks in landmarks' names. -Once being in Favorites folder LM inventory Item has such prefix. -Due to another solution is implemented in EXT-3985 these prefixes should be removed. - -*NOTE: It will be unnecessary after the first successful session in viewer 2.0. -Can be removed before public release. - -Implementation details: -At the first run with this patch it patches all cached landmarks: removes LM sort prefixes and -updates them on the viewer and server sides. -Also it calls fetching agent's inventory to process not yet loaded landmarks too. -If fetching is successfully done it will store special per-agent empty file-marker -in the user temporary folder (where cached inventory is loaded) while caching agent's inventory. -After that in will not affect the viewer until cached marker is removed. -*/ -namespace LMSortPrefix -{ -	bool cleanup_done = false; -	const std::string getMarkerPath() -	{ -		std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, gAgentID.asString())); -		std::string marker_filename = llformat("%s-lm_prefix_marker", path.c_str()); - -		return marker_filename; -	} -	bool wasClean() -	{ -		static bool was_clean = false; -		static bool already_init = false; -		if (already_init) return was_clean; - -		already_init = true; -		std::string path_to_marker = getMarkerPath(); -		was_clean = LLFile::isfile(path_to_marker); - -		return was_clean; -	} - -	void setLandmarksWereCleaned() -	{ -		if (cleanup_done) -		{ -			std::string path_to_marker = getMarkerPath(); -			LLFILE* file = LLFile::fopen(path_to_marker, "w"); -			if(!file) -			{ -				llwarns << "unable to save marker that LM prefixes were removed: " << path_to_marker << llendl; -				return; -			} - -			fclose(file); -		} -	} - -	void removePrefix(LLPointer<LLViewerInventoryItem> inv_item) -	{ -		if (wasClean()) -		{ -			LL_INFOS_ONCE("") << "Inventory was cleaned for this avatar. Patch can be removed." << LL_ENDL; -			return; -		} - -		if (LLInventoryType::IT_LANDMARK != inv_item->getInventoryType()) return; - -		std::string old_name = inv_item->getName(); - -		S32 sort_field = -1; -		std::string display_name; -		BOOL exists = LLViewerInventoryItem::extractSortFieldAndDisplayName(old_name, &sort_field, &display_name); -		if (exists && sort_field != -1) -		{ -			llinfos << "Removing Landmark sort field and separator for: " << old_name << " | " << inv_item->getUUID() << llendl; -			LLUUID parent_uuid = inv_item->getParentUUID(); -			if (gInventory.getCategory(parent_uuid)) -			{ -				llinfos << "parent folder is: " << gInventory.getCategory(parent_uuid)->getName() << llendl; -			} - - -			// mark item completed to avoid error while copying and updating server -			inv_item->setComplete(TRUE); -			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item.get()); -			new_item->rename(display_name); -			gInventory.updateItem(new_item); -			new_item->updateServer(FALSE); - -			gInventory.notifyObservers(); -		} -	} - -	void completeCleanup() -	{ -		// background fetch is completed. can save marker -		cleanup_done = true; -	} -} -  ///----------------------------------------------------------------------------  /// Class LLInventoryModel  ///---------------------------------------------------------------------------- @@ -317,7 +218,10 @@ BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id,  const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(const LLUUID& obj_id) const  {  	const LLInventoryObject* obj = getObject(obj_id); -	const LLUUID& parent_id = obj->getParentUUID(); + +	// Search up the parent chain until we get to root or an acceptable folder. +	// This assumes there are no cycles in the tree else we'll get a hang. +	LLUUID parent_id = obj->getParentUUID();  	while (!parent_id.isNull())  	{  		const LLViewerInventoryCategory *cat = getCategory(parent_id); @@ -329,6 +233,7 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons  		{  			return cat;  		} +		parent_id = cat->getParentUUID();  	}  	return NULL;  } @@ -1840,8 +1745,6 @@ void LLInventoryModel::stopBackgroundFetch()  		gIdleCallbacks.deleteFunction(&LLInventoryModel::backgroundFetch, NULL);  		sBulkFetchCount=0;  		sMinTimeBetweenFetches=0.0f; - -		LMSortPrefix::completeCleanup();  	}  } @@ -1988,13 +1891,6 @@ void LLInventoryModel::cache(  	const LLUUID& parent_folder_id,  	const LLUUID& agent_id)  { -	if (getRootFolderID() == parent_folder_id) -	{ -		// *TODO: mantipov: can be removed before public release, EXT-3985 -		//save marker to avoid fetching inventory on future sessions -		LMSortPrefix::setLandmarksWereCleaned(); -	} -  	lldebugs << "Caching " << parent_folder_id << " for " << agent_id  			 << llendl;  	LLViewerInventoryCategory* root_cat = getCategory(parent_folder_id); @@ -2805,28 +2701,6 @@ void LLInventoryModel::buildParentChildMap()  			// The inv tree is built.  			mIsAgentInvUsable = true; -			{// *TODO: mantipov: can be removed before public release, EXT-3985 -				/* -				*HACK: mantipov: to cleanup landmarks were marked with sort index prefix in name. -				Is necessary to be called once per account after EXT-3985 is implemented. -				So, let fetch agent's inventory, processing will be done in processInventoryDescendents() -				Should be removed before public release. -				*/ -				if (!LMSortPrefix::wasClean()) -				{ -					cat_array_t cats; -					item_array_t items; -					collectDescendents(agent_inv_root_id, cats, items, INCLUDE_TRASH); - -					for (item_array_t::const_iterator it= items.begin(); it != items.end(); ++it) -					{ -						LMSortPrefix::removePrefix(*it); -					} - -					gInventory.startBackgroundFetch(agent_inv_root_id); -				} -			} -  			llinfos << "Inventory initialized, notifying observers" << llendl;  			addChangedMask(LLInventoryObserver::ALL, LLUUID::null);  			notifyObservers(); @@ -3592,10 +3466,6 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)  			continue;  		}  		gInventory.updateItem(titem); - -		{// *TODO: mantipov: can be removed before public release, EXT-3985 -			LMSortPrefix::removePrefix(titem); -		}  	}  	// set version and descendentcount according to message. diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index dc187bf36c..96ce01c05f 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -138,16 +138,20 @@ void LLLogChat::saveHistory(const std::string& filename,  			    const LLUUID& from_id,  			    const std::string& line)  { -	if(!filename.size()) +	std::string tmp_filename = filename; +	LLStringUtil::trim(tmp_filename); +	if (tmp_filename.empty())  	{ -		llinfos << "Filename is Empty!" << llendl; +		std::string warn = "Chat history filename [" + filename + "] is empty!"; +		llwarning(warn, 666); +		llassert(tmp_filename.size());  		return;  	} - +	  	llofstream file (LLLogChat::makeLogFileName(filename), std::ios_base::app);  	if (!file.is_open())  	{ -		llinfos << "Couldn't open chat history log!" << llendl; +		llwarns << "Couldn't open chat history log! - " + filename << llendl;  		return;  	} diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 8c21fb6314..13e6b2c072 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -34,6 +34,8 @@  #include "llnavigationbar.h" +#include "v2math.h" +  #include "llregionhandle.h"  #include "llfloaterreg.h" @@ -180,6 +182,77 @@ void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)  	mArrowIcon->setVisible(FALSE);  } +static LLDefaultChildRegistry::Register<LLPullButton> menu_button("pull_button"); + +LLPullButton::LLPullButton(const LLPullButton::Params& params): +		LLButton(params) +	,	mClickDraggingSignal(NULL) +{ +	setDirectionFromName(params.direction); +} +boost::signals2::connection LLPullButton::setClickDraggingCallback( const commit_signal_t::slot_type& cb )  +{  +	if (!mClickDraggingSignal) mClickDraggingSignal = new commit_signal_t(); +	return mClickDraggingSignal->connect(cb);  +} + +/*virtual*/ +void LLPullButton::onMouseLeave(S32 x, S32 y, MASK mask) +{ +	LLButton::onMouseLeave(x, y, mask); +	 +	if(mMouseDownTimer.getStarted() ) +	{ +		const LLVector2 cursor_direction = LLVector2(F32(x),F32(y)) - mLastMouseDown; +		if( angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4  +			{ +				if(mClickDraggingSignal) +				{ +					(*mClickDraggingSignal)(this, LLSD()); +				} +			} +	} + +} + +/*virtual*/ +BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask) +	{ +	BOOL handled = LLButton::handleMouseDown(x,y, mask); +	if(handled) +	{ +		mLastMouseDown.set(F32(x), F32(y)); +	} +	return handled; +} + +/*virtual*/ +BOOL LLPullButton::handleMouseUp(S32 x, S32 y, MASK mask) +{ +	mLastMouseDown.clear(); +	return LLButton::handleMouseUp(x, y, mask); +} + +void LLPullButton::setDirectionFromName(const std::string& name) +{ +	if (name == "left") +	{ +		mDraggingDirection.set(F32(-1), F32(0));  +	} +	else if (name == "right") +	{ +		mDraggingDirection.set(F32(0), F32(1));  +	} +	else if (name == "down") +	{ +		 mDraggingDirection.set(F32(0), F32(-1));  +	} +	else if (name == "up") +	{ +		 mDraggingDirection.set(F32(0), F32(1));  +	} +} +  //-- LNavigationBar ----------------------------------------------------------  /* @@ -214,8 +287,8 @@ LLNavigationBar::~LLNavigationBar()  BOOL LLNavigationBar::postBuild()  { -	mBtnBack	= getChild<LLButton>("back_btn"); -	mBtnForward	= getChild<LLButton>("forward_btn"); +	mBtnBack	= getChild<LLPullButton>("back_btn"); +	mBtnForward	= getChild<LLPullButton>("forward_btn");  	mBtnHome	= getChild<LLButton>("home_btn");  	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");  @@ -223,20 +296,15 @@ BOOL LLNavigationBar::postBuild()  	fillSearchComboBox(); -	if (!mBtnBack || !mBtnForward || !mBtnHome || -		!mCmbLocation || !mSearchComboBox) -	{ -		llwarns << "Malformed navigation bar" << llendl; -		return FALSE; -	} -	  	mBtnBack->setEnabled(FALSE);  	mBtnBack->setClickedCallback(boost::bind(&LLNavigationBar::onBackButtonClicked, this)); -	mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); - +	mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this,_1, _2)); +	mBtnBack->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1)); +	  	mBtnForward->setEnabled(FALSE);  	mBtnForward->setClickedCallback(boost::bind(&LLNavigationBar::onForwardButtonClicked, this)); -	mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); +	mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _1, _2)); +	mBtnForward->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1));  	mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); @@ -331,10 +399,10 @@ void LLNavigationBar::onBackButtonClicked()  	LLTeleportHistory::getInstance()->goBack();  } -void LLNavigationBar::onBackOrForwardButtonHeldDown(const LLSD& param) +void LLNavigationBar::onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param)  {  	if (param["count"].asInteger() == 0) -		showTeleportHistoryMenu(); +		showTeleportHistoryMenu(ctrl);  }  void LLNavigationBar::onForwardButtonClicked() @@ -569,7 +637,7 @@ void LLNavigationBar::onRegionNameResponse(  	gAgent.teleportViaLocation(global_pos);  } -void	LLNavigationBar::showTeleportHistoryMenu() +void	LLNavigationBar::showTeleportHistoryMenu(LLUICtrl* btn_ctrl)  {  	// Don't show the popup if teleport history is empty.  	if (LLTeleportHistory::getInstance()->isEmpty()) @@ -583,14 +651,43 @@ void	LLNavigationBar::showTeleportHistoryMenu()  	if (mTeleportHistoryMenu == NULL)  		return; -	// *TODO: why to draw/update anything before showing the menu? -	mTeleportHistoryMenu->buildDrawLabels();  	mTeleportHistoryMenu->updateParent(LLMenuGL::sMenuContainer);  	const S32 MENU_SPAWN_PAD = -1; -	LLMenuGL::showPopup(mBtnBack, mTeleportHistoryMenu, 0, MENU_SPAWN_PAD); - +	LLMenuGL::showPopup(btn_ctrl, mTeleportHistoryMenu, 0, MENU_SPAWN_PAD); +	LLButton* nav_button = dynamic_cast<LLButton*>(btn_ctrl); +	if(nav_button) +	{ +		if(mHistoryMenuConnection.connected()) +		{ +			LL_WARNS("Navgationbar")<<"mHistoryMenuConnection should be disconnected at this moment."<<LL_ENDL; +			mHistoryMenuConnection.disconnect(); +		} +		mHistoryMenuConnection = gMenuHolder->setMouseUpCallback(boost::bind(&LLNavigationBar::onNavigationButtonHeldUp, this, nav_button)); +		// pressed state will be update after mouseUp in  onBackOrForwardButtonHeldUp(); +		nav_button->setForcePressedState(true); +	}  	// *HACK pass the mouse capturing to the drop-down menu -	gFocusMgr.setMouseCapture( NULL ); +	// it need to let menu handle mouseup event +	gFocusMgr.setMouseCapture(gMenuHolder); +} +/** + * Taking into account the HACK above,  this callback-function is responsible for correct handling of mouseUp event in case of holding-down the navigation buttons.. + * We need to process this case separately to update a pressed state of navigation button. + */ +void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button) +{ +	if(nav_button) +	{ +		nav_button->setForcePressedState(false); +	} +	if(gFocusMgr.getMouseCapture() == gMenuHolder) +	{ +		// we had passed mouseCapture in  showTeleportHistoryMenu() +		// now we MUST release mouseCapture to continue a proper mouseevent workflow.  +		gFocusMgr.setMouseCapture(NULL); +	} +	//gMenuHolder is using to display bunch of menus. Disconnect signal to avoid unnecessary calls.     +	mHistoryMenuConnection.disconnect();  }  void LLNavigationBar::handleLoginComplete() diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 9d0687f193..9d0abc7a3a 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -34,14 +34,61 @@  #define LL_LLNAVIGATIONBAR_H  #include "llpanel.h" +#include "llbutton.h" -class LLButton;  class LLLocationInputCtrl;  class LLMenuGL;  class LLSearchEditor;  class LLSearchComboBox;  /** + * This button is able to handle click-dragging mouse event. + * It has appropriated signal for this event. + * Dragging direction can be set from xml by attribute called 'direction' + *  + * *TODO: move to llui?   + */ + +class LLPullButton : public LLButton +{ +	LOG_CLASS(LLPullButton); +	 +public: +	 +	struct Params : public LLInitParam::Block<Params, LLButton::Params> +	{ +		Optional<std::string>	direction; // left, right, down, up +		 +		Params() +		:	direction("direction","down") +		{} +	}; +	 +	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); +	 +	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); +	 +	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + +	boost::signals2::connection setClickDraggingCallback( const commit_signal_t::slot_type& cb ); +	 +	/* virtual*/ ~LLPullButton() +	{ +		delete mClickDraggingSignal; +	} +	 +protected: +	friend class LLUICtrlFactory; +	// convert string name into direction vector +	void setDirectionFromName(const std::string& name); +	LLPullButton(const LLPullButton::Params& params); +	 +	commit_signal_t* mClickDraggingSignal;	 +	LLVector2 mLastMouseDown; +	LLVector2 mDraggingDirection; +}; + +/**   * Web browser-like navigation bar.   */   class LLNavigationBar @@ -70,13 +117,14 @@ public:  private:  	void rebuildTeleportHistoryMenu(); -	void showTeleportHistoryMenu(); +	void showTeleportHistoryMenu(LLUICtrl* btn_ctrl);  	void invokeSearch(std::string search_text);  	// callbacks  	void onTeleportHistoryMenuItemClicked(const LLSD& userdata);  	void onTeleportHistoryChanged();  	void onBackButtonClicked(); -	void onBackOrForwardButtonHeldDown(const LLSD& param); +	void onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param); +	void onNavigationButtonHeldUp(LLButton* nav_button);  	void onForwardButtonClicked();  	void onHomeButtonClicked();  	void onLocationSelection(); @@ -94,8 +142,8 @@ private:  	void fillSearchComboBox();  	LLMenuGL*					mTeleportHistoryMenu; -	LLButton*					mBtnBack; -	LLButton*					mBtnForward; +	LLPullButton*				mBtnBack; +	LLPullButton*				mBtnForward;  	LLButton*					mBtnHome;  	LLSearchComboBox*			mSearchComboBox;  	LLLocationInputCtrl*		mCmbLocation; @@ -103,6 +151,7 @@ private:  	LLRect						mDefaultFpRect;  	boost::signals2::connection	mTeleportFailedConnection;  	boost::signals2::connection	mTeleportFinishConnection; +	boost::signals2::connection	mHistoryMenuConnection;  	bool						mPurgeTPHistoryItems;  	// if true, save location to location history when teleport finishes  	bool						mSaveToLocationHistory; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 90482eb74d..6de47fccd2 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -62,6 +62,12 @@  static const S32 RESIZE_BAR_THICKNESS = 3; +const static std::string IM_TIME("time"); +const static std::string IM_TEXT("message"); +const static std::string IM_FROM("from"); +const static std::string IM_FROM_ID("from_id"); + +  LLNearbyChat::LLNearbyChat(const LLSD& key)   	: LLDockableFloater(NULL, false, false, key)  	,mChatHistory(NULL) @@ -194,6 +200,18 @@ void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)  		mMessageArchive.push_back(chat);  		if(mMessageArchive.size()>200)  			mMessageArchive.erase(mMessageArchive.begin()); + +		if (gSavedPerAccountSettings.getBOOL("LogChat"))  +		{ +			if (chat.mChatType != CHAT_TYPE_WHISPER && chat.mChatType != CHAT_TYPE_SHOUT) +			{ +				LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); +			} +			else +			{ +				LLLogChat::saveHistory("chat", "", chat.mFromID, chat.mFromName + " " + chat.mText); +			} +		}  	}  } @@ -262,6 +280,39 @@ void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)  		nearby_chat->updateChatHistoryStyle();  } +void LLNearbyChat::loadHistory() +{ +	std::list<LLSD> history; +	LLLogChat::loadAllHistory("chat", history); + +	std::list<LLSD>::const_iterator it = history.begin(); +	while (it != history.end()) +	{ +		const LLSD& msg = *it; + +		std::string from = msg[IM_FROM]; +		LLUUID from_id = LLUUID::null; +		if (msg[IM_FROM_ID].isUndefined()) +		{ +			gCacheName->getUUID(from, from_id); +		} + +		LLChat chat; +		chat.mFromName = from; +		chat.mFromID = from_id; +		chat.mText = msg[IM_TEXT].asString(); +		chat.mTimeStr = msg[IM_TIME].asString(); +		addMessage(chat); + +		it++; +	} +} + +//static +LLNearbyChat* LLNearbyChat::getInstance() +{ +	return LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); +}  ////////////////////////////////////////////////////////////////////////////////  // @@ -278,3 +329,4 @@ void LLNearbyChat::onFocusLost()  	setBackgroundOpaque(false);  	LLPanel::onFocusLost();  } + diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 5fb8ade19e..6ef2a1fee3 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -47,6 +47,8 @@ public:  	~LLNearbyChat();  	BOOL	postBuild			(); + +	/** @param archive true - to save a message to the chat history log */  	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());	  	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);  	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata); @@ -65,6 +67,10 @@ public:  	static void processChatHistoryStyleUpdate(const LLSD& newvalue); +	void loadHistory(); + +	static LLNearbyChat* getInstance(); +  private:  	virtual void    applySavedVariables(); diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index e2a748a1c5..b8e0892b02 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -168,6 +168,12 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi  			session_name = "chat";  		} +		//there still appears a log history file with weird name " .txt" +		if (" " == session_name || "{waiting}" == session_name || "{nobody}" == session_name) +		{ +			llwarning("Weird session name (" + session_name + ") for notification " + notification->getName(), 666) +		} +  		if(to_file_only)  		{  			logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(), diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 3f5d80c123..1e46827c1a 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -1231,12 +1231,14 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t  			static std::string mature_str = getString("type_mature");  			static std::string pg_str = getString("type_pg"); +			static LLUIString  price_str = getString("l$_price");  			bool mature = is_cf_mature(c_info->flags);  			childSetValue("content_type", mature ? mature_str : pg_str);  			childSetValue("auto_renew", is_cf_auto_renew(c_info->flags)); -			childSetTextArg("price_for_listing", "[PRICE]", llformat("%d", c_info->price_for_listing)); +			price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing)); +			childSetValue("price_for_listing", LLSD(price_str));  			setInfoLoaded(true);  		} diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 7fd2c98cb1..fd7c751cc1 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -280,8 +280,6 @@ void LLPanelGroupControlPanel::draw()  	// Need to resort the participant list if it's in sort by recent speaker order.  	if (mParticipantList)  		mParticipantList->updateRecentSpeakersOrder(); -	//* TODO: find better way to properly enable call button for group and remove this call from draw() -	updateCallButton();  	LLPanelChatControlPanel::draw();  } diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index 0f0fb4b94e..ea66ef7d2c 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -198,6 +198,10 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d  {  	fillCommonData(avatar_data); +	// 'Home page' was hidden in LLPanelAvatarProfile::fillCommonData() to fix  EXT-4734 +	// Show 'Home page' in Edit My Profile (EXT-4873) +	childSetVisible("homepage_edit", true); +  	fillPartnerData(avatar_data);  	fillAccountStatus(avatar_data); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 42a5c0b775..b45e4ba682 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -516,7 +516,6 @@ BOOL LLPanelPeople::postBuild()  	mRecentList->setShowIcons("RecentListShowIcons");  	mGroupList = getChild<LLGroupList>("group_list"); -	mGroupList->setNoItemsCommentText(getString("no_groups"));  	mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);  	mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu); @@ -668,6 +667,11 @@ void LLPanelPeople::updateFriendList()  		lldebugs << "Friends Cards were not found" << llendl;  	} +	// show special help text for just created account to help found friends. EXT-4836 +	static LLTextBox* no_friends_text = getChild<LLTextBox>("no_friends_msg"); +	no_friends_text->setVisible(all_friendsp.size() == 0); + +  	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();  	for (; buddy_it != all_buddies.end(); ++buddy_it)  	{ diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 29cfbbe606..a49386cb5c 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -70,6 +70,7 @@  #include "lltoggleablemenu.h"  #include "llviewerinventory.h"  #include "llviewermenu.h" +#include "llviewermessage.h"  #include "llviewerparcelmgr.h"  #include "llviewerregion.h"  #include "llviewerwindow.h" @@ -105,22 +106,35 @@ private:  	LLPanelPlaces*		mPlaces;  }; -class LLPlacesInventoryObserver : public LLInventoryObserver +class LLPlacesInventoryObserver : public LLInventoryAddedObserver  {  public:  	LLPlacesInventoryObserver(LLPanelPlaces* places_panel) : -		LLInventoryObserver(), -		mPlaces(places_panel) +		mPlaces(places_panel), +		mTabsCreated(false)  	{}  	/*virtual*/ void changed(U32 mask)  	{ -		if (mPlaces) -			mPlaces->changedInventory(mask); +		LLInventoryAddedObserver::changed(mask); + +		if (!mTabsCreated && mPlaces) +		{ +			mPlaces->createTabs(); +			mTabsCreated = true; +		} +	} + +protected: +	/*virtual*/ void done() +	{ +		mPlaces->showAddedLandmarkInfo(mAdded); +		mAdded.clear();  	}  private:  	LLPanelPlaces*		mPlaces; +	bool				mTabsCreated;  };  class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver @@ -943,7 +957,7 @@ void LLPanelPlaces::changedParcelSelection()  	updateVerbs();  } -void LLPanelPlaces::changedInventory(U32 mask) +void LLPanelPlaces::createTabs()  {  	if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance()))  		return; @@ -979,10 +993,6 @@ void LLPanelPlaces::changedInventory(U32 mask)  	// Filter applied to show all items.  	if (mActivePanel)  		mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); - -	// we don't need to monitor inventory changes anymore, -	// so remove the observer -	gInventory.removeObserver(mInventoryObserver);  }  void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos) @@ -991,6 +1001,33 @@ void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos)  	updateVerbs();  } +void LLPanelPlaces::showAddedLandmarkInfo(const std::vector<LLUUID>& items) +{ +	for (std::vector<LLUUID>::const_iterator item_iter = items.begin(); +		 item_iter != items.end(); +		 ++item_iter) +	{ +		const LLUUID& item_id = (*item_iter); +		if(!highlight_offered_item(item_id)) +		{ +			continue; +		} + +		LLInventoryItem* item = gInventory.getItem(item_id); + +		if (LLAssetType::AT_LANDMARK == item->getType()) +		{ +			// Created landmark is passed to Places panel to allow its editing. +			// If the panel is closed we don't reopen it until created landmark is loaded. +			if("create_landmark" == getPlaceInfoType() && !getItem()) +			{ +				setItem(item); +			} +			break; +		} +	} +} +  void LLPanelPlaces::updateVerbs()  {  	bool is_place_info_visible; diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 110d7a1054..78fcbbb11d 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -66,11 +66,15 @@ public:  	// Called on parcel selection change to update place information.  	void changedParcelSelection(); -	// Called on agent inventory change to find out when inventory gets usable. -	void changedInventory(U32 mask); +	// Called once on agent inventory first change to find out when inventory gets usable +	// and to create "My Landmarks" and "Teleport History" tabs. +	void createTabs();  	// Called when we receive the global 3D position of a parcel.  	void changedGlobalPos(const LLVector3d &global_pos); +	// Opens landmark info panel when agent creates or receives landmark. +	void showAddedLandmarkInfo(const std::vector<LLUUID>& items); +  	void setItem(LLInventoryItem* item);  	LLInventoryItem* getItem() { return mItem; } diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 43e0f9a88c..90c8f2551f 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -940,6 +940,9 @@ bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notificati  	if (0 == option)  	{ +		// order does matter, call this first or teleport history will contain one record(current location) +		LLTeleportHistory::getInstance()->purgeItems(); +  		LLTeleportHistoryStorage *th = LLTeleportHistoryStorage::getInstance();  		th->purgeItems();  		th->save(); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index dc0839c774..b90d2eedfc 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -582,7 +582,8 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(co  bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)  {  	std::string item = userdata.asString(); -	if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item) +	if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item  +		|| "can_pay" == item || "can_add" == item)  	{  		return mUUIDs.front() != gAgentID;  	} diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index fccf71f3cb..7bcbe334ff 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1904,7 +1904,7 @@ void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,  										 const LLUUID& item_id,  										 BOOL is_running)  { -	llinfos << "Update Task Inventory via capability" << llendl; +	llinfos << "Update Task Inventory via capability " << url << llendl;  	LLSD body;  	body["task_id"] = task_id;  	body["item_id"] = item_id; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index a00b6a9288..8f36c0e88a 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -487,10 +487,21 @@ void LLScreenChannel::showToastsBottom()  		toast_rect.setOriginAndSize(getRect().mLeft, bottom + toast_margin, toast_rect.getWidth() ,toast_rect.getHeight());  		(*it).toast->setRect(toast_rect); -		// don't show toasts if there is not enough space  		if(floater && floater->overlapsScreenChannel())  		{ +			if(it == mToastList.rbegin()) +			{ +				// move first toast above docked floater +				S32 shift = floater->getRect().getHeight(); +				if(floater->getDockControl()) +				{ +					shift += floater->getDockControl()->getTongueHeight(); +				} +				(*it).toast->translate(0, shift); +			} +  			LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); +			// don't show toasts if there is not enough space  			if(toast_rect.mTop > world_rect.mTop)  			{  				break; @@ -802,16 +813,6 @@ void LLScreenChannel::updateShowToastsState()  	S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");;  	LLRect this_rect = getRect(); -	// adjust channel's height -	if(floater->overlapsScreenChannel()) -	{ -		channel_bottom += floater->getRect().getHeight(); -		if(floater->getDockControl()) -		{ -			channel_bottom += floater->getDockControl()->getTongueHeight(); -		} -	} -  	if(channel_bottom != this_rect.mBottom)  	{  		setRect(LLRect(this_rect.mLeft, this_rect.mTop, this_rect.mRight, channel_bottom)); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 5383158cd3..3fd5309947 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -164,7 +164,21 @@ void LLSidepanelInventory::onWearButtonClicked()  void LLSidepanelInventory::onPlayButtonClicked()  { -	performActionOnSelection("activate"); +	const LLInventoryItem *item = getSelectedItem(); +	if (!item) +	{ +		return; +	} + +	switch(item->getInventoryType()) +	{ +	case LLInventoryType::IT_GESTURE: +		performActionOnSelection("play"); +		break; +	default: +		performActionOnSelection("open"); +		break; +	}  }  void LLSidepanelInventory::onTeleportButtonClicked() diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index c2d3749a3a..2c6b93df96 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -67,6 +67,7 @@  #include "llmemorystream.h"  #include "llmessageconfig.h"  #include "llmoveview.h" +#include "llnearbychat.h"  #include "llnotifications.h"  #include "llnotificationsutil.h"  #include "llteleporthistory.h" @@ -861,7 +862,8 @@ bool idle_startup()  		LLFile::mkdir(gDirUtilp->getChatLogsDir());  		LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); -		//good as place as any to create user windlight directories + +		//good a place as any to create user windlight directories  		std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", ""));  		LLFile::mkdir(user_windlight_path_name.c_str());		 @@ -1282,6 +1284,14 @@ bool idle_startup()              LLAppViewer::instance()->loadNameCache();  		} +		//gCacheName is required for nearby chat history loading +		//so I just moved nearby history loading a few states further +		if (!gNoRender && gSavedPerAccountSettings.getBOOL("LogShowHistory")) +		{ +			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); +			if (nearby_chat) nearby_chat->loadHistory(); +		} +  		// *Note: this is where gWorldMap used to be initialized.  		// register null callbacks for audio until the audio system is initialized diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index ce00dec802..dcc85392f7 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -173,6 +173,8 @@ void LLTeleportHistory::purgeItems()  	// reset the count  	mRequestedItem = -1;  	mCurrentItem = 0; + +	onHistoryChanged();  }  // static diff --git a/indra/newview/lltoolplacer.h b/indra/newview/lltoolplacer.h index b7422380d4..df07f1854c 100644 --- a/indra/newview/lltoolplacer.h +++ b/indra/newview/lltoolplacer.h @@ -33,7 +33,6 @@  #ifndef LL_TOOLPLACER_H  #define LL_TOOLPLACER_H -#include "llprimitive.h"  #include "llpanel.h"  #include "lltool.h" diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 658d1c9ddd..29114c33c5 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -200,7 +200,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);  	LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>); -	LLFloaterReg::add("call_info", "floater_call_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallInfoDialog>);  	LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>);  	LLFloaterPayUtil::registerFloater(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d95450e506..e437f5bc69 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -860,28 +860,12 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f  		 ++item_iter)  	{  		const LLUUID& item_id = (*item_iter); -		LLInventoryItem* item = gInventory.getItem(item_id); -		if(!item) +		if(!highlight_offered_item(item_id))  		{ -			LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL;  			continue;  		} -		//////////////////////////////////////////////////////////////////////////////// -		// Don't highlight if it's in certain "quiet" folders which don't need UI  -		// notification (e.g. trash, cof, lost-and-found). -		if(!gAgent.getAFK()) -		{ -			const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(item_id); -			if (parent) -			{ -				const LLFolderType::EType parent_type = parent->getPreferredType(); -				if (LLViewerFolderType::lookupIsQuietType(parent_type)) -				{ -					continue; -				} -			} -		} +		LLInventoryItem* item = gInventory.getItem(item_id);  		////////////////////////////////////////////////////////////////////////////////  		// Special handling for various types. @@ -928,10 +912,11 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f  						LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->getPanel("panel_places"));  						if (places_panel)  						{ -							// we are creating a landmark +							// Landmark creation handling is moved to LLPanelPlaces::showAddedLandmarkInfo() +							// TODO* LLPanelPlaces dependency is going to be removed. See EXT-4347.  							if("create_landmark" == places_panel->getPlaceInfoType() && !places_panel->getItem())  							{ -								places_panel->setItem(item); +								//places_panel->setItem(item);  							}  							// we are opening a group notice attachment  							else @@ -981,6 +966,34 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f  	}  } +bool highlight_offered_item(const LLUUID& item_id) +{ +	LLInventoryItem* item = gInventory.getItem(item_id); +	if(!item) +	{ +		LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL; +		return false; +	} + +	//////////////////////////////////////////////////////////////////////////////// +	// Don't highlight if it's in certain "quiet" folders which don't need UI +	// notification (e.g. trash, cof, lost-and-found). +	if(!gAgent.getAFK()) +	{ +		const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(item_id); +		if (parent) +		{ +			const LLFolderType::EType parent_type = parent->getPreferredType(); +			if (LLViewerFolderType::lookupIsQuietType(parent_type)) +			{ +				return false; +			} +		} +	} + +	return true; +} +  void inventory_offer_mute_callback(const LLUUID& blocked_id,  								   const std::string& first_name,  								   const std::string& last_name, @@ -2168,6 +2181,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				chat.mFromID = from_id ^ gAgent.getSessionID();  			} +			if(SYSTEM_FROM == name) +			{ +				// System's UUID is NULL (fixes EXT-4766) +				chat.mFromID = from_id = LLUUID::null; +			} +  			LLSD query_string;  			query_string["owner"] = from_id;  			query_string["slurl"] = location; @@ -2186,7 +2205,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());  			if(nearby_chat)  			{ -				nearby_chat->addMessage(chat); +				LLSD args; +				args["owner_id"] = from_id; +				args["slurl"] = location; +				nearby_chat->addMessage(chat, true, args);  			} diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 1415c16090..7dd629dcfd 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -203,6 +203,11 @@ void process_initiate_download(LLMessageSystem* msg, void**);  void start_new_inventory_observer();  void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& from_name); +// Returns true if item is not in certain "quiet" folder which don't need UI +// notification (e.g. trash, cof, lost-and-found) and agent is not AFK, false otherwise. +// Returns false if item is not found. +bool highlight_offered_item(const LLUUID& item_id); +  struct LLOfferInfo  {          LLOfferInfo() diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 202abe2833..dc66541df9 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -395,13 +395,16 @@ void LLVoiceChannel::setState(EState state)  	switch(state)  	{  	case STATE_RINGING: -		LLCallInfoDialog::show("ringing", mNotifyArgs); +		//TODO: remove or redirect this call status notification +//		LLCallInfoDialog::show("ringing", mNotifyArgs);  		break;  	case STATE_CONNECTED: -		LLCallInfoDialog::show("connected", mNotifyArgs); +		//TODO: remove or redirect this call status notification +//		LLCallInfoDialog::show("connected", mNotifyArgs);  		break;  	case STATE_HUNG_UP: -		LLCallInfoDialog::show("hang_up", mNotifyArgs); +		//TODO: remove or redirect this call status notification +//		LLCallInfoDialog::show("hang_up", mNotifyArgs);  		break;  	default:  		break; @@ -640,7 +643,8 @@ void LLVoiceChannelGroup::setState(EState state)  	case STATE_RINGING:  		if ( !mIsRetrying )  		{ -			LLCallInfoDialog::show("ringing", mNotifyArgs); +			//TODO: remove or redirect this call status notification +//			LLCallInfoDialog::show("ringing", mNotifyArgs);  		}  		doSetState(state); @@ -705,7 +709,8 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)  		//skip showing "Voice not available at your current location" when agent voice is disabled (EXT-4749)  		if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())  		{ -			LLCallInfoDialog::show("unavailable", mNotifyArgs); +			//TODO: remove or redirect this call status notification +//			LLCallInfoDialog::show("unavailable", mNotifyArgs);  		}  		return;  	default: @@ -905,7 +910,8 @@ void LLVoiceChannelP2P::setState(EState state)  		// so provide a special purpose message here  		if (mReceivedCall && state == STATE_RINGING)  		{ -			LLCallInfoDialog::show("answering", mNotifyArgs); +			//TODO: remove or redirect this call status notification +//			LLCallInfoDialog::show("answering", mNotifyArgs);  			doSetState(state);  			return;  		} diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index d16f59b844..739f6d51d3 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -4593,7 +4593,8 @@ BOOL LLVivoxVoiceClient::isOnlineSIP(const LLUUID &id)  bool LLVivoxVoiceClient::isVoiceWorking()  { -	return (stateLoggedIn <= mState) && (mState <= stateLeavingSession); +  //Added stateSessionTerminated state to avoid problems with call in parcels with disabled voice (EXT-4758) +  return (stateLoggedIn <= mState) && (mState <= stateSessionTerminated);  }  // Returns true if the indicated participant in the current audio session is really an SL avatar. diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index e3b6b1fa36..34b14b2837 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -83,7 +83,8 @@ public:  	virtual void updateSettings(); // call after loading settings and whenever they change -	virtual bool isVoiceWorking(); // connected to a voice server and voice channel +	// Returns true if vivox has successfully logged in and is not in error state	 +	virtual bool isVoiceWorking();  	/////////////////////  	/// @name Tuning diff --git a/indra/newview/skins/default/textures/build/Object_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Cone_Selected.pngBinary files differ new file mode 100644 index 0000000000..d50dc69ffe --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cube_Selected.png b/indra/newview/skins/default/textures/build/Object_Cube_Selected.pngBinary files differ new file mode 100644 index 0000000000..3d6964530d --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.pngBinary files differ new file mode 100644 index 0000000000..3ed0389961 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Grass_Selected.png b/indra/newview/skins/default/textures/build/Object_Grass_Selected.pngBinary files differ new file mode 100644 index 0000000000..3ebd5ea7a1 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.pngBinary files differ new file mode 100644 index 0000000000..3bdc4d1fd5 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.pngBinary files differ new file mode 100644 index 0000000000..0912442e29 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.pngBinary files differ new file mode 100644 index 0000000000..33db4a2de8 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Prism_Selected.png b/indra/newview/skins/default/textures/build/Object_Prism_Selected.pngBinary files differ new file mode 100644 index 0000000000..9e80fe2b84 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.pngBinary files differ new file mode 100644 index 0000000000..d36bfa55d4 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Ring_Selected.png b/indra/newview/skins/default/textures/build/Object_Ring_Selected.pngBinary files differ new file mode 100644 index 0000000000..962f6efb93 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.pngBinary files differ new file mode 100644 index 0000000000..715d597144 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.pngBinary files differ new file mode 100644 index 0000000000..b2ea680f23 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Torus_Selected.png b/indra/newview/skins/default/textures/build/Object_Torus_Selected.pngBinary files differ new file mode 100644 index 0000000000..1fc22686eb --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tree_Selected.png b/indra/newview/skins/default/textures/build/Object_Tree_Selected.pngBinary files differ new file mode 100644 index 0000000000..5bd87f8a2f --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tube_Selected.png b/indra/newview/skins/default/textures/build/Object_Tube_Selected.pngBinary files differ new file mode 100644 index 0000000000..a4c3f39e14 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 60c1470b89..ea66897b35 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -321,20 +321,35 @@ with the same filename but different name    <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" />    <texture name="Object_Cone" file_name="build/Object_Cone.png" preload="false" /> +  <texture name="Object_Cone_Selected" file_name="build/Object_Cone_Selected.png" preload="false" />    <texture name="Object_Cube" file_name="build/Object_Cube.png" preload="false" /> +  <texture name="Object_Cube_Selected" file_name="build/Object_Cube_Selected.png" preload="false" />    <texture name="Object_Cylinder" file_name="build/Object_Cylinder.png" preload="false" /> +  <texture name="Object_Cylinder_Selected" file_name="build/Object_Cylinder_Selected.png" preload="false" />    <texture name="Object_Grass" file_name="build/Object_Grass.png" preload="false" /> +  <texture name="Object_Grass_Selected" file_name="build/Object_Grass_Selected.png" preload="false" />    <texture name="Object_Hemi_Cone" file_name="build/Object_Hemi_Cone.png" preload="false" /> +  <texture name="Object_Hemi_Cone_Selected" file_name="build/Object_Hemi_Cone_Selected.png" preload="false" />    <texture name="Object_Hemi_Cylinder" file_name="build/Object_Hemi_Cylinder.png" preload="false" /> +  <texture name="Object_Hemi_Cylinder_Selected" file_name="build/Object_Hemi_Cylinder_Selected.png" preload="false" />    <texture name="Object_Hemi_Sphere" file_name="build/Object_Hemi_Sphere.png" preload="false" /> +  <texture name="Object_Hemi_Sphere_Selected" file_name="build/Object_Hemi_Sphere_Selected.png" preload="false" />    <texture name="Object_Prism" file_name="build/Object_Prism.png" preload="false" /> +  <texture name="Object_Prism_Selected" file_name="build/Object_Prism_Selected.png" preload="false" />    <texture name="Object_Pyramid" file_name="build/Object_Pyramid.png" preload="false" /> +  <texture name="Object_Pyramid_Selected" file_name="build/Object_Pyramid_Selected.png" preload="false" />    <texture name="Object_Ring" file_name="build/Object_Ring.png" preload="false" /> +  <texture name="Object_Ring_Selected" file_name="build/Object_Ring_Selected.png" preload="false" />    <texture name="Object_Sphere" file_name="build/Object_Sphere.png" preload="false" /> +  <texture name="Object_Sphere_Selected" file_name="build/Object_Sphere_Selected.png" preload="false" />    <texture name="Object_Tetrahedron" file_name="build/Object_Tetrahedron.png" preload="false" /> +  <texture name="Object_Tetrahedron_Selected" file_name="build/Object_Tetrahedron_Selected.png" preload="false" />    <texture name="Object_Torus" file_name="build/Object_Torus.png" preload="false" /> +  <texture name="Object_Torus_Selected" file_name="build/Object_Torus_Selected.png" preload="false" />    <texture name="Object_Tree" file_name="build/Object_Tree.png" preload="false" /> +  <texture name="Object_Tree_Selected" file_name="build/Object_Tree_Selected.png" preload="false" />    <texture name="Object_Tube" file_name="build/Object_Tube.png" preload="false" /> +  <texture name="Object_Tube_Selected" file_name="build/Object_Tube_Selected.png" preload="false" />    <texture name="OptionsMenu_Disabled" file_name="icons/OptionsMenu_Disabled.png" preload="false" />    <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> @@ -585,10 +600,15 @@ with the same filename but different name             scale.left="4" scale.top="28" scale.right="60" scale.bottom="4" />    <texture name="Tool_Create" file_name="build/Tool_Create.png" preload="false" /> +  <texture name="Tool_Create_Selected" file_name="build/Tool_Create_Selected.png" preload="false" />    <texture name="Tool_Dozer" file_name="build/Tool_Dozer.png" preload="false" /> +  <texture name="Tool_Dozer_Selected" file_name="build/Tool_Dozer_Selected.png" preload="false" />    <texture name="Tool_Face" file_name="build/Tool_Face.png" preload="false" /> +  <texture name="Tool_Face_Selected" file_name="build/Tool_Face_Selected.png" preload="false" />    <texture name="Tool_Grab" file_name="build/Tool_Grab.png" preload="false" /> +  <texture name="Tool_Grab_Selected" file_name="build/Tool_Grab_Selected.png" preload="false" />    <texture name="Tool_Zoom" file_name="build/Tool_Zoom.png" preload="false" /> +  <texture name="Tool_Zoom_Selected" file_name="build/Tool_Zoom_Selected.png" preload="false" />    <texture name="Toolbar_Divider" file_name="containers/Toolbar_Divider.png" preload="false" />    <texture name="Toolbar_Left_Off" file_name="containers/Toolbar_Left_Off.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml index 7236351f2e..b9bc45a10b 100644 --- a/indra/newview/skins/default/xui/en/floater_aaa.xml +++ b/indra/newview/skins/default/xui/en/floater_aaa.xml @@ -19,7 +19,7 @@   width="320">    <string name="nudge_parabuild" translate="false">Nudge 1</string>    <string name="test_the_vlt">This string CHANGE2 is extracted.</string> -  <string name="testing_eli">Just a test. change here. more change.</string> +  <string name="testing_eli">Just a test. changes.</string>    <chat_history     allow_html="true"     bg_readonly_color="ChatHistoryBgColor" diff --git a/indra/newview/skins/default/xui/en/floater_animation_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_preview.xml index 4f4288b654..1ffedde29b 100644 --- a/indra/newview/skins/default/xui/en/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_preview.xml @@ -147,7 +147,11 @@ Maximum animation length is [MAX_LENGTH] seconds.       name="E_ST_NO_XLT_EMOTE">          Cannot read emote name.      </floater.string> -    <text +    <floater.string +     name="E_ST_BAD_ROOT"> +        Incorrect root joint name, use "hip". +    </floater.string> +  <text       type="string"       length="1"       bottom="42" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 9aaa660574..d2e5473157 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -12,7 +12,7 @@   can_minimize="true"   can_close="true"   visible="false" - width="440" + width="360"   can_resize="true"   min_width="250"   min_height="190"> @@ -20,7 +20,7 @@     animate="false"     follows="all"    height="320" -  width="440" +  width="360"    layout="topleft"    orientation="horizontal"    name="im_panels" @@ -38,7 +38,7 @@         left="0"         top="0"         height="200" -	     width="325" +	     width="245"         user_resize="true">          <button            height="20" @@ -65,7 +65,7 @@           parse_highlights="true"           allow_html="true"          left="1" -         width="320"> +         width="240">          </chat_history>          <line_editor           bottom="0" @@ -75,7 +75,7 @@           label="To"           layout="bottomleft"           name="chat_editor" -         width="320"> +         width="240">          </line_editor>      </layout_panel>    </layout_stack> diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml index 455018f467..d09a0a0535 100644 --- a/indra/newview/skins/default/xui/en/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml @@ -36,7 +36,7 @@       top_delta="3"       name="payee_name"       width="184"> -      Ericacita Moostopolison +      [FIRST] [LAST]      </text>      <text       type="string" diff --git a/indra/newview/skins/default/xui/en/floater_script_limits.xml b/indra/newview/skins/default/xui/en/floater_script_limits.xml index 98c44ad1b3..6b36cdfcc5 100644 --- a/indra/newview/skins/default/xui/en/floater_script_limits.xml +++ b/indra/newview/skins/default/xui/en/floater_script_limits.xml @@ -1,6 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater   legacy_header_height="18" + can_resize="true"   height="570"   help_topic="scriptlimits"   layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index 60c9810e95..2c9402f6cb 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -46,8 +46,11 @@    <ui_ctrl       height="90"      width="90" +    layout="topleft"      name="thumbnail_placeholder"      top_pad="6" +    follows="left|top" +    left="10"      />      <text       type="string" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index f1aa5c27c1..5630dfbe8f 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -70,7 +70,7 @@       height="20"       image_disabled="Tool_Zoom"       image_disabled_selected="Tool_Zoom" -     image_selected="Tool_Zoom" +     image_selected="Tool_Zoom_Selected"       image_unselected="Tool_Zoom"       layout="topleft"       left="10" @@ -86,7 +86,7 @@       height="20"       image_disabled="Tool_Grab"       image_disabled_selected="Tool_Grab" -     image_selected="Tool_Grab" +     image_selected="Tool_Grab_Selected"       image_unselected="Tool_Grab"       layout="topleft"       left_pad="20" @@ -102,7 +102,7 @@       height="20"       image_disabled="Tool_Face"       image_disabled_selected="Tool_Face" -     image_selected="Tool_Face" +     image_selected="Tool_Face_Selected"       image_unselected="Tool_Face"       layout="topleft"       left_pad="20" @@ -118,7 +118,7 @@       height="20"       image_disabled="Tool_Create"       image_disabled_selected="Tool_Create" -     image_selected="Tool_Create" +     image_selected="Tool_Create_Selected"       image_unselected="Tool_Create"       layout="topleft"       left_pad="20" @@ -134,7 +134,7 @@       height="20"       image_disabled="Tool_Dozer"       image_disabled_selected="Tool_Dozer" -     image_selected="Tool_Dozer" +     image_selected="Tool_Dozer_Selected"       image_unselected="Tool_Dozer"       layout="topleft"       left_pad="20" @@ -344,7 +344,7 @@       height="20"       image_disabled="Object_Cube"       image_disabled_selected="Object_Cube" -     image_selected="Object_Cube" +     image_selected="Object_Cube_Selected"       image_unselected="Object_Cube"       layout="topleft"       left="4" @@ -357,7 +357,7 @@       height="20"       image_disabled="Object_Prism"       image_disabled_selected="Object_Prism" -     image_selected="Object_Prism" +     image_selected="Object_Prism_Selected"       image_unselected="Object_Prism"       layout="topleft"       left_delta="26" @@ -370,7 +370,7 @@       height="20"       image_disabled="Object_Pyramid"       image_disabled_selected="Object_Pyramid" -     image_selected="Object_Pyramid" +     image_selected="Object_Pyramid_Selected"       image_unselected="Object_Pyramid"       layout="topleft"       left_delta="26" @@ -383,7 +383,7 @@       height="20"       image_disabled="Object_Tetrahedron"       image_disabled_selected="Object_Tetrahedron" -     image_selected="Object_Tetrahedron" +     image_selected="Object_Tetrahedron_Selected"       image_unselected="Object_Tetrahedron"       layout="topleft"       left_delta="26" @@ -396,7 +396,7 @@       height="20"       image_disabled="Object_Cylinder"       image_disabled_selected="Object_Cylinder" -     image_selected="Object_Cylinder" +     image_selected="Object_Cylinder_Selected"       image_unselected="Object_Cylinder"       layout="topleft"       left_delta="26" @@ -409,7 +409,7 @@       height="20"       image_disabled="Object_Hemi_Cylinder"       image_disabled_selected="Object_Hemi_Cylinder" -     image_selected="Object_Hemi_Cylinder" +     image_selected="Object_Hemi_Cylinder_Selected"       image_unselected="Object_Hemi_Cylinder"       layout="topleft"       left_delta="26" @@ -422,7 +422,7 @@       height="20"       image_disabled="Object_Cone"       image_disabled_selected="Object_Cone" -     image_selected="Object_Cone" +     image_selected="Object_Cone_Selected"       image_unselected="Object_Cone"       layout="topleft"       left_delta="26" @@ -435,7 +435,7 @@       height="20"       image_disabled="Object_Hemi_Cone"       image_disabled_selected="Object_Hemi_Cone" -     image_selected="Object_Hemi_Cone" +     image_selected="Object_Hemi_Cone_Selected"       image_unselected="Object_Hemi_Cone"       layout="topleft"       left_delta="26" @@ -448,7 +448,7 @@       height="20"       image_disabled="Object_Sphere"       image_disabled_selected="Object_Sphere" -     image_selected="Object_Sphere" +     image_selected="Object_Sphere_Selected"       image_unselected="Object_Sphere"       layout="topleft"       left_delta="26" @@ -461,7 +461,7 @@       height="20"       image_disabled="Object_Hemi_Sphere"       image_disabled_selected="Object_Hemi_Sphere" -     image_selected="Object_Hemi_Sphere" +     image_selected="Object_Hemi_Sphere_Selected"       image_unselected="Object_Hemi_Sphere"       layout="topleft"       left_delta="26" @@ -474,7 +474,7 @@       height="20"       image_disabled="Object_Torus"       image_disabled_selected="Object_Torus" -     image_selected="Object_Torus" +     image_selected="Object_Torus_Selected"       image_unselected="Object_Torus"       layout="topleft"       left="4" @@ -487,7 +487,7 @@       height="20"       image_disabled="Object_Tube"       image_disabled_selected="Object_Tube" -     image_selected="Object_Tube" +     image_selected="Object_Tube_Selected"       image_unselected="Object_Tube"       layout="topleft"       left_delta="26" @@ -500,7 +500,7 @@       height="20"       image_disabled="Object_Ring"       image_disabled_selected="Object_Ring" -     image_selected="Object_Ring" +     image_selected="Object_Ring_Selected"       image_unselected="Object_Ring"       layout="topleft"       left_delta="26" @@ -513,7 +513,7 @@       height="20"       image_disabled="Object_Tree"       image_disabled_selected="Object_Tree" -     image_selected="Object_Tree" +     image_selected="Object_Tree_Selected"       image_unselected="Object_Tree"       layout="topleft"       left_delta="26" @@ -526,8 +526,9 @@       height="20"       image_disabled="Object_Grass"       image_disabled_selected="Object_Grass" -     image_selected="Object_Grass" +     image_selected="Object_Grass_Selected"       image_unselected="Object_Grass" +     image_overlay_color="Red"       layout="topleft"       left_delta="26"       name="ToolGrass" diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml index 805ffbae66..d03a7e3d41 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml @@ -78,6 +78,9 @@       name="Pay">          <menu_item_call.on_click           function="Avatar.Pay" /> +        <menu_item_call.on_enable +         function="ParticipantList.EnableItem" +         parameter="can_pay" />      </menu_item_call>          <menu_item_separator           layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/panel_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml index 39c4923f12..89d632c4c6 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_header.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml @@ -21,19 +21,20 @@           width="18" />      <text_editor        allow_scroll="false" -      v_pad = "0" +      v_pad = "7"        read_only = "true"        follows="left|right"        font.style="BOLD" -      height="12" +      height="24"        layout="topleft"        left_pad="5"        right="-120"        name="user_name"        text_color="white"        bg_readonly_color="black" -      top="8" +      top="0"        use_ellipses="true" +      valign="bottom"         value="Ericag Vader" />      <text              font="SansSerifSmall" diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index 677bdbc3d2..31719aad20 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -18,6 +18,10 @@    name="type_pg">      General Content   </panel.string> + <panel.string +  name="l$_price"> +    L$[PRICE] + </panel.string>      <button       follows="top|right"       height="23" @@ -71,8 +75,11 @@           name="classified_snapshot"           top="20"           width="290" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" +         h_pad="0"           height="35"           width="290"           layout="topleft" @@ -81,35 +88,53 @@           left="10"           top_pad="10"           name="classified_name" +         read_only="true"           text_color="white" +         v_pad="0"           value="[name]"           use_ellipses="true" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top" +         h_pad="0"           height="25"           layout="topleft"           left="10"           name="classified_location" +         read_only="true"           width="290"           word_wrap="true" +         v_pad="0"           value="[loading...]" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" +         h_pad="0"           height="18"           layout="topleft"           left="10"           name="content_type" +         read_only="true"           width="290"           top_pad="5" +         v_pad="0"           value="[content type]" /> -        <text +        <text_editor +         allow_html="true" +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" +         h_pad="0"           height="18"           layout="topleft"           left="10"           name="category" +         read_only="true"           width="290"           top_pad="5" +         v_pad="0"           value="[category]" />          <check_box           enabled="false" @@ -119,26 +144,37 @@           left="10"           name="auto_renew"           top_pad="5" +         v_pad="0"           width="290" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top" +         h_pad="0"           halign="left"           height="16"           layout="topleft"           left="10"           name="price_for_listing" +         read_only="true"           top_pad="5"           tool_tip="Price for listing." -         width="105"> -         L$[PRICE] -        </text> -        <text +         v_pad="0" +         width="105" /> +        <text_editor +         allow_html="true" +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" +         h_pad="0"           height="200"           layout="topleft"           left="10" +         max_length="1023"           name="classified_desc" +         read_only="true"           width="290" +         v_pad="0"           value="[description]"           word_wrap="true" />      </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index 8f7750628e..2a2199fc87 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -255,13 +255,18 @@           top_pad="10"           value="My Account:"           width="100" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" -         height="15" +         h_pad="0" +         height="28"           layout="topleft"           left="10"           name="acc_status_text" +         read_only="true"           top_pad="5" +         v_pad="0"           value="Resident. No payment info on file."           width="200"           word_wrap="true" /> 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 f19057cae3..25a0213bde 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -495,6 +495,10 @@ things in this group. There's a broad variety of Abilities.           width="300">              <scroll_list.columns               label="" +             name="icon" +             width="2" /> +            <scroll_list.columns +             label=""               name="checkbox"               width="20" />              <scroll_list.columns diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml index 9279d1e686..c7e5b25e06 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -93,6 +93,7 @@               height="23"               label="Teleport"               name="teleport_btn" +             tool_tip = "Offer to teleport this person"               width="100" />          </layout_panel>          <layout_panel @@ -119,6 +120,23 @@           layout="topleft"           min_height="25"           width="100" +         name="share_btn_panel" +         user_resize="false"> +           <button +             auto_resize="true" +             follows="left|top|right" +             height="23" +             label="Pay" +             name="pay_btn" +             width="100" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="100"           name="call_btn_panel"           user_resize="false">              <button diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml index a0734d3dca..d519569543 100644 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml @@ -206,13 +206,18 @@               top_pad="10"               value="Resident Since:"               width="300" /> -            <text +            <text_editor +             allow_scroll="false" +             bg_visible="false"               follows="left|top" +             h_pad="0"               height="15"               layout="topleft"               left="10"               name="register_date" +             read_only="true"               translate="false" +             v_pad="0"               value="05/31/2376"               width="300"               word_wrap="true" /> @@ -238,19 +243,24 @@           top_delta="0"  	 value="Go to Dashboard"           width="100"/> --> -            <text +            <text_editor +            allow_scroll="false" +            bg_visible="false"              follows="left|top" +            h_pad="0"              height="28"              layout="topleft"              left="10"              name="acc_status_text" +            read_only="true"              top_pad="0"              translate="false" +            v_pad="0"              width="300"              word_wrap="true">                Resident. No payment info on file.                Linden. -            </text> +            </text_editor>              <text               follows="left|top"         font.style="BOLD" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 5fe5db892a..02eddc9212 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -39,8 +39,9 @@  	 layout="topleft"  	 name="navigation_panel"  	 width="600"> -	     <button +	     <pull_button  	     follows="left|top" +	     direction="down"  	     height="23"  	     image_overlay="Arrow_Left_Off"  	     layout="topleft" @@ -49,8 +50,9 @@  	     tool_tip="Go back to previous location"  	     top="2"  	     width="31" /> -	    <button +	    <pull_button  	     follows="left|top" +	     direction="down"  	     height="23"  	     image_overlay="Arrow_Right_Off"  	     layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index ac98bb9bd9..3b5add33a8 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -24,9 +24,6 @@ background_visible="true"       name="no_friends"       value="No friends" />      <string -     name="no_groups" -     value="No groups" /> -    <string       name="people_filter_label"       value="Filter People" />      <string @@ -163,6 +160,17 @@ background_visible="true"                           width="313" />                  </accordion_tab>              </accordion> +            <text +             follows="all" +             height="450" +             left="10" +             name="no_friends_msg" +             top="10" +             width="293" +             wrap="true"> +                To add friends try [secondlife:///app/search/people global search] or click on a user to add them as a friend. +If you're looking for people to hang out with, [secondlife:///app/worldmap try the Map]. +             </text>              <panel               follows="left|right|bottom"               height="30" @@ -226,6 +234,8 @@ background_visible="true"               layout="topleft"               left="0"               name="group_list" +             no_filtered_groups_msg="No groups" +             no_groups_msg="[secondlife:///app/search/groups Trying searching for some groups to join.]"               top="0"               width="313" />              <panel diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 7489988722..375f369ba7 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -61,8 +61,11 @@           name="pick_snapshot"           top="20"           width="280" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" +         h_pad="0"           height="35"           width="280"           layout="topleft" @@ -71,17 +74,24 @@           left="10"           top_pad="10"           name="pick_name" +         read_only="true"           text_color="white" +         v_pad="0"           value="[name]"           use_ellipses="true" /> -        <text +        <text_editor +         allow_scroll="false" +         bg_visible="false"           follows="left|top|right" +         h_pad="0"           height="25"           layout="topleft"           left="10"           name="pick_location" +         read_only="true"           width="280"           word_wrap="true" +         v_pad="0"           value="[loading...]" />          <text_editor           bg_readonly_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 9bfd8b91d8..c4e4b9aa9b 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -17,12 +17,13 @@ background_visible="true"       name="teleport_history_tab_title"       value="TELEPORT HISTORY" />      <filter_editor +     text_pad_left="14"       follows="left|top|right" -     font="SansSerif" +     font="SansSerifSmall"       height="23"       layout="topleft"       left="15" -     label="Filter Places" +     label="Filter My Places"       max_length="300"       name="Filter"       top="3" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 27461571da..351df22042 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -173,8 +173,7 @@                value="http://librarianavengers.org"                width="300"                word_wrap="false" -              use_ellipses="true" -         /> +              use_ellipses="true" />              <text               follows="left|top"             font.style="BOLD" @@ -186,13 +185,18 @@               top_pad="10"               value="Resident Since:"               width="300" /> -            <text +            <text_editor +             allow_scroll="false" +             bg_visible="false"               follows="left|top" +             h_pad="0"               height="15"               layout="topleft"               left="10"               name="register_date" +             read_only="true"               translate="false" +             v_pad="0"               value="05/31/2376"               width="300"               word_wrap="true" /> @@ -218,19 +222,24 @@           top_delta="0"  	 value="Go to Dashboard"           width="100"/> --> -            <text +            <text_editor +             allow_scroll="false" +             bg_visible="false"               follows="left|top" +             h_pad="0"               height="28"               layout="topleft"               left="10"               name="acc_status_text" +             read_only="true"               top_pad="0"               translate="false" +             v_pad="0"               width="300"               word_wrap="true">                Resident. No payment info on file.                Linden. -            </text> +            </text_editor>              <text               follows="left|top"         font.style="BOLD" @@ -306,7 +315,7 @@           name="add_friend"           tool_tip="Offer friendship to the Resident"           top="5" -         width="81" /> +         width="80" />          <button           follows="bottom|left"           height="23" @@ -316,7 +325,7 @@           tool_tip="Open instant message session"           top="5"           left_pad="3" -         width="45" /> +         width="39" />          <button           follows="bottom|left"           height="23" @@ -326,7 +335,7 @@           tool_tip="Call this Resident"           left_pad="3"           top="5" -         width="46" /> +         width="43" />          <button           enabled="false"           follows="bottom|left" @@ -337,7 +346,7 @@           tool_tip="Show the Resident on the map"           top="5"           left_pad="3" -         width="46" /> +         width="41" />          <button           follows="bottom|left"           height="23" @@ -347,8 +356,8 @@           tool_tip="Offer teleport"           left_pad="3"           top="5" -         width="78" /> -       <!-- <button +         width="69" /> +        <button           follows="bottom|right"           height="23"           label="▼" @@ -357,8 +366,8 @@           tool_tip="Pay money to or share inventory with the Resident"           right="-1"           top="5" -	 left_pad="3" -         width="23" />--> +	 	 left_pad="3" +         width="23" />          </layout_panel>        <layout_panel           follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml index d98f690339..629d8567d1 100644 --- a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml +++ b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml @@ -9,7 +9,44 @@   name="script_limits_my_avatar_panel"   top="0"   width="480"> -    <text +	<text +	 type="string" +	 length="1" +	 follows="left|top" +	 height="16" +	 layout="topleft" +	 left="10" +	 name="script_memory" +	 top_pad="24" +	 text_color="White" +	 width="480"> +		Avatar Script Usage +	</text> +	<text +	 type="string" +	 length="1" +	 follows="left|top" +	 height="16" +	 layout="topleft" +	 left="30" +	 name="memory_used" +	 top_delta="18" +	 width="480"> + +	</text> +	<text +	 type="string" +	 length="1" +	 follows="left|top" +	 height="16" +	 layout="topleft" +	 left="30" +	 name="urls_used" +	 top_delta="18" +	 width="480"> + +	</text> +	<text       type="string"       length="1"       follows="left|top" @@ -17,7 +54,7 @@       layout="topleft"       left="10"       name="loading_text" -     top="10" +     top="80"       text_color="EmphasisColor"       width="480">          Loading... @@ -25,12 +62,12 @@      <scroll_list       draw_heading="true"       follows="all" -     height="500" +     height="415"       layout="topleft"       left_delta="0"       multi_select="true"       name="scripts_list" -     top_delta="17" +     top="100"       width="460">          <scroll_list.columns           label="Size (kb)" diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml index 0fa3c1cf2e..9dff00fa0b 100644 --- a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml +++ b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml @@ -33,7 +33,7 @@  	 top_delta="18"  	 visible="true"  	 width="480"> -		Parcels Owned: +	   	</text>  	<text  	 type="string" @@ -45,7 +45,19 @@  	 name="memory_used"  	 top_delta="18"  	 width="480"> -		Memory used: +	</text> +	 +	<text +	 type="string" +	 length="1" +	 follows="left|top" +	 height="16" +	 layout="topleft" +	 left="30" +	 name="urls_used" +	 top_delta="18" +	 width="480"> +	   	</text>  	<text       type="string" @@ -55,7 +67,7 @@       layout="topleft"       left="10"       name="loading_text" -     top_delta="32" +     top_delta="12"       text_color="EmphasisColor"       width="480">          Loading... @@ -73,7 +85,11 @@          <scroll_list.columns           label="Size (kb)"           name="size" -         width="70" /> +         width="72" /> +        <scroll_list.columns +         label="URLs" +         name="urls" +         width="48" />          <scroll_list.columns           label="Object Name"           name="name" @@ -83,11 +99,13 @@           name="owner"           width="100" />          <scroll_list.columns -         label="Parcel / Location" -         name="location" +         label="Parcel" +         name="parcel"           width="130" /> -<!--		<scroll_list.commit_callback -          function="TopObjects.CommitObjectsList" />--> +        <scroll_list.columns +         label="Location" +         name="location" +         width="80" />      </scroll_list>      <button       follows="bottom|left" @@ -102,8 +120,8 @@      <button       follows="bottom|right"       height="19" -	 visible="false"       label="Highlight" +	 visible="false"       layout="bottomright"       left="370"       name="highlight_btn" @@ -112,8 +130,8 @@      <button       follows="bottom|right"       height="19" -	 visible="false"       label="Return" +	 visible="false"       layout="bottomright"       name="return_btn"       top="34" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 750d151b7f..974159a850 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2060,6 +2060,7 @@ this texture in your inventory  	<string name="ScriptLimitsURLsUsed">URLs used: [COUNT] out of [MAX]; [AVAILABLE] available</string>  	<string name="ScriptLimitsURLsUsedSimple">URLs used: [COUNT]</string>  	<string name="ScriptLimitsRequestError">Error requesting information</string> +	<string name="ScriptLimitsRequestNoParcelSelected">No Parcel Selected</string>  	<string name="ScriptLimitsRequestWrongRegion">Error: script information is only available in your current region</string>  	<string name="ScriptLimitsRequestWaiting">Retrieving information...</string>  	<string name="ScriptLimitsRequestDontOwnParcel">You do not have permission to examine this parcel</string> diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml index f59c46b2f5..d9b6387f0d 100644 --- a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml +++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml @@ -2,10 +2,13 @@  <expandable_text   max_height="300" >   <textbox -   more_label="More"  +  allow_html="true" +  allow_scroll="true" +  bg_visible="false" +  more_label="More"     follows="left|top|right"    name="text" -   allow_scroll="true"  +  read_only="true"    use_ellipses="true"    word_wrap="true"    tab_stop="true" @@ -16,4 +19,4 @@    name="scroll"    follows="all"   /> -</expandable_text>
\ No newline at end of file +</expandable_text> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index 70a58b8e03..2163660206 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -96,7 +96,7 @@      name="damage_icon"      width="14"      height="13" -    top="21" +    top="19"      left="2"      follows="right|top"      image_name="Parcel_Damage_Dark" @@ -106,7 +106,7 @@      name="damage_text"  	width="35"  	height="18" -	top="16" +	top="17"      follows="right|top"  	halign="right"  	font="SansSerifSmall" | 
