diff options
Diffstat (limited to 'indra')
88 files changed, 3184 insertions, 541 deletions
| diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 2b4d8ed831..64af6c94f5 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -100,7 +100,7 @@ public:  	BOOL getIsLinkType() const;  	// mutators - will not call updateServer();  	void setUUID(const LLUUID& new_uuid); -	void rename(const std::string& new_name); +	virtual void rename(const std::string& new_name);  	void setParent(const LLUUID& new_parent);  	void setType(LLAssetType::EType type); diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 99f364a589..45573cd817 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -105,7 +105,7 @@ bool removeSubString(std::string& str, const std::string& substr)  	size_t pos = str.find(substr);  	if (pos != string::npos)  	{ -		str.erase(pos); +		str.erase(pos, substr.size());  		return true;  	}  	return false; diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 790f2d5729..95d693cdc4 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -34,6 +34,8 @@ set(llui_SOURCE_FILES      llconsole.cpp      llcontainerview.cpp      llctrlselectioninterface.cpp +    lldockablefloater.cpp +    lldockcontrol.cpp      lldraghandle.cpp      lleditmenuhandler.cpp      llf32uictrl.cpp @@ -113,6 +115,8 @@ set(llui_HEADER_FILES      llcontainerview.h      llctrlselectioninterface.h      lldraghandle.h +    lldockablefloater.h +    lldockcontrol.h      lleditmenuhandler.h      llf32uictrl.h      llfiltereditor.h  diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 98e8c9a988..bf58e19949 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -355,11 +355,19 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)  			setFocus(TRUE);  		} +		/* +		 * ATTENTION! This call fires another mouse down callback. +		 * If you wish to remove this call emit that signal directly +		 * by calling LLUICtrl::mMouseDownSignal(x, y, mask); +		 */ +		LLUICtrl::handleMouseDown(x, y, mask); +  		mMouseDownSignal(this, LLSD());  		mMouseDownTimer.start();  		mMouseDownFrame = (S32) LLFrameTimer::getFrameCount();  		mMouseHeldDownCount = 0; +  		if (getSoundFlags() & MOUSE_DOWN)  		{ @@ -378,6 +386,13 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)  		// Always release the mouse  		gFocusMgr.setMouseCapture( NULL ); +		/* +		 * ATTENTION! This call fires another mouse up callback. +		 * If you wish to remove this call emit that signal directly +		 * by calling LLUICtrl::mMouseUpSignal(x, y, mask); +		 */ +		LLUICtrl::handleMouseUp(x, y, mask); +  		// Regardless of where mouseup occurs, handle callback  		mMouseUpSignal(this, LLSD()); @@ -460,12 +475,16 @@ BOOL	LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)  void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)  { +	LLUICtrl::onMouseEnter(x, y, mask); +  	if (isInEnabledChain())  		mNeedsHighlight = TRUE;  }  void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)  { +	LLUICtrl::onMouseLeave(x, y, mask); +  	mNeedsHighlight = FALSE;  } diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp new file mode 100644 index 0000000000..d0789d6502 --- /dev/null +++ b/indra/llui/lldockablefloater.cpp @@ -0,0 +1,86 @@ +/**  + * @file lldockablefloater.cpp + * @brief Creates a panel of a specific kind for a toast + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + *  + * Copyright (c) 2000-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "lldockablefloater.h" + +LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, +		const LLSD& key, const Params& params) : +	LLFloater(key, params), mDockControl(dockControl) +{ +} + +LLDockableFloater::~LLDockableFloater() +{ +} + +BOOL LLDockableFloater::postBuild() +{ +	mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); +	LLFloater::setDocked(true); +	return LLView::postBuild(); +} + +void LLDockableFloater::setDocked(bool docked, bool pop_on_undock) +{ +	if (docked) +	{ +		mDockControl.get()->on(); +	} +	else +	{ +		mDockControl.get()->off(); +	} +	LLFloater::setDocked(docked, pop_on_undock); +} + +void LLDockableFloater::draw() +{ +	mDockControl.get()->repositionDockable(); +	mDockControl.get()->drawToungue(); +	LLFloater::draw(); +} + +void LLDockableFloater::setDockControl(LLDockControl* dockControl) +{ +	mDockControl.reset(dockControl); +} +const LLUIImagePtr& LLDockableFloater::getDockTongue() +{ +	return mDockTongue; +} + +LLDockControl* LLDockableFloater::getDockControl() +{ +	return mDockControl.get(); +} diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h new file mode 100644 index 0000000000..5ece78a925 --- /dev/null +++ b/indra/llui/lldockablefloater.h @@ -0,0 +1,65 @@ +/**  + * @file lldockablefloater.h + * @brief Creates a panel of a specific kind for a toast. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + *  + * Copyright (c) 2003-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_DOCKABLEFLOATER_H +#define LL_DOCKABLEFLOATER_H + +#include "llerror.h" +#include "llfloater.h" +#include "lldockcontrol.h" + +/** + * Represents floater that can dock. + * In case impossibility deriving from LLDockableFloater use LLDockControl. + */ +class LLDockableFloater : public LLFloater +{ +public: +	LOG_CLASS(LLDockableFloater); +	LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params = getDefaultParams()); +	virtual ~LLDockableFloater(); + +	/* virtula */BOOL postBuild(); +	/* virtual */void setDocked(bool docked, bool pop_on_undock = true); +	/* virtual */void draw(); + +protected: +	void setDockControl(LLDockControl* dockControl); +	LLDockControl* getDockControl(); +	const LLUIImagePtr& getDockTongue(); + +private: +	std::auto_ptr<LLDockControl> mDockControl; +	LLUIImagePtr mDockTongue; +}; + +#endif /* LL_DOCKABLEFLOATER_H */ diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp new file mode 100644 index 0000000000..bec7f04cc0 --- /dev/null +++ b/indra/llui/lldockcontrol.cpp @@ -0,0 +1,126 @@ +/**  + * @file lldockcontrol.cpp + * @brief Creates a panel of a specific kind for a toast + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + *  + * Copyright (c) 2000-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "lldockcontrol.h" + +LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, +		const LLUIImagePtr& dockTongue, DocAt dockAt, bool enabled) : +	mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue( +			dockTongue) +{ +	mDockAt = dockAt; +	if (enabled) +	{ +		on(); +	} +	else +	{ +		off(); +	} +} + +LLDockControl::~LLDockControl() +{ +} + +void LLDockControl::repositionDockable() +{ +	if (mEnabled) +	{ +		calculateDockablePosition(); +	} +} + +void LLDockControl::calculateDockablePosition() +{ +	LLRect dockRect = mDockWidget->calcScreenRect(); +	if (mPrevDockRect != dockRect || mRecalculateDocablePosition) +	{ +		LLRect dockableRect = mDockableFloater->calcScreenRect(); +		LLRect rootRect = mDockableFloater->getRootView()->getRect(); + +		S32 x = 0; +		S32 y = 0; +		switch (mDockAt) +		{ +		case TOP: +			x = dockRect.getCenterX() - dockableRect.getWidth() / 2; +			y = dockRect.mTop + mDockTongue->getHeight() +					+ dockableRect.getHeight(); +			if (x < rootRect.mLeft) +			{ +				x = rootRect.mLeft; +			} +			if (x + dockableRect.getWidth() > rootRect.mRight) +			{ +				x = rootRect.mRight - dockableRect.getWidth(); +			} +			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2; +			mDockTongueY = dockRect.mTop; +			break; +		} +		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), +				dockableRect.getHeight()); +		LLRect localDocableParentRect; +		mDockableFloater->getParent()->screenRectToLocal(dockableRect, +				&localDocableParentRect); +		mDockableFloater->setRect(localDocableParentRect); + +		mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, +				&mDockTongueX, &mDockTongueY); +		mPrevDockRect = dockRect; +		mRecalculateDocablePosition = false; +	} +} + +void LLDockControl::on() +{ +	mDockableFloater->setCanDrag(false); +	mEnabled = true; +	mRecalculateDocablePosition = true; +} + +void LLDockControl::off() +{ +	mDockableFloater->setCanDrag(true); +	mEnabled = false; +} + +void LLDockControl::drawToungue() +{ +	if (mEnabled) +	{ +		mDockTongue->draw(mDockTongueX, mDockTongueY); +	} +} diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h new file mode 100644 index 0000000000..0e1f4c8e64 --- /dev/null +++ b/indra/llui/lldockcontrol.h @@ -0,0 +1,81 @@ +/**  + * @file lldockcontrol.h + * @brief Creates a panel of a specific kind for a toast. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + *  + * Copyright (c) 2003-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_DOCKCONTROL_H +#define LL_DOCKCONTROL_H + +#include "llerror.h" +#include "llview.h" +#include "llfloater.h" +#include "lluiimage.h" + +/** + * Provides services for docking of specified floater. + * This class should be used in case impossibility deriving from LLDockableFloater. + */ +class LLDockControl +{ +public: +	enum DocAt +	{ +		TOP +	}; + +public: +	LOG_CLASS(LLDockControl); +	LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, +			const LLUIImagePtr& dockTongue, DocAt dockAt, +			bool enabled); +	virtual ~LLDockControl(); + +public: +	void on(); +	void off(); +	void setDock(LLView* dockWidget) +	{	mDockWidget = dockWidget;}; +	void repositionDockable(); +	void drawToungue(); +protected: +	virtual void calculateDockablePosition(); +private: +	bool mEnabled; +	bool mRecalculateDocablePosition; +	DocAt mDockAt; +	LLView* mDockWidget; +	LLRect mPrevDockRect; +	LLFloater* mDockableFloater; +	LLUIImagePtr mDockTongue; +	S32 mDockTongueX; +	S32 mDockTongueY; +}; + +#endif /* LL_DOCKCONTROL_H */ diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index b9a253aac8..36a3b007b6 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -123,6 +123,7 @@ LLScrollListCtrl::Params::Params()  	sort_ascending("sort_ascending", true),  	commit_on_keyboard_movement("commit_on_keyboard_movement", true),  	heading_height("heading_height"), +	page_lines("page_lines", 0),  	background_visible("background_visible"),  	draw_stripes("draw_stripes"),  	column_padding("column_padding"), @@ -145,7 +146,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  :	LLUICtrl(p),  	mLineHeight(0),  	mScrollLines(0), -	mPageLines(0), +	mPageLines(p.page_lines),  	mMaxSelectable(0),  	mAllowKeyboardMovement(TRUE),  	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement), @@ -196,8 +197,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  	updateLineHeight(); -	mPageLines = mLineHeight? (mItemListRect.getHeight()) / mLineHeight : 0; -  	// Init the scrollbar  	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); @@ -214,7 +213,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  	sbparams.orientation(LLScrollbar::VERTICAL);  	sbparams.doc_size(getItemCount());  	sbparams.doc_pos(mScrollLines); -	sbparams.page_size(mPageLines); +	sbparams.page_size( mPageLines ? mPageLines : getItemCount() );  	sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));  	sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);  	sbparams.visible(false); @@ -469,8 +468,12 @@ void LLScrollListCtrl::updateLayout()  	getChildView("comment_text")->setShape(mItemListRect);  	// how many lines of content in a single "page" -	mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; -	BOOL scrollbar_visible = getItemCount() > mPageLines; +	S32 page_lines =  mLineHeight? mItemListRect.getHeight() / mLineHeight : getItemCount(); +	//if mPageLines is NOT provided display all item +	if(mPageLines) +		page_lines = mPageLines; + +	BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight();  	if (scrollbar_visible)  	{  		// provide space on the right for scrollbar @@ -479,7 +482,7 @@ void LLScrollListCtrl::updateLayout()  	mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - scrollbar_size, mItemListRect.mBottom);  	mScrollbar->reshape(scrollbar_size, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); -	mScrollbar->setPageSize( mPageLines ); +	mScrollbar->setPageSize(page_lines);  	mScrollbar->setDocSize( getItemCount() );  	mScrollbar->setVisible(scrollbar_visible); @@ -491,6 +494,9 @@ void LLScrollListCtrl::updateLayout()  void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height)  {  	S32 height = llmin( getRequiredRect().getHeight(), max_height ); +	if(mPageLines) +		height = llmin( mPageLines * mLineHeight + (mDisplayColumnHeaders ? mHeadingHeight : 0), height ); +  	S32 width = getRect().getWidth();  	reshape( width, height ); @@ -721,6 +727,12 @@ void LLScrollListCtrl::setHeadingHeight(S32 heading_height)  	updateLayout();  } +void LLScrollListCtrl::setPageLines(S32 new_page_lines) +{ +	mPageLines  = new_page_lines; +	 +	updateLayout(); +}  BOOL LLScrollListCtrl::selectFirstItem()  { @@ -1367,7 +1379,7 @@ void LLScrollListCtrl::drawItems()  	S32 y = mItemListRect.mTop - mLineHeight;  	// allow for partial line at bottom -	S32 num_page_lines = mPageLines + 1; +	S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;  	LLRect item_rect; @@ -1856,7 +1868,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y )  		mLineHeight );  	// allow for partial line at bottom -	S32 num_page_lines = mPageLines + 1; +	S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;  	S32 line = 0;  	item_list::iterator iter; @@ -2421,7 +2433,8 @@ void LLScrollListCtrl::scrollToShowSelected()  	}  	S32 lowest = mScrollLines; -	S32 highest = mScrollLines + mPageLines; +	S32 page_lines = (mPageLines)? mPageLines : getItemCount(); +	S32 highest = mScrollLines + page_lines;  	if (index < lowest)  	{ @@ -2430,7 +2443,7 @@ void LLScrollListCtrl::scrollToShowSelected()  	}  	else if (highest <= index)  	{ -		setScrollPos(index - mPageLines + 1); +		setScrollPos(index - page_lines + 1);  	}  } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 7a7e5be0be..5c18f85160 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -87,6 +87,7 @@ public:  		// layout  		Optional<S32>	column_padding, +							page_lines,  						heading_height;  		// sort and search behavior @@ -314,6 +315,11 @@ public:  	S32 getMaxContentWidth() { return mMaxContentWidth; }  	void setHeadingHeight(S32 heading_height); +	/** +	 * Sets  max visible  lines without scroolbar, if this value equals to 0, +	 * then display all items. +	 */ +	void setPageLines(S32 page_lines );  	void setCollapseEmptyColumns(BOOL collapse);  	LLScrollListItem*	hitItem(S32 x,S32 y); @@ -368,11 +374,13 @@ protected:  	typedef std::deque<LLScrollListItem *> item_list;  	item_list&		getItemList() { return mItemList; } +	void			updateLineHeight(); +  private:  	void			selectPrevItem(BOOL extend_selection);  	void			selectNextItem(BOOL extend_selection);  	void			drawItems(); -	void			updateLineHeight(); +	  	void            updateLineHeightInsert(LLScrollListItem* item);  	void			reportInvalidInput();  	BOOL			isRepeatedChars(const LLWString& string) const; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 7a92bfb74c..30bf182deb 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -481,7 +481,10 @@ void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& c  								 mShadowType,  								 line_length, getRect().getWidth(), NULL, mUseEllipses );  			cur_pos += line_length + 1; -			y -= llfloor(mDefaultFont->getLineHeight()) + mLineSpacing; +			S32 line_height = llfloor(mDefaultFont->getLineHeight()) + mLineSpacing;  +			y -= line_height; +			if(y < line_height) +				break;  		}  	}  } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 296ccea0e4..51c259ff53 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -3412,11 +3412,8 @@ void LLTextEditor::endOfDoc()  // Sets the scrollbar from the cursor position  void LLTextEditor::updateScrollFromCursor()  { -	if (mReadOnly) -	{ -		// no cursor in read only mode -		return; -	} +	// Update scroll position even in read-only mode (when there's no cursor displayed) +	// because startOfDoc()/endOfDoc() modify cursor position. See EXT-736.  	if (!mScrollNeeded)  	{ diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 83d45f0dfa..55d94b325f 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -2741,11 +2741,11 @@ void	LLView::notifyParent(const LLSD& info)  	if(parent)  		parent->notifyParent(info);  } -void	LLView::notifyChilds(const LLSD& info) +void	LLView::notifyChildren(const LLSD& info)  {  	for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)  	{ -		(*child_it)->notifyChilds(info); +		(*child_it)->notifyChildren(info);  	}  } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 87298b5292..1d48378081 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -550,7 +550,7 @@ public:  	virtual void	handleReshape(const LLRect& rect, bool by_user);  	virtual void	notifyParent(const LLSD& info); -	virtual void	notifyChilds(const LLSD& info); +	virtual void	notifyChildren(const LLSD& info);  protected:  	void			drawDebugRect(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 05459cfcac..f4194ed511 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -180,7 +180,6 @@ set(viewer_SOURCE_FILES      llfloaterlandholdings.cpp      llfloatermap.cpp      llfloatermemleak.cpp -    llfloatermute.cpp      llfloaternamedesc.cpp      llfloaternotificationsconsole.cpp      llfloateropenobject.cpp @@ -286,6 +285,7 @@ set(viewer_SOURCE_FILES      llpanelavatar.cpp      llpanelavatarrow.cpp      llpanelavatartag.cpp +    llpanelblockedlist.cpp      llpanelclassified.cpp      llpanelcontents.cpp      llpaneldirbrowser.cpp @@ -348,6 +348,8 @@ set(viewer_SOURCE_FILES      llremoteparcelrequest.cpp      llsavedsettingsglue.cpp      llscreenchannel.cpp +    llsearchcombobox.cpp +    llsearchhistory.cpp      llselectmgr.cpp      llsidetray.cpp      llsidetraypanelcontainer.cpp @@ -634,7 +636,6 @@ set(viewer_HEADER_FILES      llfloaterlandholdings.h      llfloatermap.h      llfloatermemleak.h -    llfloatermute.h      llfloaternamedesc.h      llfloaternotificationsconsole.h      llfloateropenobject.h @@ -738,6 +739,7 @@ set(viewer_HEADER_FILES      llpanelavatar.h      llpanelavatarrow.h      llpanelavatartag.h +    llpanelblockedlist.h      llpanelclassified.h      llpanelcontents.h      llpaneldirbrowser.h @@ -802,6 +804,8 @@ set(viewer_HEADER_FILES      llrootview.h      llscreenchannel.h      llsavedsettingsglue.h +    llsearchcombobox.h +    llsearchhistory.h      llselectmgr.h      llsidetray.h      llsidetraypanelcontainer.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e88bc5a91f..32b1443157 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6866,10 +6866,10 @@        <key>Value</key>        <integer>0</integer>      </map>     -    <key>ShowPGSearchAll</key>     +    <key>ShowCameraAndMoveControls</key>                      <map>        <key>Comment</key> -      <string>Show/Hide Navigation Bar Favorites Panel</string> +      <string>Show/Hide Camera and Move controls in the bottom tray</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -6880,7 +6880,7 @@      <key>ShowNavbarFavoritesPanel</key>          <map>        <key>Comment</key> -      <string>Show/Hide Navigation Bar Navigation Panel</string> +      <string>Show/Hide Navigation Bar Favorites Panel</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -6891,6 +6891,17 @@      <key>ShowNavbarNavigationPanel</key>              <map>        <key>Comment</key> +      <string>Show/Hide Navigation Bar Navigation Panel</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer>    +    </map> +    <key>ShowPGSearchAll</key>     +    <map> +      <key>Comment</key>        <string>Display results of search All that are flagged as PG</string>        <key>Persist</key>        <integer>1</integer> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index e1747930b0..08681db6cb 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -47,7 +47,6 @@  #include "llfloaterdirectory.h"  #include "llfloaterland.h" -#include "llfloatermute.h"  #include "llfloatersnapshot.h"  #include "llfloatertools.h"  #include "llfloaterworldmap.h" diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index e0322e26b9..a121d327f7 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -223,12 +223,13 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str  #endif  	setScrollPos(pos); +	updateLineHeight();  	LLRect	rect = getRequiredRect();  	LLSD params;  	params["action"] = "size_changes";  	params["width"] = rect.getWidth(); -	params["height"] = rect.getHeight(); +	params["height"] = llmax(rect.getHeight(),20) + 5;  	getParent()->notifyParent(params); diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index fe13d4f652..861f23abb7 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -60,7 +60,6 @@ LLBottomTray::LLBottomTray(const LLSD&)  	mSysWell = getChild<LLNotificationChiclet>("sys_well");  	mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window")); -	LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")->setSysWell(mSysWell);  	mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); @@ -80,8 +79,16 @@ LLBottomTray::LLBottomTray(const LLSD&)  BOOL LLBottomTray::postBuild()  { +	mCommitCallbackRegistrar.add("ShowCamMoveCtrls.Action", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked, this, _2)); +	mEnableCallbackRegistrar.add("ShowCamMoveCtrls.EnableMenuItem", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled, this, _2)); + +	mShowCamMoveCtrlsContextMenu =  LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_camera_move_controls.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	gMenuHolder->addChild(mShowCamMoveCtrlsContextMenu); +  	mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");  	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); +	mMovementPanel = getChild<LLPanel>("movement_panel"); +	mCamPanel = getChild<LLPanel>("cam_panel");  	return TRUE;  } @@ -205,8 +212,9 @@ void LLBottomTray::setVisible(BOOL visible)  			child_it != mToolbarStack->getChildList()->end(); child_it++)  		{  			LLView* viewp = *child_it; +			std::string name = viewp->getName(); -			if ("chat_bar" == viewp->getName()) +			if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name)  				continue;  			else   			{ @@ -216,3 +224,45 @@ void LLBottomTray::setVisible(BOOL visible)  	}  } +BOOL LLBottomTray::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ +	if (mShowCamMoveCtrlsContextMenu) +	{ +		mShowCamMoveCtrlsContextMenu->buildDrawLabels(); +		mShowCamMoveCtrlsContextMenu->updateParent(LLMenuGL::sMenuContainer); +		LLMenuGL::showPopup(this, mShowCamMoveCtrlsContextMenu, x, y); +	} + +	return TRUE; +} + +bool LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata) +{ +	std::string item = userdata.asString(); + +	if (item == "show_camera_move_controls") +	{ +		return gSavedSettings.getBOOL("ShowCameraAndMoveControls"); +	} + +	return FALSE; +} + +void LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata) +{ +	std::string item = userdata.asString(); + +	if (item == "show_camera_move_controls") +	{ +		BOOL state = !gSavedSettings.getBOOL("ShowCameraAndMoveControls"); + +		showCameraAndMoveControls(state); +		gSavedSettings.setBOOL("ShowCameraAndMoveControls", state); +	} +} + +void LLBottomTray::showCameraAndMoveControls(BOOL visible) +{ +	mCamPanel->setVisible(visible); +	mMovementPanel->setVisible(visible); +} diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index a8fe65a9d3..c3c840ede0 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -33,6 +33,8 @@  #ifndef LL_LLBOTTOMPANEL_H  #define LL_LLBOTTOMPANEL_H +#include <llmenugl.h> +  #include "llpanel.h"  #include "llimview.h" @@ -68,6 +70,10 @@ public:  	virtual void onFocusLost();  	virtual void setVisible(BOOL visible); +	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + +	void showCameraAndMoveControls(BOOL visible); +  private:  protected: @@ -76,6 +82,9 @@ protected:  	void onChicletClick(LLUICtrl* ctrl); +	bool onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata); +	void onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata); +  	static void* createNearbyChatBar(void* userdata);  	/** @@ -88,7 +97,9 @@ protected:  	LLTalkButton* 		mTalkBtn;  	LLNearbyChatBar*	mNearbyChatBar;  	LLLayoutStack*		mToolbarStack; - +	LLMenuGL*			mShowCamMoveCtrlsContextMenu; +	LLPanel*			mMovementPanel; +	LLPanel*			mCamPanel;  };  #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 1109d8174f..808fcde312 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -117,6 +117,10 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback(  	return mButton->setClickedCallback(cb);  } +void LLNotificationChiclet::setToggleState(BOOL toggled) { +	mButton->setToggleState(toggled); +} +  void LLNotificationChiclet::updateUreadIMNotifications()  {  	mUreadIMNotifications = gIMMgr->getNumberOfUnreadIM(); @@ -235,6 +239,7 @@ LLIMP2PChiclet::Params::Params()  	avatar_icon.name("avatar_icon");  	avatar_icon.rect(LLRect(0, 25, 25, 0)); +	avatar_icon.mouse_opaque(false);  	unread_notifications.name("unread");  	unread_notifications.rect(LLRect(25, 25, 45, 0)); @@ -242,6 +247,7 @@ LLIMP2PChiclet::Params::Params()  	unread_notifications.font_halign(LLFontGL::HCENTER);  	unread_notifications.v_pad(5);  	unread_notifications.text_color(LLColor4::white); +	unread_notifications.mouse_opaque(false);  	speaker.name("speaker");  	speaker.rect(LLRect(45, 25, 65, 0)); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index ba202515a8..f96dfb69ec 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -537,6 +537,7 @@ public:  	void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications + mUreadIMNotifications); }  	void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications + mUreadIMNotifications); }  	void updateUreadIMNotifications(); +	void setToggleState(BOOL toggled);  protected:  	LLNotificationChiclet(const Params& p); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 7ad60232c7..a7f0a8ff9a 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -55,6 +55,7 @@  #include "llviewerinventory.h"  #include "llviewermenu.h"  #include "llviewermenu.h" +#include "lltooldraganddrop.h"  static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar"); @@ -73,6 +74,7 @@ public:  		, mLoaded(false) {}  	void setLandmarkID(const LLUUID& id) { mLandmarkID = id; } +	const LLUUID& getLandmarkId() const { return mLandmarkID; }  	const std::string& getSLURL()  	{ @@ -130,8 +132,21 @@ public:  		msg = mUrlGetter.getSLURL();  		return TRUE;  	} + +	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask) +	{ +		LLFavoritesBarCtrl* fb = dynamic_cast<LLFavoritesBarCtrl*>(getParent()); + +		if (fb) +		{ +			fb->handleHover(x, y, mask); +		} + +		return LLButton::handleHover(x, y, mask); +	}  	void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); } +	const LLUUID& getLandmarkId() const { return mUrlGetter.getLandmarkId(); }  protected:  	LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {} @@ -141,6 +156,33 @@ private:  	LLSLURLGetter mUrlGetter;  }; +class LLFavoritesToggleableMenu : public LLToggleableMenu +{ +public: +	virtual BOOL handleHover(S32 x, S32 y, MASK mask) +	{ +		if (fb) +		{ +			fb->handleHover(x, y, mask); +		} + +		return LLToggleableMenu::handleHover(x, y, mask); +	} + +	void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; } + +protected: +	LLFavoritesToggleableMenu(const LLToggleableMenu::Params& p): +		LLToggleableMenu(p) +	{ +	} + +	friend class LLUICtrlFactory; + +private: +	LLFavoritesBarCtrl* fb; +}; +  /**   * This class is needed to override LLMenuItemCallGL default handleToolTip function and   * show SLURL as button tooltip. @@ -164,6 +206,18 @@ public:  	void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); } +	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) +	{ +		mMouseDownSignal(this, x, y, mask); +		return LLMenuItemCallGL::handleMouseDown(x, y, mask); +	} + +	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) +	{ +		mMouseUpSignal(this, x, y, mask); +		return LLMenuItemCallGL::handleMouseUp(x, y, mask); +	} +  protected:  	LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p) {} @@ -181,6 +235,14 @@ struct LLFavoritesSort  	// TODO - made it customizible using gSavedSettings  	bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)  	{ +		S32 sortField1 = a->getSortField(); +		S32 sortField2 = b->getSortField(); + +		if (!(sortField1 < 0 && sortField2 < 0)) +		{ +			return sortField2 > sortField1; +		} +  		time_t first_create = a->getCreationDate();  		time_t second_create = b->getCreationDate();  		if (first_create == second_create) @@ -239,29 +301,34 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	case DAD_LANDMARK:  		{  			// Copy the item into the favorites folder (if it's not already there). -			LLInventoryItem *item = (LLInventoryItem *)cargo_data;			 -			LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); -			if (item->getParentUUID() == favorites_id) +			LLInventoryItem *item = (LLInventoryItem *)cargo_data; + +			// check if we are dragging an existing item from the favorites bar +			if (item && mDragItemId == item->getUUID())  			{ -				llwarns << "Attemt to copy a favorite item into the same folder." << llendl; -				break; +				*accept = ACCEPT_YES_SINGLE; + +				if (drop) +				{ +					handleExistingFavoriteDragAndDrop(x, y); +				}  			} +			else +			{ +				LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); +				if (item->getParentUUID() == favorites_id) +				{ +					llwarns << "Attemt to copy a favorite item into the same folder." << llendl; +					break; +				} -			*accept = ACCEPT_YES_COPY_SINGLE; +				*accept = ACCEPT_YES_COPY_SINGLE; -			if (drop) -			{ -				copy_inventory_item( -						gAgent.getID(), -						item->getPermissions().getOwner(), -						item->getUUID(), -						favorites_id, -						std::string(), -						LLPointer<LLInventoryCallback>(NULL)); - -				llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl; +				if (drop) +				{ +					handleNewFavoriteDragAndDrop(item, favorites_id, x, y); +				}  			} -			  		}  		break;  	default: @@ -271,6 +338,61 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	return TRUE;  } +void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) +{ +	LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y)); + +	if (dest) +	{ +		updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId()); +	} +	else +	{ +		mItems.push_back(gInventory.getItem(mDragItemId)); +	} + +	saveItemsOrder(mItems); + +	LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*) mPopupMenuHandle.get(); + +	if (menu && menu->getVisible()) +	{ +		menu->setVisible(FALSE); +		showDropDownMenu(); +	} + +	mDragItemId = LLUUID::null; +	getWindow()->setCursor(UI_CURSOR_ARROW); +} + +void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y) +{ +	LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y)); + +	if (dest) +	{ +		insertBeforeItem(mItems, dest->getLandmarkId(), item->getUUID()); +	} +	else +	{ +		mItems.push_back(gInventory.getItem(item->getUUID())); +	} + +	saveItemsOrder(mItems); + +	copy_inventory_item( +			gAgent.getID(), +			item->getPermissions().getOwner(), +			item->getUUID(), +			favorites_id, +			std::string(), +			LLPointer<LLInventoryCallback>(NULL)); + +	getWindow()->setCursor(UI_CURSOR_ARROW); + +	llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl; +} +  //virtual  void LLFavoritesBarCtrl::changed(U32 mask)  { @@ -311,9 +433,9 @@ LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode()  void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  { -	LLInventoryModel::item_array_t items; +	mItems.clear(); -	if (!collectFavoriteItems(items)) +	if (!collectFavoriteItems(mItems))  	{  		return;  	} @@ -331,7 +453,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  	const S32 buttonVGap = 2; -	S32 count = items.count(); +	S32 count = mItems.count();  	const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad");  	const S32 chevron_button_width = mFont->getWidth(">>") + buttonHPad * 2; @@ -369,7 +491,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  		S32 i;  		for (i = 0; i < mFirstDropDownItem; ++i)  		{ -			if (mItemNamesCache.get(i) != items.get(i)->getName()) +			if (mItemNamesCache.get(i) != mItems.get(i)->getName())  			{  				break;  			} @@ -387,7 +509,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  		mItemNamesCache.clear();  		for (S32 i = 0; i < mFirstDropDownItem; i++)  		{ -			mItemNamesCache.put(items.get(i)->getName()); +			mItemNamesCache.put(mItems.get(i)->getName());  		}  		// Rebuild the buttons only @@ -404,7 +526,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  			}  		} -		createButtons(items, buttonXMLNode, buttonWidth, buttonHGap); +		createButtons(mItems, buttonXMLNode, buttonWidth, buttonHGap);  	}  	// Chevron button @@ -467,9 +589,9 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite  {  	S32 curr_x = buttonHGap;  	// Adding buttons -	for(S32 i = mFirstDropDownItem -1; i >= 0; i--) +	for(S32 i = mFirstDropDownItem -1, j = 0; i >= 0; i--)  	{ -		LLInventoryItem* item = items.get(i); +		LLViewerInventoryItem* item = items.get(j++);  		LLFavoriteLandmarkButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);  		if (NULL == fav_btn) @@ -488,6 +610,10 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite  		fav_btn->setToolTip(item->getName());  		fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));  		fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 )); + +		fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); +		fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4)); +  		sendChildToBack(fav_btn);  		curr_x += buttonWidth + buttonHGap; @@ -521,6 +647,15 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it  	std::sort(items.begin(), items.end(), LLFavoritesSort()); +	if (needToSaveItemsOrder(items)) +	{ +		S32 sortField = 0; +		for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) +		{ +			(*i)->setSortField(++sortField); +		} +	} +  	return TRUE;  } @@ -528,7 +663,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()  {  	if (mPopupMenuHandle.isDead())  	{ -		LLToggleableMenu::Params menu_p; +		LLFavoritesToggleableMenu::Params menu_p;  		menu_p.name("favorites menu");  		menu_p.can_tear_off(false);  		menu_p.visible(false); @@ -536,26 +671,26 @@ void LLFavoritesBarCtrl::showDropDownMenu()  		menu_p.max_scrollable_items = 10;  		menu_p.preferred_width = DROP_DOWN_MENU_WIDTH; -		LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p); - +		LLFavoritesToggleableMenu* menu = LLUICtrlFactory::create<LLFavoritesToggleableMenu>(menu_p); +		menu->initFavoritesBarPointer(this);  		mPopupMenuHandle = menu->getHandle();  	} -	LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get(); +	LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*)mPopupMenuHandle.get();  	if(menu)  	{  		if (!menu->toggleVisibility())  			return; -		LLInventoryModel::item_array_t items; +		mItems.clear(); -		if (!collectFavoriteItems(items)) +		if (!collectFavoriteItems(mItems))  		{  			return;  		} -		S32 count = items.count(); +		S32 count = mItems.count();  		// Check it there are changed items, since last call  		if (mItemNamesCache.size() == count) @@ -563,7 +698,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()  			S32 i;  			for (i = mFirstDropDownItem; i < count; i++)  			{ -				if (mItemNamesCache.get(i) != items.get(i)->getName()) +				if (mItemNamesCache.get(i) != mItems.get(i)->getName())  				{  					break;  				} @@ -587,7 +722,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()  		{  			for (S32 i = mFirstDropDownItem; i < count; i++)  			{ -				mItemNamesCache.put(items.get(i)->getName()); +				mItemNamesCache.put(mItems.get(i)->getName());  			}  		} @@ -598,17 +733,18 @@ void LLFavoritesBarCtrl::showDropDownMenu()  		for(S32 i = mFirstDropDownItem; i < count; i++)  		{ -			LLInventoryItem* item = items.get(i); +			LLViewerInventoryItem* item = mItems.get(i);  			const std::string& item_name = item->getName(); -			LLMenuItemCallGL::Params item_params; +			LLFavoriteLandmarkMenuItem::Params item_params;  			item_params.name(item_name);  			item_params.label(item_name);  			item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));  			LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);  			menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4)); -			menu_item->setLandmarkID(item->getUUID()); +			menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); +			menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));  			// Check whether item name wider than menu  			if (menu_item->getNominalWidth() > max_width) @@ -644,13 +780,6 @@ void LLFavoritesBarCtrl::showDropDownMenu()  void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)  { -	LLInventoryModel::item_array_t items; - -	if (!collectFavoriteItems(items)) -	{ -		return; -	} -  	// We only have one Inventory, gInventory. Some day this should be better abstracted.  	LLInvFVBridgeAction::doAction(item_id,&gInventory);  } @@ -797,5 +926,135 @@ void LLFavoritesBarCtrl::pastFromClipboard() const  	}  } +void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +{ +	mDragItemId = id; +	mStartDrag = TRUE; + +	S32 screenX, screenY; +	localPointToScreen(x, y, &screenX, &screenY); + +	LLToolDragAndDrop::getInstance()->setDragStart(screenX, screenY); +} + +void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +{ +	mDragItemId = LLUUID::null; +} + +BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask) +{ +	if (mDragItemId != LLUUID::null && mStartDrag) +	{ +		S32 screenX, screenY; +		localPointToScreen(x, y, &screenX, &screenY); + +		if(LLToolDragAndDrop::getInstance()->isOverThreshold(screenX, screenY)) +		{ +			LLToolDragAndDrop::getInstance()->beginDrag( +				DAD_LANDMARK, mDragItemId, +				LLToolDragAndDrop::SOURCE_LIBRARY); + +			mStartDrag = FALSE; + +			return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask); +		} +	} + +	return TRUE; +} + +LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y) +{ +	LLUICtrl* ctrl = 0; +	S32 screenX, screenY; +	const child_list_t* list = getChildList(); + +	localPointToScreen(x, y, &screenX, &screenY); + +	// look for a child which contains the point (screenX, screenY) in it's rectangle +	for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i) +	{ +		LLRect rect; +		localRectToScreen((*i)->getRect(), &rect); + +		if (rect.pointInRect(screenX, screenY)) +		{ +			ctrl = dynamic_cast<LLUICtrl*>(*i); +			break; +		} +	} + +	return ctrl; +} + +BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array_t& items) +{ +	BOOL result = FALSE; + +	// if there is an item without sort order field set, we need to save items order +	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) +	{ +		if ((*i)->getSortField() < 0) +		{ +			result = TRUE; +			break; +		} +	} + +	return result; +} + +void LLFavoritesBarCtrl::saveItemsOrder(LLInventoryModel::item_array_t& items) +{ +	int sortField = 0; + +	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field +	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) +	{ +		LLViewerInventoryItem* item = *i; + +		item->setSortField(++sortField); +		item->setComplete(TRUE); +		item->updateServer(FALSE); + +		gInventory.updateItem(item); +	} + +	gInventory.notifyObservers(); +} + +LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) +{ +	LLInventoryModel::item_array_t::iterator result = items.end(); + +	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) +	{ +		if ((*i)->getUUID() == id) +		{ +			result = i; +			break; +		} +	} + +	return result; +} + +void LLFavoritesBarCtrl::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId) +{ +	LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId); +	LLViewerInventoryItem* destItem = gInventory.getItem(destItemId); + +	items.erase(findItemByUUID(items, srcItem->getUUID())); +	items.insert(findItemByUUID(items, destItem->getUUID()), srcItem); +} + +void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId) +{ +	LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId); +	LLViewerInventoryItem* insertedItem = gInventory.getItem(insertedItemId); + +	items.insert(findItemByUUID(items, beforeItem->getUUID()), insertedItem); +}  // EOF diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 824b396add..4cd92d1a58 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -60,6 +60,8 @@ public:  								   EAcceptance* accept,  								   std::string& tooltip_msg); +	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask); +  	// LLInventoryObserver observer trigger  	virtual void changed(U32 mask);  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -73,10 +75,12 @@ protected:  	void onButtonClick(LLUUID id);  	void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask); +	void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask); +	void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask); +  	void doToSelected(const LLSD& userdata);  	BOOL isClipboardPasteable() const;  	void pastFromClipboard() const; -  	void showDropDownMenu(); @@ -94,8 +98,49 @@ protected:  	LLRect mChevronRect;  	std::string mChevronButtonToolTip; + +private: +	/* +	 * Helper function to make code more readable. It handles all drag and drop +	 * operations of the existing favorites items on the favorites bar. +	 */ +	void handleExistingFavoriteDragAndDrop(S32 x, S32 y); + +	/* +	 * Helper function to make code more readable. It handles all drag and drop +	 * operations of the new landmark to the favorites bar. +	 */ +	void handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y); + +	// finds a control under the specified LOCAL point +	LLUICtrl* findChildByLocalCoords(S32 x, S32 y); + +	// checks if the current order of the favorites items must be saved +	BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items); + +	// saves current order of the favorites items +	void saveItemsOrder(LLInventoryModel::item_array_t& items); + +	/* +	 * changes favorites items order by insertion of the item identified by srcItemId +	 * BEFORE the item identified by destItemId. both items must exist in items array. +	 */ +	void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId); + +	/* +	 * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId. +	 * this function assumes that an item identified by insertedItemId doesn't exist in items array. +	 */ +	void insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId); + +	// finds an item by it's UUID in the items array +	LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id); + +	BOOL mSkipUpdate; +	BOOL mStartDrag; +	LLUUID mDragItemId; +	LLInventoryModel::item_array_t mItems;  };  #endif // LL_LLFAVORITESBARCTRL_H - diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 0dee3a1e83..14fb93df61 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -47,7 +47,6 @@  #include "llconsole.h"  #include "llfloateractivespeakers.h"  #include "llfloaterchatterbox.h" -#include "llfloatermute.h"  #include "llfloaterreg.h"  #include "llfloaterscriptdebug.h"  #include "llkeyboard.h" @@ -56,6 +55,7 @@  //#include "llresizehandle.h"  #include "llchatbar.h"  #include "llrecentpeople.h" +#include "llpanelblockedlist.h"  #include "llstatusbar.h"  #include "llviewertexteditor.h"  #include "llviewergesture.h"			// for triggering gestures @@ -280,7 +280,7 @@ void LLFloaterChat::onClickMute(void *data)  	LLMute mute(id);  	mute.setFromDisplayName(name);  	LLMuteList::getInstance()->add(mute); -	LLFloaterReg::showInstance("mute"); +	LLPanelBlockedList::showPanelAndSelect(mute.mID);  }  //static diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index c47c7b073c..d389cf06ec 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -61,6 +61,7 @@  #include "llnavigationbar.h"  #include "llpanellogin.h"  #include "llradiogroup.h" +#include "llsearchcombobox.h"  #include "llsky.h"  #include "llscrolllistctrl.h"  #include "llscrolllistitem.h" @@ -214,6 +215,11 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response  		// flag client texture cache for clearing next time the client runs  		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);  		LLNotifications::instance().add("CacheWillClear"); + +		LLSearchHistory::getInstance()->clearHistory(); +		LLSearchHistory::getInstance()->save(); +		LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box"); +		search_ctrl->clearHistory();  	}  	return false; diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index bef5f094e3..97b7f3e9ad 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -173,6 +173,15 @@ bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCateg  	return TRUE == gInventory.isObjectDescendentOf(cat->getUUID(), findFriendFolderUUIDImpl());  } +bool LLFriendCardsManager::isAnyFriendCategory(const LLUUID& catID) const +{ +	const LLUUID& friendFolderID = findFriendFolderUUIDImpl(); +	if (catID == friendFolderID) +		return true; + +	return TRUE == gInventory.isObjectDescendentOf(catID, friendFolderID); +} +  void LLFriendCardsManager::syncFriendsFolder()  {  	//lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" if they are absent @@ -305,10 +314,12 @@ void LLFriendCardsManager::findMatchedFriendCards(const LLUUID& avatarID, LLInve  	LLInventoryModel::cat_array_t cats;  	LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); -	LLParticularBuddyCollector matchFunctor(avatarID);  	LLViewerInventoryCategory* friendFolder = gInventory.getCategory(friendFolderUUID); +	if (NULL == friendFolder) +		return; +	LLParticularBuddyCollector matchFunctor(avatarID);  	LLInventoryModel::cat_array_t subFolders;  	subFolders.push_back(friendFolder); diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index 18a6d0ab69..aa391ce2c1 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -77,6 +77,11 @@ public:  	bool isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const;  	/** +	 *	Checks is the specified category is a Friend folder or any its subfolder +	 */ +	bool isAnyFriendCategory(const LLUUID& catID) const; + +	/**  	 *	Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List  	 */  	void syncFriendsFolder(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 789e628b67..adc73111e0 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2420,8 +2420,14 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,  										drop);  			break;  		case DAD_CATEGORY: -			accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, -											drop); +			if (LLFriendCardsManager::instance().isAnyFriendCategory(mUUID)) +			{ +				accept = FALSE; +			} +			else +			{ +				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop); +			}  			break;  		default:  			break; diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp index c83cde9d83..d910dbf718 100644 --- a/indra/newview/lllocationhistory.cpp +++ b/indra/newview/lllocationhistory.cpp @@ -37,59 +37,41 @@  #include <iomanip> // for std::setw()  #include "llui.h" - -const char LLLocationHistory::delimiter = '\t'; +#include "llsd.h" +#include "llsdserialize.h"  LLLocationHistory::LLLocationHistory() :  	mFilename("typed_locations.txt")  {  } -void LLLocationHistory::addItem(const std::string & item, const std::string & tooltip) { +void LLLocationHistory::addItem(const LLLocationHistoryItem& item) {  	static LLUICachedControl<S32> max_items("LocationHistoryMaxSize", 100);  	// check if this item doesn't duplicate any existing one -	std::vector<std::string>::iterator item_iter = std::find_if(mItems.begin(), mItems.end(), -			boost::bind(&LLLocationHistory::equalByRegionParcel,this,_1,item)); +	location_list_t::iterator item_iter = std::find(mItems.begin(), mItems.end(),item);  	if(item_iter != mItems.end()){ -	/*replace duplicate. -	 * If an item's region and item's parcel are  equal. -	 */ -		mToolTips.erase(*item_iter);  		mItems.erase(item_iter);	 -		  	}  	mItems.push_back(item); -	mToolTips[item] = tooltip; - +	  	// If the vector size exceeds the maximum, purge the oldest items.  	if ((S32)mItems.size() > max_items) { -		for(std::vector<std::string>::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) { -			mToolTips.erase(*i); -			mItems.erase(i); +		for(location_list_t::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) { +				mItems.erase(i);  		}  	}  } -/** - * check if the history item is equal. - * @return  true - if region name and parcel is equal.   +/* + * @brief Try to find item in history.  + * If item has been founded, it will be places into end of history. + * @return true - item has founded   */ -bool LLLocationHistory::equalByRegionParcel(const std::string& item, const std::string& newItem){ - -	 -	S32 itemIndex = item.find('('); -	S32 newItemIndex = newItem.find('('); -	 -	std::string region_parcel  = item.substr(0,itemIndex); -	std::string new_region_parcel  = newItem.substr(0,newItemIndex); -	 -	return region_parcel == new_region_parcel; -} -bool LLLocationHistory::touchItem(const std::string & item) { +bool LLLocationHistory::touchItem(const LLLocationHistoryItem& item) {  	bool result = false; -	std::vector<std::string>::iterator item_iter = std::find(mItems.begin(), mItems.end(), item); +	location_list_t::iterator item_iter = std::find(mItems.begin(), mItems.end(), item);  	// the last used item should be the first in the history  	if (item_iter != mItems.end()) { @@ -104,13 +86,6 @@ bool LLLocationHistory::touchItem(const std::string & item) {  void LLLocationHistory::removeItems()  {  	mItems.clear(); -	mToolTips.clear(); -} - -std::string LLLocationHistory::getToolTip(const std::string & item) const { -	std::map<std::string, std::string>::const_iterator i = mToolTips.find(item); - -	return i != mToolTips.end() ? i->second : "";  }  bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t& result) const @@ -123,7 +98,7 @@ bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t&  	for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)  	{ -		std::string haystack = *it; +		std::string haystack = it->getLocation();  		LLStringUtil::toLower(haystack);  		if (haystack.find(needle) != std::string::npos) @@ -139,7 +114,7 @@ void LLLocationHistory::dump() const  	int i = 0;  	for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it, ++i)  	{ -	    llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << *it << llendl; +	    llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << it->getLocation() << llendl;  	}  } @@ -158,11 +133,7 @@ void LLLocationHistory::save() const  	for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)  	{ -		std::string tooltip =  getToolTip(*it); -		if(!tooltip.empty()) -		{ -			file << (*it) << delimiter << tooltip << std::endl; -		} +		file << LLSDOStreamer<LLSDNotationFormatter>((*it).toLLSD()) << std::endl;  	}  	file.close(); @@ -186,16 +157,17 @@ void LLLocationHistory::load()  	// add each line in the file to the list  	std::string line; - +	LLPointer<LLSDParser> parser = new LLSDNotationParser();  	while (std::getline(file, line)) { -		size_t dp = line.find(delimiter); - -		if (dp != std::string::npos) { -			const std::string reg_name = line.substr(0, dp); -			const std::string tooltip = line.substr(dp + 1, std::string::npos); - -			addItem(reg_name, tooltip); +		LLSD s_item; +		std::istringstream iss(line); +		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) +		{ +			llinfos<< "Parsing saved teleport history failed" << llendl; +			break;  		} + +		mItems.push_back(s_item);  	}  	file.close(); diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h index 060a6b2fe8..5f9976f87a 100644 --- a/indra/newview/lllocationhistory.h +++ b/indra/newview/lllocationhistory.h @@ -40,21 +40,84 @@  #include <map>  #include <boost/function.hpp> +class LLSD; + +enum ELocationType { +	 TYPED_REGION_SURL//region name or surl  +	,LANDMARK  // name of landmark +	,TELEPORT_HISTORY  +	}; +class LLLocationHistoryItem { +			 +public: +	LLLocationHistoryItem(){} +	LLLocationHistoryItem(std::string typed_location,  +			LLVector3d global_position, std::string tooltip,ELocationType type ): +		mLocation(typed_location),		 +		mGlobalPos(global_position), +		mToolTip(tooltip), +		mType(type) +	{} +	LLLocationHistoryItem(const LLLocationHistoryItem& item): +		mGlobalPos(item.mGlobalPos), +		mToolTip(item.mToolTip), +		mLocation(item.mLocation), +		mType(item.mType) +	{} +	LLLocationHistoryItem(const LLSD& data): +	mLocation(data["location"]), +	mGlobalPos(data["global_pos"]), +	mToolTip(data["tooltip"]), +	mType(ELocationType(data["item_type"].asInteger())) +	{} + +	bool operator==(const LLLocationHistoryItem& item) +	{ +		// do not compare  mGlobalPos,  +		// because of a rounding off , the history  can contain duplicates +		return mLocation == item.mLocation && (mType == item.mType);  +	} +	bool operator!=(const LLLocationHistoryItem& item) +	{ +		return ! (*this == item); +	} +	LLSD toLLSD() const +	{ +		LLSD val; +		val["location"]= mLocation; +		val["global_pos"]	= mGlobalPos.getValue(); +		val["tooltip"]	= mToolTip; +		val["item_type"] = mType; +		return val; +	} +	const std::string& getLocation() const { return mLocation;	}; +	const std::string& getToolTip() const { return mToolTip;	}; +	//static bool equalByRegionParcel(const LLLocationHistoryItem& item1, const LLLocationHistoryItem& item2); +	static bool equalByLocation(const LLLocationHistoryItem& item1, const std::string& item_location) +	{ +		return  item1.getLocation() == item_location; +	} +	 +	LLVector3d	mGlobalPos; // global position +	std::string mToolTip;// SURL +	std::string mLocation;// typed_location +	ELocationType mType; +}; +  class LLLocationHistory: public LLSingleton<LLLocationHistory>  {  	LOG_CLASS(LLLocationHistory);  public: -	typedef std::vector<std::string>	location_list_t; +	typedef std::vector<LLLocationHistoryItem>	location_list_t;  	typedef boost::function<void()>		loaded_callback_t;  	typedef boost::signals2::signal<void()> loaded_signal_t;  	LLLocationHistory(); -	void					addItem(const std::string & item, const std::string & tooltip); -	bool					touchItem(const std::string & item); +	void					addItem(const LLLocationHistoryItem& item); +	bool					touchItem(const LLLocationHistoryItem& item);  	void                    removeItems(); -	std::string				getToolTip(const std::string & item) const;  	size_t					getItemCount() const	{ return mItems.size(); }  	const location_list_t&	getItems() const		{ return mItems; }  	bool					getMatchingItems(std::string substring, location_list_t& result) const; @@ -65,10 +128,8 @@ public:  	void					dump() const;  private: -	bool equalByRegionParcel(const std::string& item, const  std::string& item_to_add); -	const static char delimiter; -	std::vector<std::string>			mItems; -	std::map<std::string, std::string>	mToolTips; + +	location_list_t			mItems;  	std::string							mFilename; /// File to store the history to.  	loaded_signal_t						mLoadedSignal;  }; diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index a8ec826e88..f54a614f62 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -48,6 +48,7 @@  #include "lllandmarkactions.h"  #include "lllandmarklist.h"  #include "lllocationhistory.h" +#include "llteleporthistory.h"  #include "llsidetray.h"  #include "llslurl.h"  #include "lltrans.h" @@ -295,11 +296,19 @@ BOOL LLLocationInputCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect*  	if (LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen) && !msg.empty())  	{  		if (mList->getRect().pointInRect(x, y)) { -			LLLocationHistory* lh = LLLocationHistory::getInstance(); -			const std::string tooltip = lh->getToolTip(msg); - -			if (!tooltip.empty()) { -				msg = tooltip; +			S32 loc_x, loc_y; +			//x,y - contain coordinates related to the location input control, but without taking the expanded list into account +			//So we have to convert it again into local coordinates of mList +			localPointToOtherView(x,y,&loc_x,&loc_y,mList); +			 +			LLScrollListItem* item =  mList->hitItem(loc_x,loc_y); +			if (item) +			{ +				LLSD value = item->getValue(); +				if (value.has("tooltip")) +				{ +					msg = value["tooltip"].asString(); +				}  			}  		} @@ -448,18 +457,58 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)  	rebuildLocationHistory(filter);  	//Let's add landmarks to the top of the list if any -	if( filter.size() !=0 ) +	if(!filter.empty() )  	{  		LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(filter, TRUE);  		for(U32 i=0; i < landmark_items.size(); i++)  		{ -			mList->addSimpleElement(landmark_items[i]->getName(), ADD_TOP); +			LLSD value; +			//TODO:: DO we need tooltip for Landmark?? +			 +			value["item_type"] = LANDMARK; +			value["AssetUUID"] =  landmark_items[i]->getAssetUUID();  +			add(landmark_items[i]->getName(), value); +			 +		} +	//Let's add teleport history items +		LLTeleportHistory* th = LLTeleportHistory::getInstance(); +		LLTeleportHistory::slurl_list_t th_items = th->getItems(); + +		std::set<std::string> new_item_titles;// duplicate control +		LLTeleportHistory::slurl_list_t::iterator result = std::find_if( +				th_items.begin(), th_items.end(), boost::bind( +						&LLLocationInputCtrl::findTeleportItemsByTitle, this, +						_1, filter)); + +		while (result != th_items.end()) +		{ +			//mTitile format - region_name[, parcel_name] +			//mFullTitile format - region_name[, parcel_name] (local_x,local_y, local_z) +			if (new_item_titles.insert(result->mFullTitle).second) +			{ +				LLSD value; +				value["item_type"] = TELEPORT_HISTORY; +				value["global_pos"] = result->mGlobalPos.getValue(); +				std::string region_name = result->mTitle.substr(0, result->mTitle.find(',')); +				//TODO*: add Surl to teleportitem or parse region name from title +				value["tooltip"] = LLSLURL::buildSLURLfromPosGlobal(region_name, +						result->mGlobalPos,	false); +				add(result->getTitle(), value);  +			} +			result = std::find_if(result + 1, th_items.end(), boost::bind( +									&LLLocationInputCtrl::findTeleportItemsByTitle, this, +									_1, filter));  		}  	} +	sortByName(); +	  	mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.  } - +bool LLLocationInputCtrl::findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter) +{ +	return item.mTitle.find(filter) != std::string::npos; +}  void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask)  {  	if (mLocationContextMenu) @@ -519,7 +568,12 @@ void LLLocationInputCtrl::rebuildLocationHistory(std::string filter)  	removeall();  	for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)  	{ -		add(*it); +		LLSD value; +		value["tooltip"] = it->getToolTip(); +		//location history can contain only typed locations +		value["item_type"] = TYPED_REGION_SURL; +		value["global_pos"] = it->mGlobalPos.getValue(); +		add(it->getLocation(), value);  	}  } diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index d967df8257..3c43e1a321 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -41,6 +41,7 @@ class LLLandmark;  class LLAddLandmarkObserver;  class LLRemoveLandmarkObserver;  class LLMenuGL; +class LLTeleportHistoryItem;  /**   * Location input control. @@ -103,6 +104,7 @@ private:  	void					refresh();  	void					refreshLocation();  	void					rebuildLocationHistory(std::string filter = ""); +	bool 					findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter);  	void					setText(const LLStringExplicit& text);  	void					updateAddLandmarkButton();  	void 					updateContextMenu(); diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 28e9c93779..c283b3a05f 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -45,7 +45,7 @@  #include "lllocationhistory.h"  #include "lllocationinputctrl.h"  #include "llteleporthistory.h" -#include "llsearcheditor.h" +#include "llsearchcombobox.h"  #include "llsidetray.h"  #include "llslurl.h"  #include "llurlsimstring.h" @@ -82,7 +82,6 @@ public:  		Mandatory<EType> item_type;  		Params() {} -		Params(EType type, std::string title);  	};  	/*virtual*/ void	draw(); @@ -104,24 +103,21 @@ private:  const std::string LLTeleportHistoryMenuItem::ICON_IMG_BACKWARD("teleport_history_backward.tga");  const std::string LLTeleportHistoryMenuItem::ICON_IMG_FORWARD("teleport_history_forward.tga"); -LLTeleportHistoryMenuItem::Params::Params(EType type, std::string title) -{ -	item_type(type); -	font.name("SANSSERIF"); - -	if (type == TYPE_CURRENT) -		font.style("BOLD"); -	else -		title = "   " + title; - -	name(title); -	label(title); -} -  LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)  :	LLMenuItemCallGL(p),  	mArrowIcon(NULL)  { +	// Set appearance depending on the item type. +	if (p.item_type  == TYPE_CURRENT) +	{ +		setFont(LLFontGL::getFontSansSerifBold()); +	} +	else +	{ +		setFont(LLFontGL::getFontSansSerif()); +		setLabel(std::string("   ") + std::string(p.label)); +	} +  	LLIconCtrl::Params icon_params;  	icon_params.name("icon");  	icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0)); @@ -183,14 +179,11 @@ LLNavigationBar::LLNavigationBar()  	mBtnForward(NULL),  	mBtnHome(NULL),  	mCmbLocation(NULL), -	mLeSearch(NULL), +	mSearchComboBox(NULL),  	mPurgeTPHistoryItems(false)  {  	setIsChrome(TRUE); -	mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback( -			boost::bind(&LLNavigationBar::onTeleportFinished, this, _1)); -  	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml");  	// set a listener function for LoginComplete event @@ -202,8 +195,10 @@ LLNavigationBar::LLNavigationBar()  LLNavigationBar::~LLNavigationBar()  { -	mParcelMgrConnection.disconnect(); +	mTeleportFinishConnection.disconnect();  	sInstance = 0; + +	LLSearchHistory::getInstance()->save();  }  BOOL LLNavigationBar::postBuild() @@ -213,10 +208,12 @@ BOOL LLNavigationBar::postBuild()  	mBtnHome	= getChild<LLButton>("home_btn");  	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");  -	mLeSearch	= getChild<LLSearchEditor>("search_input"); +	mSearchComboBox	= getChild<LLSearchComboBox>("search_combo_box"); + +	fillSearchComboBox();  	if (!mBtnBack || !mBtnForward || !mBtnHome || -		!mCmbLocation || !mLeSearch) +		!mCmbLocation || !mSearchComboBox)  	{  		llwarns << "Malformed navigation bar" << llendl;  		return FALSE; @@ -234,7 +231,7 @@ BOOL LLNavigationBar::postBuild()  	mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); -	mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); +	mSearchComboBox->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));  	mDefaultNbRect = getRect();  	mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect(); @@ -246,6 +243,25 @@ BOOL LLNavigationBar::postBuild()  	return TRUE;  } +void LLNavigationBar::fillSearchComboBox() +{ +	if(!mSearchComboBox) +	{ +		return; +	} + +	LLSearchHistory::getInstance()->load(); + +	LLSearchHistory::search_history_list_t search_list =  +		LLSearchHistory::getInstance()->getSearchHistoryList(); +	LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin(); +	for( ; search_list.end() != it; ++it) +	{ +		LLSearchHistory::LLSearchHistoryItem item = *it; +		mSearchComboBox->add(item.search_query); +	} +} +  void LLNavigationBar::draw()  {  	if(mPurgeTPHistoryItems) @@ -280,7 +296,12 @@ void LLNavigationBar::onHomeButtonClicked()  void LLNavigationBar::onSearchCommit()  { -	invokeSearch(mLeSearch->getValue().asString()); +	std::string search_query = mSearchComboBox->getValue().asString(); +	if(!search_query.empty()) +	{ +		LLSearchHistory::getInstance()->addEntry(search_query); +		invokeSearch(mSearchComboBox->getValue().asString());	 +	}  }  void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata) @@ -299,69 +320,107 @@ void LLNavigationBar::onLocationSelection()  	if (typed_location.empty())  		return; +	LLSD value = mCmbLocation->getSelectedValue(); +	 +	if(value.has("item_type")) +	{ + +		switch(value["item_type"].asInteger()) +		{ +		case LANDMARK: +			 +			if(value.has("AssetUUID")) +			{ +				 +				gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); +				return; +			} +			else +			{ +				LLInventoryModel::item_array_t landmark_items = +						LLLandmarkActions::fetchLandmarksByName(typed_location, +								FALSE); +				if (!landmark_items.empty()) +				{ +					gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID()); +					return;  +				} +			} +			break; +			 +		case TELEPORT_HISTORY: +			//in case of teleport item was selected, teleport by position too. +		case TYPED_REGION_SURL: +			if(value.has("global_pos")) +			{ +				gAgent.teleportViaLocation(LLVector3d(value["global_pos"])); +				return; +			} +			break; +			 +		default: +			break;		 +		} +	} +	//Let's parse surl or region name +	  	std::string region_name;  	LLVector3 local_coords(128, 128, 0);  	S32 x = 0, y = 0, z = 0; -  	// Is the typed location a SLURL?  	if (LLSLURL::isSLURL(typed_location))  	{  		// Yes. Extract region name and local coordinates from it.  		if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), ®ion_name, &x, &y, &z)) -			local_coords.set(x, y, z); +				local_coords.set(x, y, z);  		else  			return; -	} -	else +	}else  	{ -		//If it is not slurl let's look for landmarks -		LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(typed_location, FALSE); -		if ( !landmark_items.empty() ) -		{ -			gAgent.teleportViaLandmark(landmark_items[0]->getAssetUUID()); -			return; -		} -		//No landmark match, check if it is a region name -		region_name = parseLocation(typed_location, &x, &y, &z); -		if (region_name != typed_location) -			local_coords.set(x, y, z); - -		// Treat it as region name. -		// region_name = typed_location; +		// assume that an user has typed the {region name} or possible {region_name, parcel} +		region_name  = typed_location.substr(0,typed_location.find(','));  	} - +	  	// Resolve the region name to its global coordinates.  	// If resolution succeeds we'll teleport.  	LLWorldMap::url_callback_t cb = boost::bind(  			&LLNavigationBar::onRegionNameResponse, this,  			typed_location, region_name, local_coords, _1, _2, _3, _4); +	// connect the callback each time, when user enter new location to get real location of agent after teleport +	mTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> +			setTeleportFinishedCallback(boost::bind(&LLNavigationBar::onTeleportFinished, this, _1,typed_location)); +	  	LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);  } -void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos) +void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location)  {  	// Location is valid. Add it to the typed locations history.  	LLLocationHistory* lh = LLLocationHistory::getInstance(); +	//TODO*: do we need convert surl into readable format?  	std::string location;  	/*NOTE:  	 * We can't use gAgent.getPositionAgent() in case of local teleport to build location.  	 * At this moment gAgent.getPositionAgent() contains previous coordinates.  	 * according to EXT-65 agent position is being reseted on each frame.    	 */ -	LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM, -			gAgent.getPosAgentFromGlobal(global_agent_pos)); +		LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM, +					gAgent.getPosAgentFromGlobal(global_agent_pos)); +	std::string tooltip (LLSLURL::buildSLURLfromPosGlobal(gAgent.getRegion()->getName(), global_agent_pos, false)); +	LLLocationHistoryItem item (location, +			global_agent_pos, tooltip,TYPED_REGION_SURL);// we can add into history only TYPED location  	//Touch it, if it is at list already, add new location otherwise -	if ( !lh->touchItem(location) ) { -		std::string tooltip = LLSLURL::buildSLURLfromPosGlobal( -				gAgent.getRegion()->getName(), global_agent_pos, false); -		 -		lh->addItem(location, tooltip); +	if ( !lh->touchItem(item) ) { +		lh->addItem(item);  	} -	llinfos << "Saving after on teleport finish" << llendl; -	lh->save(); +	lh->save(); +	 +	if(mTeleportFinishConnection.connected()) +		mTeleportFinishConnection.disconnect(); +	  }  void LLNavigationBar::onTeleportHistoryChanged() @@ -411,7 +470,9 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()  		else  			type = LLTeleportHistoryMenuItem::TYPE_CURRENT; -		LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].getTitle()); +		LLTeleportHistoryMenuItem::Params item_params; +		item_params.label = item_params.name = hist_items[i].getTitle(); +		item_params.item_type = type;  		item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));  		LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params);  		//new_itemp->setFont() @@ -435,8 +496,8 @@ void LLNavigationBar::onRegionNameResponse(  	// Teleport to the location.  	LLVector3d region_pos = from_region_handle(region_handle);  	LLVector3d global_pos = region_pos + (LLVector3d) local_coords; -	 -	llinfos << "Teleporting to: " << global_pos  << llendl; + +	llinfos << "Teleporting to: " << LLSLURL::buildSLURLfromPosGlobal(region_name,	global_pos, false)  << llendl;  	gAgent.teleportViaLocation(global_pos);  } @@ -474,35 +535,6 @@ void LLNavigationBar::invokeSearch(std::string search_text)  	LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text)));  } -std::string LLNavigationBar::parseLocation(const std::string & location, S32* x, S32* y, S32* z) { -	/* -	 * This regular expression extracts numbers from the following string -	 * construct: "(num1, num2, num3)", where num1, num2 and num3 are decimal -	 * numbers. Leading and trailing spaces are also caught by the expression. -	 */ -	const boost::regex re("\\s*\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)\\s*"); - -	boost::smatch m; -	if (boost::regex_search(location, m, re)) { -		// string representations of parsed by regex++ numbers -		std::string xstr(m[1].first, m[1].second); -		std::string ystr(m[2].first, m[2].second); -		std::string zstr(m[3].first, m[3].second); - -		*x = atoi(xstr.c_str()); -		*y = atoi(ystr.c_str()); -		*z = atoi(zstr.c_str()); -		//erase commas in coordinates -		std::string region_parcel = boost::regex_replace(location, re, ""); -		// cut region name -		return region_parcel.substr(0, region_parcel.find_first_of(',')); -	} - -	*x = *y = *z = 0; - -	return location; -} -  void LLNavigationBar::clearHistoryCache()  {  	mCmbLocation->removeall(); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 6932847854..8a65cd24fa 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -41,6 +41,7 @@ class LLButton;  class LLLocationInputCtrl;  class LLMenuGL;  class LLSearchEditor; +class LLSearchComboBox;  /**   * Web browser-like navigation bar. @@ -69,12 +70,6 @@ private:  	void rebuildTeleportHistoryMenu();  	void showTeleportHistoryMenu();  	void invokeSearch(std::string search_text); - -	/** -	 * Get region name and local coordinates from typed location -	 */ -	static std::string parseLocation(const std::string & location, S32* x, S32* y, S32* z); -  	// callbacks  	void onTeleportHistoryMenuItemClicked(const LLSD& userdata);  	void onTeleportHistoryChanged(); @@ -86,7 +81,7 @@ private:  	void onLocationSelection();  	void onLocationPrearrange(const LLSD& data);  	void onSearchCommit(); -	void onTeleportFinished(const LLVector3d& global_agent_pos); +	void onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location);  	void onRegionNameResponse(  			std::string typed_location,  			std::string region_name, @@ -94,17 +89,19 @@ private:  			U64 region_handle, const std::string& url,  			const LLUUID& snapshot_id, bool teleport); +	void fillSearchComboBox(); +  	static LLNavigationBar *sInstance;  	LLMenuGL*					mTeleportHistoryMenu;  	LLButton*					mBtnBack;  	LLButton*					mBtnForward;  	LLButton*					mBtnHome; -	LLSearchEditor*				mLeSearch; +	LLSearchComboBox*			mSearchComboBox;  	LLLocationInputCtrl*		mCmbLocation;  	LLRect						mDefaultNbRect;  	LLRect						mDefaultFpRect; -	boost::signals2::connection	mParcelMgrConnection; +	boost::signals2::connection	mTeleportFinishConnection;  	bool						mPurgeTPHistoryItems;  }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index b2d606ab4d..fd3519bf4b 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -372,7 +372,6 @@ void LLPanelAvatarProfile::resetControls()  	childSetVisible("status_me_panel", false);  	childSetVisible("profile_me_buttons_panel", false);  	childSetVisible("account_actions_panel", false); -	childSetVisible("partner_edit_link", false);  }  void LLPanelAvatarProfile::resetData() @@ -539,7 +538,7 @@ void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)  	childSetValue("acc_status_text", caption_text);  } -void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url) +void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url)  {  	LLWeb::loadURL(url);  } @@ -675,4 +674,3 @@ void LLPanelAvatarMeProfile::onStatusMessageChanged()  {  	updateData();  } - diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 4ee4cb6e87..1ed5fa4357 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -166,7 +166,7 @@ protected:  	 */  	virtual void fillAccountStatus(const LLAvatarData* avatar_data); -	void onUrlTextboxClicked(std::string url); +	void onUrlTextboxClicked(const std::string& url);  	void onHomepageTextboxClicked();  	void onAddFriendButtonClick();  	void onIMButtonClick(); diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp new file mode 100644 index 0000000000..60d0f07285 --- /dev/null +++ b/indra/newview/llpanelblockedlist.cpp @@ -0,0 +1,279 @@ +/**  + * @file llpanelblockedlist.cpp + * @brief Container for blocked Residents & Objects list + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloater.h" +#include "llfloaterreg.h" +#include "llscrolllistctrl.h" + +#include "llpanelblockedlist.h" + +// project include +#include "llfloateravatarpicker.h" +#include "llsidetray.h" +#include "llsidetraypanelcontainer.h" + +static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray"); + +// +// Constants +// +const std::string BLOCKED_PARAM_NAME = "blocked_to_select"; + +//----------------------------------------------------------------------------- +// LLPanelBlockedList() +//----------------------------------------------------------------------------- + +LLPanelBlockedList::LLPanelBlockedList() +:	LLPanel() +{ +	mCommitCallbackRegistrar.add("Block.ClickPick",			boost::bind(&LLPanelBlockedList::onPickBtnClick, this)); +	mCommitCallbackRegistrar.add("Block.ClickBlockByName",	boost::bind(&LLPanelBlockedList::onBlockByNameClick, this)); +	mCommitCallbackRegistrar.add("Block.ClickRemove",		boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this)); +} + +LLPanelBlockedList::~LLPanelBlockedList() +{ +	LLMuteList::getInstance()->removeObserver(this); +} + +BOOL LLPanelBlockedList::postBuild() +{ +	mBlockedList = getChild<LLScrollListCtrl>("blocked"); +	mBlockedList->setCommitOnSelectionChange(TRUE); + +	childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL); + +	LLMuteList::getInstance()->addObserver(this); +	 +	refreshBlockedList(); + +	return LLPanel::postBuild(); +} + +void LLPanelBlockedList::draw() +{ +	updateButtons(); +	LLPanel::draw(); +} + +void LLPanelBlockedList::onOpen(const LLSD& key) +{ +	if (key.has(BLOCKED_PARAM_NAME) && key[BLOCKED_PARAM_NAME].asUUID().notNull()) +	{ +		selectBlocked(key[BLOCKED_PARAM_NAME].asUUID()); +	} +} + +void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id) +{ +	mBlockedList->selectByID(mute_id); +} + +void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect) +{ +	LLSideTray::getInstance()->showPanel("panel_block_list_sidetray", LLSD().insert(BLOCKED_PARAM_NAME, idToSelect)); +} + + +////////////////////////////////////////////////////////////////////////// +// Private Section +////////////////////////////////////////////////////////////////////////// +void LLPanelBlockedList::refreshBlockedList() +{ +	mBlockedList->deleteAllItems(); + +	std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes(); +	std::vector<LLMute>::iterator it; +	for (it = mutes.begin(); it != mutes.end(); ++it) +	{ +		std::string display_name = it->getDisplayName(); +		mBlockedList->addStringUUIDItem(display_name, it->mID, ADD_BOTTOM, TRUE); +	} +} + +void LLPanelBlockedList::updateButtons() +{ +	bool hasSelected = NULL != mBlockedList->getFirstSelected(); +	childSetEnabled("Unblock", hasSelected); +} + + + +void LLPanelBlockedList::onBackBtnClick() +{ +	LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); +	if(parent) +	{ +		parent->openPreviousPanel(); +	} +} + +void LLPanelBlockedList::onRemoveBtnClick() +{ +	std::string name = mBlockedList->getSelectedItemLabel(); +	LLUUID id = mBlockedList->getStringUUIDSelectedItem(); +	LLMute mute(id); +	mute.setFromDisplayName(name); +	// now mute.mName has the suffix trimmed off +	 +	S32 last_selected = mBlockedList->getFirstSelectedIndex(); +	if (LLMuteList::getInstance()->remove(mute)) +	{ +		// Above removals may rebuild this dialog. +		 +		if (last_selected == mBlockedList->getItemCount()) +		{ +			// we were on the last item, so select the last item again +			mBlockedList->selectNthItem(last_selected - 1); +		} +		else +		{ +			// else select the item after the last item previously selected +			mBlockedList->selectNthItem(last_selected); +		} +	} +} + +void LLPanelBlockedList::onPickBtnClick() +{ +	const BOOL allow_multiple = FALSE; +	const BOOL close_on_select = TRUE; +	/*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(callbackBlockPicked, this, allow_multiple, close_on_select); + +	// *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed? +	// old Floater dependency is not enable in panel +	// addDependentFloater(picker); +} + +void LLPanelBlockedList::onBlockByNameClick() +{ +	LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName); +} + +//static +void LLPanelBlockedList::callbackBlockPicked(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data) +{ +	if (names.empty() || ids.empty()) return; +	LLMute mute(ids[0], names[0], LLMute::AGENT); +	LLMuteList::getInstance()->add(mute); +	showPanelAndSelect(mute.mID); +} + +//static +void LLPanelBlockedList::callbackBlockByName(const std::string& text) +{ +	if (text.empty()) return; + +	LLMute mute(LLUUID::null, text, LLMute::BY_NAME); +	BOOL success = LLMuteList::getInstance()->add(mute); +	if (!success) +	{ +		LLNotifications::instance().add("MuteByNameFailed"); +	} +} + +////////////////////////////////////////////////////////////////////////// +//			LLFloaterGetBlockedObjectName +////////////////////////////////////////////////////////////////////////// + +// Constructor/Destructor +LLFloaterGetBlockedObjectName::LLFloaterGetBlockedObjectName(const LLSD& key) +: LLFloater(key) +, mGetObjectNameCallback(NULL) +{ +} + +// Destroys the object +LLFloaterGetBlockedObjectName::~LLFloaterGetBlockedObjectName() +{ +	gFocusMgr.releaseFocusIfNeeded( this ); +} + +BOOL LLFloaterGetBlockedObjectName::postBuild() +{ +	getChild<LLButton>("OK")->		setCommitCallback(boost::bind(&LLFloaterGetBlockedObjectName::applyBlocking, this)); +	getChild<LLButton>("Cancel")->	setCommitCallback(boost::bind(&LLFloaterGetBlockedObjectName::cancelBlocking, this)); +	center(); + +	return LLFloater::postBuild(); +} + +BOOL LLFloaterGetBlockedObjectName::handleKeyHere(KEY key, MASK mask) +{ +	if (key == KEY_RETURN && mask == MASK_NONE) +	{ +		applyBlocking(); +		return TRUE; +	} +	else if (key == KEY_ESCAPE && mask == MASK_NONE) +	{ +		cancelBlocking(); +		return TRUE; +	} + +	return LLFloater::handleKeyHere(key, mask); +} + +// static +LLFloaterGetBlockedObjectName* LLFloaterGetBlockedObjectName::show(get_object_name_callback_t callback) +{ +	LLFloaterGetBlockedObjectName* floater = LLFloaterReg::showTypedInstance<LLFloaterGetBlockedObjectName>("mute_object_by_name"); + +	floater->mGetObjectNameCallback = callback; + +	// *TODO: mantipov: should LLFloaterGetBlockedObjectName be closed when panel is closed? +	// old Floater dependency is not enable in panel +	// addDependentFloater(floater); + +	return floater; +} + +////////////////////////////////////////////////////////////////////////// +// Private Section +void LLFloaterGetBlockedObjectName::applyBlocking() +{ +	if (mGetObjectNameCallback) +	{ +		const std::string& text = childGetValue("object_name").asString(); +		mGetObjectNameCallback(text); +	} +	closeFloater(); +} + +void LLFloaterGetBlockedObjectName::cancelBlocking() +{ +	closeFloater(); +} + +//EOF diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h new file mode 100644 index 0000000000..52b74a184b --- /dev/null +++ b/indra/newview/llpanelblockedlist.h @@ -0,0 +1,115 @@ +/**  + * @file llpanelblockedlist.h + * @brief Container for blocked Residents & Objects list + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + *  + * Copyright (c) 2002-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELBLOCKEDLIST_H +#define LL_LLPANELBLOCKEDLIST_H + +#include "llpanel.h" +#include "llmutelist.h" +// #include <vector> + +// class LLButton; +// class LLLineEditor; +// class LLMessageSystem; +// class LLUUID; + class LLScrollListCtrl; + +class LLPanelBlockedList +	:	public LLPanel, public LLMuteListObserver +{ +public: +	LLPanelBlockedList(); +	~LLPanelBlockedList(); + +	virtual BOOL postBuild(); +	virtual void draw(); +	virtual void onOpen(const LLSD& key); +	 +	void selectBlocked(const LLUUID& id); + +	/** +	 *	Shows current Panel in side tray and select passed blocked item. +	 *  +	 *	@param idToSelect - LLUUID of blocked Resident or Object to be selected.  +	 *			If it is LLUUID::null, nothing will be selected. +	 */ +	static void showPanelAndSelect(const LLUUID& idToSelect); + +	// LLMuteListObserver callback interface implementation. +	/* virtual */ void onChange() {	refreshBlockedList();} +	 +private: +	void refreshBlockedList(); +	void updateButtons(); + +	// UI callbacks +	void onBackBtnClick(); +	void onRemoveBtnClick(); +	void onPickBtnClick(); +	void onBlockByNameClick(); + +	static void callbackBlockPicked(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data); +	static void callbackBlockByName(const std::string& text); + +private: +	LLScrollListCtrl* mBlockedList; +}; + +//----------------------------------------------------------------------------- +// LLFloaterGetBlockedObjectName() +//----------------------------------------------------------------------------- +// Class for handling mute object by name floater. +class LLFloaterGetBlockedObjectName : public LLFloater +{ +	friend class LLFloaterReg; +public: +	typedef boost::function<void (const std::string&)> get_object_name_callback_t; + +	virtual BOOL postBuild(); + +	virtual BOOL handleKeyHere(KEY key, MASK mask); + +	static LLFloaterGetBlockedObjectName* show(get_object_name_callback_t callback); + +private: +	LLFloaterGetBlockedObjectName(const LLSD& key); +	virtual ~LLFloaterGetBlockedObjectName(); + +	// UI Callbacks +	void applyBlocking(); +	void cancelBlocking(); + +	get_object_name_callback_t mGetObjectNameCallback; +}; + + +#endif // LL_LLPANELBLOCKEDLIST_H diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 34d5ef8f86..42aa21c13e 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -43,12 +43,12 @@  // newview  #include "llagent.h" +#include "llavataractions.h"  #include "llavatarlist.h"  #include "llcallingcard.h"			// for LLAvatarTracker  #include "llfloateravatarpicker.h"  //#include "llfloaterminiinspector.h"  #include "llfriendcard.h" -#include "llavataractions.h"  #include "llgroupactions.h"  #include "llgrouplist.h"  #include "llrecentpeople.h" @@ -976,7 +976,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)  	}  } -  void LLPanelPeople::onCallButtonClicked()  {  	// *TODO: not implemented yet diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index bd6ca4746c..c34038c672 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -54,6 +54,11 @@ static const std::string XML_BTN_INFO = "info_btn";  static const std::string XML_BTN_TELEPORT = "teleport_btn";  static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn"; +static const std::string PICK_ID("pick_id"); +static const std::string PICK_CREATOR_ID("pick_creator_id"); +static const std::string PICK_NAME("pick_name"); + +  static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");  //----------------------------------------------------------------------------- @@ -97,19 +102,8 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  			gCacheName->getName(getAvatarId(),name,second_name);  			childSetTextArg("pick_title", "[NAME]",name); -			// to restore selection of the same item later -			LLUUID pick_id_selected(LLUUID::null); -			if (getSelectedPickItem()) pick_id_selected = getSelectedPickItem()->getPickId(); -  			mPicksList->clear(); -			//*TODO move it somewhere else? -			childSetEnabled(XML_BTN_NEW, false); -			childSetEnabled(XML_BTN_DELETE, false); -			childSetEnabled(XML_BTN_INFO, false); -			childSetEnabled(XML_BTN_TELEPORT,!avatar_picks->picks_list.empty()); -			childSetEnabled(XML_BTN_SHOW_ON_MAP,!avatar_picks->picks_list.empty()); -						  			LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();  			for(; avatar_picks->picks_list.end() != it; ++it)  			{ @@ -124,12 +118,18 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  				LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);  				picture->update(); -				mPicksList->addItem(picture); -				if (pick_id_selected != LLUUID::null &&  -					pick_id == pick_id_selected) mPicksList->toggleSelection(picture); + +				LLSD pick_value = LLSD(); +				pick_value.insert(PICK_ID, pick_id); +				pick_value.insert(PICK_NAME, pick_name); +				pick_value.insert(PICK_CREATOR_ID, getAvatarId()); + +				mPicksList->addItem(picture, pick_value);  				picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));  				picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4)); +				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this)); +				picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));  			}  			LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); @@ -140,10 +140,10 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  LLPickItem* LLPanelPicks::getSelectedPickItem()  { -	std::list<LLPanel*> selected_items = mPicksList->getSelectedItems(); +	LLPanel* selected_item = mPicksList->getSelectedItem(); +	if (!selected_item) return NULL; -	if (selected_items.empty()) return NULL; -	return dynamic_cast<LLPickItem*>(selected_items.front()); +	return dynamic_cast<LLPickItem*>(selected_item);  }  BOOL LLPanelPicks::postBuild() @@ -193,6 +193,10 @@ void LLPanelPicks::onOpen(const LLSD& key)  	{  		childSetVisible("pick_title", !self);  		childSetVisible("pick_title_agent", self); + +		mPopupMenu->setItemVisible("pick_delete", TRUE); +		mPopupMenu->setItemVisible("pick_edit", TRUE); +		mPopupMenu->setItemVisible("pick_separator", TRUE);  	}  	LLPanelProfileTab::onOpen(key); @@ -201,11 +205,11 @@ void LLPanelPicks::onOpen(const LLSD& key)  //static  void LLPanelPicks::onClickDelete()  { -	LLPickItem* pick_item = getSelectedPickItem(); -	if (!pick_item) return; +	LLSD pick_value = mPicksList->getSelectedValue(); +	if (pick_value.isUndefined()) return;  	LLSD args;  -	args["PICK"] = pick_item->getPickName();  +	args["PICK"] = pick_value[PICK_NAME];   	LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2));   } @@ -213,12 +217,12 @@ bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response  {  	S32 option = LLNotification::getSelectedOption(notification, response); -	LLPickItem* pick_item = getSelectedPickItem(); +	LLSD pick_value = mPicksList->getSelectedValue();  	if (0 == option)  	{ -		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId()); -		mPicksList->removeItem(pick_item); +		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]); +		mPicksList->removeItemByValue(pick_value);  	}  	updateButtons();  	return false; @@ -265,32 +269,30 @@ void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)  void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)  { -	LLPickItem* pick_item = dynamic_cast<LLPickItem*>(item); -	if (!pick_item) return; +	LLSD pick_value = mPicksList->getSelectedValue(); +	if (pick_value.isUndefined()) return; +	  	LLSD args;  -	args["PICK"] = pick_item->getPickName();  +	args["PICK"] = pick_value[PICK_NAME];   	LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));   }  void LLPanelPicks::updateButtons()  {  	int picks_num = mPicksList->size(); -	childSetEnabled(XML_BTN_INFO, picks_num > 0); +	bool has_selected = mPicksList->numSelected(); + +	childSetEnabled(XML_BTN_INFO, has_selected);  	if (getAvatarId() == gAgentID)  	{  		childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS); -		childSetEnabled(XML_BTN_DELETE, picks_num > 0); - -		//*TODO move somewhere this calls -		// we'd better set them up earlier when a panel was being constructed -		mPopupMenu->setItemVisible("pick_delete", TRUE); -		mPopupMenu->setItemVisible("pick_edit", TRUE); -		mPopupMenu->setItemVisible("pick_separator", TRUE); +		childSetEnabled(XML_BTN_DELETE, has_selected);  	} -	//*TODO update buttons like Show on Map, Teleport etc. - +	childSetEnabled(XML_BTN_INFO, has_selected); +	childSetEnabled(XML_BTN_TELEPORT, has_selected); +	childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected);  }  void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) @@ -318,12 +320,12 @@ void LLPanelPicks::onClickNew()  void LLPanelPicks::onClickInfo()  { -	LLPickItem* pick = getSelectedPickItem(); -	if (!pick) return; +	LLSD selected_value = mPicksList->getSelectedValue(); +	if (selected_value.isUndefined()) return;  	buildPickPanel();  	mPickPanel->reset(); -	mPickPanel->init(pick->getCreatorId(), pick->getPickId()); +	mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);  	getProfilePanel()->togglePanel(mPickPanel);  } @@ -335,12 +337,12 @@ void LLPanelPicks::onClickBack()  void LLPanelPicks::onClickMenuEdit()  {  	//*TODO, refactor - most of that is similar to onClickInfo -	LLPickItem* pick = getSelectedPickItem(); -	if (!pick) return; +	LLSD selected_value = mPicksList->getSelectedValue(); +	if (selected_value.isUndefined()) return;  	buildPickPanel();  	mPickPanel->reset(); -	mPickPanel->init(pick->getCreatorId(), pick->getPickId()); +	mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);  	mPickPanel->setEditMode(TRUE);  	getProfilePanel()->togglePanel(mPickPanel);  } @@ -470,3 +472,17 @@ void LLPanelPicks::onClose()  		getProfilePanel()->togglePanel(mPickPanel);  	}  } + +BOOL LLPickItem::postBuild() +{ +	setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", true)); +	setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", false)); +	return TRUE; +} + +void LLPickItem::setValue(const LLSD& value) +{ +	if (!value.isMap()) return;; +	if (!value.has("selected")) return; +	childSetVisible("selected_icon", value["selected"]); +} diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 5860354902..97e8e607c8 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -152,6 +152,11 @@ public:  	~LLPickItem(); +	/*virtual*/ BOOL postBuild(); + +	/** setting on/off background icon to indicate selected state */ +	/*virtual*/ void setValue(const LLSD& value); +  protected:  	LLUUID mPickID; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 73e09a36f9..ec1c10d8c9 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -49,6 +49,7 @@  #include "lltextbox.h"  #include "llaccordionctrl.h" +#include "llaccordionctrltab.h"  #include "llagent.h"  #include "llavatarpropertiesprocessor.h"  #include "llfloaterworldmap.h" @@ -81,6 +82,8 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo()  	{  		LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);  	} + +	LLViewerParcelMgr::getInstance()->removeObserver(this);  }  BOOL LLPanelPlaceInfo::postBuild() @@ -98,26 +101,16 @@ BOOL LLPanelPlaceInfo::postBuild()  	mParcelName = getChild<LLTextBox>("parcel_title");  	mDescEditor = getChild<LLTextEditor>("description"); -	mMaturityRatingIcon = getChild<LLIconCtrl>("maturity");  	mMaturityRatingText = getChild<LLTextBox>("maturity_value"); -  	mParcelOwner = getChild<LLTextBox>("owner_value"); -  	mLastVisited = getChild<LLTextBox>("last_visited_value"); -	mRatingIcon = getChild<LLIconCtrl>("rating_icon");  	mRatingText = getChild<LLTextBox>("rating_value"); -	mVoiceIcon = getChild<LLIconCtrl>("voice_icon");  	mVoiceText = getChild<LLTextBox>("voice_value"); -	mFlyIcon = getChild<LLIconCtrl>("fly_icon");  	mFlyText = getChild<LLTextBox>("fly_value"); -	mPushIcon = getChild<LLIconCtrl>("push_icon");  	mPushText = getChild<LLTextBox>("push_value"); -	mBuildIcon = getChild<LLIconCtrl>("build_icon");  	mBuildText = getChild<LLTextBox>("build_value"); -	mScriptsIcon = getChild<LLIconCtrl>("scripts_icon");  	mScriptsText = getChild<LLTextBox>("scripts_value"); -	mDamageIcon = getChild<LLIconCtrl>("damage_icon");  	mDamageText = getChild<LLTextBox>("damage_value");  	mRegionNameText = getChild<LLTextBox>("region_name"); @@ -131,6 +124,16 @@ BOOL LLPanelPlaceInfo::postBuild()  	mEstateOwnerText = getChild<LLTextBox>("estate_owner");  	mCovenantText = getChild<LLTextEditor>("covenant"); +	mSalesPriceText = getChild<LLTextBox>("sales_price"); +	mAreaText = getChild<LLTextBox>("area"); +	mTrafficText = getChild<LLTextBox>("traffic"); +	mPrimitivesText = getChild<LLTextBox>("primitives"); +	mParcelScriptsText = getChild<LLTextBox>("parcel_scripts"); +	mTerraformLimitsText = getChild<LLTextBox>("terraform_limits"); +	mSubdivideText = getChild<LLTextEditor>("subdivide"); +	mResaleText = getChild<LLTextEditor>("resale"); +	mSaleToText = getChild<LLTextBox>("sale_to"); +  	mOwner = getChild<LLTextBox>("owner");  	mCreator = getChild<LLTextBox>("creator");  	mCreated = getChild<LLTextBox>("created"); @@ -253,7 +256,6 @@ void LLPanelPlaceInfo::resetLocation()  	mLandmarkID.setNull();  	mPosRegion.clearVec();  	std::string not_available = getString("not_available"); -	mMaturityRatingIcon->setValue(not_available);  	mMaturityRatingText->setValue(not_available);  	mParcelOwner->setValue(not_available);  	mLastVisited->setValue(not_available); @@ -268,19 +270,12 @@ void LLPanelPlaceInfo::resetLocation()  	mSnapshotCtrl->setImageAssetID(LLUUID::null);  	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); -	mRatingIcon->setValue(not_available);  	mRatingText->setText(not_available); -	mVoiceIcon->setValue(not_available);  	mVoiceText->setText(not_available); -	mFlyIcon->setValue(not_available);  	mFlyText->setText(not_available); -	mPushIcon->setValue(not_available);  	mPushText->setText(not_available); -	mBuildIcon->setValue(not_available);  	mBuildText->setText(not_available); -	mScriptsIcon->setValue(not_available); -	mScriptsText->setText(not_available); -	mDamageIcon->setValue(not_available); +	mParcelScriptsText->setText(not_available);  	mDamageText->setText(not_available);  	mRegionNameText->setValue(not_available); @@ -293,6 +288,16 @@ void LLPanelPlaceInfo::resetLocation()  	mEstateRatingText->setValue(not_available);  	mEstateOwnerText->setValue(not_available);  	mCovenantText->setValue(not_available); + +	mSalesPriceText->setValue(not_available); +	mAreaText->setValue(not_available); +	mTrafficText->setValue(not_available); +	mPrimitivesText->setValue(not_available); +	mParcelScriptsText->setValue(not_available); +	mTerraformLimitsText->setValue(not_available); +	mSubdivideText->setValue(not_available); +	mResaleText->setValue(not_available); +	mSaleToText->setValue(not_available);  }  //virtual @@ -312,7 +317,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	bool is_info_type_teleport_history = type == TELEPORT_HISTORY;  	getChild<LLTextBox>("maturity_label")->setVisible(!is_info_type_agent); -	mMaturityRatingIcon->setVisible(!is_info_type_agent);  	mMaturityRatingText->setVisible(!is_info_type_agent);  	getChild<LLTextBox>("owner_label")->setVisible(is_info_type_agent); @@ -326,6 +330,8 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent); +	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); +  	switch(type)  	{  		case CREATE_LANDMARK: @@ -333,6 +339,15 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  		break;  		case AGENT: +			if (parcel_mgr) +			{ +				// If information is requested for current agent location +				// start using LLViewerParcelMgr for land selection. +				parcel_mgr->addObserver(this); +				parcel_mgr->selectParcelAt(gAgent.getPositionGlobal()); +			} + +		// Fall through to PLACE case  		case PLACE:  			mCurrentTitle = getString("title_place"); @@ -348,14 +363,22 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  		case TELEPORT_HISTORY:  			mCurrentTitle = getString("title_teleport_history"); - -			// *TODO: Add last visited timestamp. -			mLastVisited->setText(getString("unknown"));  		break;  	} +	if (type != AGENT && parcel_mgr != NULL) +	{ +		if (!parcel_mgr->selectionEmpty()) +		{ +			parcel_mgr->deselectUnused(); +		} +		parcel_mgr->removeObserver(this); +	} +  	if (type != PLACE)  		toggleMediaPanel(FALSE); + +	mInfoType = type;  }  BOOL LLPanelPlaceInfo::isMediaPanelVisible() @@ -432,22 +455,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  	// HACK: Flag 0x2 == adult region,  	// Flag 0x1 == mature region, otherwise assume PG  	std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); -	std::string rating_icon = "places_rating_pg.tga";  	if (parcel_data.flags & 0x2)  	{  		rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT); -		rating_icon = "places_rating_adult.tga";  	}  	else if (parcel_data.flags & 0x1)  	{  		rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE); -		rating_icon = "places_rating_mature.tga";  	} -	mMaturityRatingIcon->setValue(rating_icon);  	mMaturityRatingText->setValue(rating); - -	mRatingIcon->setValue(rating_icon);  	mRatingText->setValue(rating);  	//update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE @@ -476,7 +493,7 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  		mRegionName->setText(name);  	} -	if (mCurrentTitle != getString("title_landmark")) +	if (mInfoType == CREATE_LANDMARK)  	{  		mTitleEditor->setText(parcel_data.name);  		mNotesEditor->setText(LLStringUtil::null); @@ -517,10 +534,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,  void LLPanelPlaceInfo::displayAgentParcelInfo()  { -	mPosRegion = gAgent.getPositionAgent(); +	mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection(); -	LLViewerRegion* region = gAgent.getRegion(); -	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +	LLParcel* parcel = mParcel->getParcel(); +	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();  	if (!region || !parcel)  		return; @@ -547,13 +564,6 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()  	default:  		parcel_data.flags = 0;  	} -	 -	// Adding "For Sale" flag in remote parcel response format. -	if (parcel->getForSale()) -	{ -		parcel_data.flags |= DFQ_FOR_SALE; -	} -	  	parcel_data.desc = parcel->getDesc();  	parcel_data.name = parcel->getName();  	parcel_data.sim_name = gAgent.getRegion()->getName(); @@ -563,75 +573,68 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()  	parcel_data.global_y = global_pos.mdV[1];  	parcel_data.global_z = global_pos.mdV[2]; +	mPosRegion = gAgent.getPositionAgent(); +  	processParcelInfo(parcel_data); +	std::string on = getString("on"); +	std::string off = getString("off"); +  	// Processing parcel characteristics  	if (parcel->getParcelFlagAllowVoice())  	{ -		mVoiceIcon->setValue("places_voice_on.tga"); -		mVoiceText->setText(getString("on")); +		mVoiceText->setText(on);  	}  	else  	{ -		mVoiceIcon->setValue("places_voice_off.tga"); -		mVoiceText->setText(getString("off")); +		mVoiceText->setText(off);  	}  	if (!region->getBlockFly() && parcel->getAllowFly())  	{ -		mFlyIcon->setValue("places_fly_on.tga"); -		mFlyText->setText(getString("on")); +		mFlyText->setText(on);  	}  	else  	{ -		mFlyIcon->setValue("places_fly_off.tga"); -		mFlyText->setText(getString("off")); +		mFlyText->setText(off);  	}  	if (region->getRestrictPushObject() || parcel->getRestrictPushObject())  	{ -		mPushIcon->setValue("places_push_off.tga"); -		mPushText->setText(getString("off")); +		mPushText->setText(off);  	}  	else  	{ -		mPushIcon->setValue("places_push_on.tga"); -		mPushText->setText(getString("on")); +		mPushText->setText(on);  	}  	if (parcel->getAllowModify())  	{ -		mBuildIcon->setValue("places_build_on.tga"); -		mBuildText->setText(getString("on")); +		mBuildText->setText(on);  	}  	else  	{ -		mBuildIcon->setValue("places_build_off.tga"); -		mBuildText->setText(getString("off")); +		mBuildText->setText(off);  	}  	if((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) ||  	   (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) ||  	   !parcel->getAllowOtherScripts())  	{ -		mScriptsIcon->setValue("places_scripts_off.tga"); -		mScriptsText->setText(getString("off")); +		mScriptsText->setText(off);  	}  	else  	{ -		mScriptsIcon->setValue("places_scripts_on.tga"); -		mScriptsText->setText(getString("on")); +		mScriptsText->setText(on);  	}  	if (region->getAllowDamage() || parcel->getAllowDamage())  	{ -		mDamageIcon->setValue("places_damage_on.tga"); -		mDamageText->setText(getString("on")); +		mDamageText->setText(on);  	}  	else  	{ -		mDamageIcon->setValue("places_damage_off.tga"); -		mDamageText->setText(getString("off")); +		mDamageText->setText(off);  	}  	mRegionNameText->setText(region->getName()); @@ -656,7 +659,8 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()  				gCacheName->get(parcel->getGroupID(), TRUE,  								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionGroupText, _2, _3)); -				mParcelOwner->setText(mRegionGroupText->getText()); +				gCacheName->get(parcel->getGroupID(), TRUE, +								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mParcelOwner, _2, _3));  			}  			else  			{ @@ -681,6 +685,98 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()  	}  	mEstateRatingText->setText(region->getSimAccessString()); + +	S32 area; +	S32 claim_price; +	S32 rent_price; +	F32 dwell; +	BOOL for_sale = parcel->getForSale(); +	LLViewerParcelMgr::getInstance()->getDisplayInfo(&area, +													 &claim_price, +													 &rent_price, +													 &for_sale, +													 &dwell); + +	if (for_sale) +	{ +		// Adding "For Sale" flag in remote parcel response format. +		parcel_data.flags |= DFQ_FOR_SALE; + +		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); +		if(auth_buyer_id.notNull()) +		{ +			gCacheName->get(auth_buyer_id, TRUE, +							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mSaleToText, _2, _3)); + +			// Show sales info to a specific person or a group he belongs to. +			if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id)) +			{ +				for_sale = FALSE; +			} +		} +		else +		{ +			mSaleToText->setText(getString("anyone")); +		} + +		const U8* sign = (U8*)getString("price_text").c_str(); +		const U8* sqm = (U8*)getString("area_text").c_str(); + +		mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice())); +		mAreaText->setText(llformat("%d %s", area, sqm)); +		mTrafficText->setText(llformat("%.0f", dwell)); + +		// Can't have more than region max tasks, regardless of parcel +		// object bonus factor. +		S32 primitives = llmin(llround(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()), +							   (S32)region->getMaxTasks()); + +		const U8* available = (U8*)getString("available").c_str(); +		const U8* allocated = (U8*)getString("allocated").c_str(); + +		mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated)); + +		if (parcel->getAllowOtherScripts()) +		{ +			mParcelScriptsText->setText(getString("all_residents_text")); +		} +		else if (parcel->getAllowGroupScripts()) +		{ +			mParcelScriptsText->setText(getString("group_text")); +		} +		else +		{ +			mParcelScriptsText->setText(off); +		} + +		mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off); + +		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) +		{ +			mSubdivideText->setText(getString("can_change")); +		} +		else +		{ +			mSubdivideText->setText(getString("can_not_change")); +		} +		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) +		{ +			mResaleText->setText(getString("can_not_resell")); +		} +		else +		{ +			mResaleText->setText(getString("can_resell")); +		} +	} + +	getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale); +} + +// virtual +void LLPanelPlaceInfo::changed() +{ +	resetLocation(); +	displayAgentParcelInfo();  }  void LLPanelPlaceInfo::updateEstateName(const std::string& name) @@ -698,6 +794,22 @@ void LLPanelPlaceInfo::updateCovenantText(const std::string &text)  	mCovenantText->setText(text);  } +void LLPanelPlaceInfo::updateLastVisitedText(const LLDate &date) +{ +	if (date.isNull()) +	{ +		mLastVisited->setText(getString("unknown")); +	} +	else +	{ +		std::string timeStr = getString("acquired_date"); +		LLSD substitution; +		substitution["datetime"] = (S32) date.secondsSinceEpoch(); +		LLStringUtil::format (timeStr, substitution); +		mLastVisited->setText(timeStr); +	} +} +  void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)  {  	LLInventoryItem* item = gInventory.getItem(mLandmarkID); @@ -785,6 +897,7 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)  	LLAvatarPropertiesProcessor::instance().sendDataUpdate(&pick_data, APT_PICK_INFO);  } +// virtual  void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)  {  	if (mMinHeight > 0 && mScrollingPanel != NULL) @@ -794,3 +907,22 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)  	LLView::reshape(width, height, called_from_parent);  } + +// virtual +void LLPanelPlaceInfo::handleVisibilityChange (BOOL new_visibility) +{ +	LLPanel::handleVisibilityChange(new_visibility); + +	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); +	if (!parcel_mgr) +		return; + +	// Remove land selection when panel hides. +	if (!new_visibility) +	{ +		if (!parcel_mgr->selectionEmpty()) +		{ +			parcel_mgr->deselectLand(); +		} +	} +} diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 0cdeaab2b7..60f35cd0c1 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -42,15 +42,17 @@  #include "llpanelmedia.h"  #include "llremoteparcelrequest.h" +#include "llviewerparcelmgr.h"  class LLButton;  class LLInventoryItem;  class LLLineEditor; +class LLParcelSelection;  class LLTextBox;  class LLTextEditor;  class LLTextureCtrl; -class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver +class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObserver  {  public:  	enum INFO_TYPE @@ -105,9 +107,13 @@ public:  	// without sending a request to the server.  	void displayAgentParcelInfo(); +	// Called on parcel selection change by LLViewerParcelMgr. +	/*virtual*/ void changed(); +  	void updateEstateName(const std::string& name);  	void updateEstateOwnerName(const std::string& name);  	void updateCovenantText(const std::string &text); +	void updateLastVisitedText(const LLDate &date);  	void nameUpdatedCallback(LLTextBox* text,  							 const std::string& first, @@ -115,6 +121,7 @@ public:  	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); +	/*virtual*/ void handleVisibilityChange (BOOL new_visibility);  private:  	enum LANDMARK_INFO_TYPE @@ -131,30 +138,23 @@ private:  	LLVector3		mPosRegion;  	std::string		mCurrentTitle;  	S32				mMinHeight; +	INFO_TYPE 		mInfoType;  	LLTextBox*			mTitle;  	LLTextureCtrl*		mSnapshotCtrl;  	LLTextBox*			mRegionName;  	LLTextBox*			mParcelName;  	LLTextEditor*		mDescEditor; -	LLIconCtrl*			mMaturityRatingIcon;  	LLTextBox*			mMaturityRatingText;  	LLTextBox*			mParcelOwner;  	LLTextBox*			mLastVisited; -	LLIconCtrl*			mRatingIcon;  	LLTextBox*			mRatingText; -	LLIconCtrl*			mVoiceIcon;  	LLTextBox*			mVoiceText; -	LLIconCtrl*			mFlyIcon;  	LLTextBox*			mFlyText; -	LLIconCtrl*			mPushIcon;  	LLTextBox*			mPushText; -	LLIconCtrl*			mBuildIcon;  	LLTextBox*			mBuildText; -	LLIconCtrl*			mScriptsIcon;  	LLTextBox*			mScriptsText; -	LLIconCtrl*			mDamageIcon;  	LLTextBox*			mDamageText;  	LLTextBox*			mRegionNameText; @@ -168,6 +168,16 @@ private:  	LLTextBox*			mEstateOwnerText;  	LLTextEditor*		mCovenantText; +	LLTextBox*			mSalesPriceText; +	LLTextBox*			mAreaText; +	LLTextBox*			mTrafficText; +	LLTextBox*			mPrimitivesText; +	LLTextBox*			mParcelScriptsText; +	LLTextBox*			mTerraformLimitsText; +	LLTextEditor*		mSubdivideText; +	LLTextEditor*		mResaleText; +	LLTextBox*			mSaleToText; +  	LLTextBox*			mOwner;  	LLTextBox*			mCreator;  	LLTextBox*			mCreated; @@ -176,6 +186,8 @@ private:  	LLPanel*            mScrollingPanel;  	LLPanel*			mInfoPanel;  	LLMediaPanel*		mMediaPanel; + +	LLSafeHandle<LLParcelSelection>	mParcel;  };  #endif // LL_LLPANELPLACEINFO_H diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 2aebfdabfa..bc740bd865 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -51,6 +51,7 @@  #include "llpanellandmarks.h"  #include "llpanelteleporthistory.h"  #include "llsidetray.h" +#include "llteleporthistorystorage.h"  #include "lltoggleablemenu.h"  #include "llviewerinventory.h"  #include "llviewermenu.h" @@ -172,8 +173,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	if (mPlaceInfoType == AGENT_INFO_TYPE)  	{  		mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT); -		mPlaceInfo->displayAgentParcelInfo(); -		 +  		mPosGlobal = gAgent.getPositionGlobal();  	}  	else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) @@ -212,14 +212,15 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	{  		S32 index = key["id"].asInteger(); -		const LLTeleportHistory::slurl_list_t& hist_items = -			LLTeleportHistory::getInstance()->getItems(); +		const LLTeleportHistoryStorage::slurl_list_t& hist_items = +					LLTeleportHistoryStorage::getInstance()->getItems();  		mPosGlobal = hist_items[index].mGlobalPos;  		mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); +		mPlaceInfo->updateLastVisitedText(hist_items[index].mDate);  		mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal), -									  hist_items[index].mRegionID, +									  LLUUID(),  									  mPosGlobal);  	}  } diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 8b378c33e3..df48ee5d08 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -37,6 +37,7 @@  #include "llpanelteleporthistory.h"  #include "llsidetray.h"  #include "llworldmap.h" +#include "llteleporthistorystorage.h"  // Not yet implemented; need to remove buildPanel() from constructor when we switch  //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history"); @@ -56,7 +57,7 @@ LLTeleportHistoryPanel::~LLTeleportHistoryPanel()  BOOL LLTeleportHistoryPanel::postBuild()  { -	mTeleportHistory = LLTeleportHistory::getInstance(); +	mTeleportHistory = LLTeleportHistoryStorage::getInstance();  	if (mTeleportHistory)  	{  		mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this)); @@ -92,9 +93,7 @@ void LLTeleportHistoryPanel::onShowOnMap()  	S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); -	const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems(); - -	LLVector3d global_pos = hist_items[index].mGlobalPos; +	LLVector3d global_pos = mTeleportHistory->getItems()[index].mGlobalPos;  	if (!global_pos.isExactlyZero())  	{ @@ -153,7 +152,7 @@ void LLTeleportHistoryPanel::updateVerbs()  	if (itemp)  	{  		index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); -		cur_item = mTeleportHistory->getCurrentItemIndex(); +		cur_item = mTeleportHistory->getItems().size() - 1;  	}  	mTeleportBtn->setEnabled(index != cur_item); @@ -162,13 +161,11 @@ void LLTeleportHistoryPanel::updateVerbs()  void LLTeleportHistoryPanel::showTeleportHistory()  { -	const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems(); +	const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems();  	mHistoryItems->deleteAllItems(); -	S32 cur_item = mTeleportHistory->getCurrentItemIndex(); - -	for (LLTeleportHistory::slurl_list_t::const_iterator iter = hist_items.begin(); +	for (LLTeleportHistoryStorage::slurl_list_t::const_iterator iter = hist_items.begin();  				iter != hist_items.end(); ++iter)  	{  		std::string landmark_title = (*iter).mTitle; @@ -181,7 +178,6 @@ void LLTeleportHistoryPanel::showTeleportHistory()  			continue;  		S32 index = iter - hist_items.begin(); -  		LLSD row;  		row["id"] = index; @@ -201,14 +197,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()  		index_column["value"] = index;  		mHistoryItems->addElement(row, ADD_TOP); - -		if (cur_item == index) -		{ -			LLScrollListItem* itemp = mHistoryItems->getItem(index); -			((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD); -		}  	} +	// Consider last item (most recent) as current +	LLScrollListItem* itemp = mHistoryItems->getItem((S32)hist_items.size() - 1); +	((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD); +  	updateVerbs();  } diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index 553385b37e..023b04c3fa 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -39,6 +39,8 @@  #include "llpanelplacestab.h"  #include "llteleporthistory.h" +class LLTeleportHistoryStorage; +  class LLTeleportHistoryPanel : public LLPanelPlacesTab  {  public: @@ -65,7 +67,7 @@ private:  		LIST_INDEX  	}; -	LLTeleportHistory*		mTeleportHistory; +	LLTeleportHistoryStorage*	mTeleportHistory;  	LLScrollListCtrl*		mHistoryItems;  	std::string				mFilterSubString;  }; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 68996673be..1fbe359295 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -88,9 +88,12 @@ void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)  //--------------------------------------------------------------------------  void LLScreenChannel::addToast(LLToast::Params p)  { -	bool store_toast = !mShowToasts && p.can_be_stored && mCanStoreToasts; +	bool store_toast = false, show_toast = false; -	if(!mShowToasts && !store_toast) +	show_toast = mShowToasts || p.force_show; +	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts; + +	if(!show_toast && !store_toast)  	{  		mOnRejectToast(p);  		return; @@ -106,7 +109,7 @@ void LLScreenChannel::addToast(LLToast::Params p)  		new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));  	} -	if(mShowToasts) +	if(show_toast)  	{  		mToastList.push_back(new_toast_elem);  		showToasts(); diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp new file mode 100644 index 0000000000..c903f40f3f --- /dev/null +++ b/indra/newview/llsearchcombobox.cpp @@ -0,0 +1,250 @@ +/** + * @file llsearchcombobox.cpp + * @brief Search Combobox implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llsearchcombobox.h" + +#include "llkeyboard.h" +#include "lluictrlfactory.h" + +static LLDefaultChildRegistry::Register<LLSearchComboBox> r1("search_combo_box"); + +class LLSearchHistoryBuilder +{ +public: +	LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter); + +	virtual void buildSearchHistory(); + +	virtual ~LLSearchHistoryBuilder(){} + +protected: + +	virtual bool filterSearchHistory(); + +	LLSearchComboBox* mComboBox; +	std::string mFilter; +	LLSearchHistory::search_history_list_t mFilteredSearchHistory; +}; + +LLSearchComboBox::Params::Params() +: search_button("search_button") +, dropdown_button_visible("dropdown_button_visible", false) +{ +} + +LLSearchComboBox::LLSearchComboBox(const Params&p) +: LLComboBox(p) +{ +	S32 btn_top = p.search_button.top_pad + p.search_button.rect.height; +	S32 btn_right = p.search_button.rect.width + p.search_button.left_pad; +	LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad); + +	LLButton::Params button_params(p.search_button); +	button_params.name(std::string("search_btn")); +	button_params.rect(search_btn_rect) ; +	button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP); +	button_params.tab_stop(false); +	button_params.click_callback.function(boost::bind(&LLSearchComboBox::onSelectionCommit, this)); +	mSearchButton = LLUICtrlFactory::create<LLButton>(button_params); +	mTextEntry->addChild(mSearchButton); + +	setButtonVisible(p.dropdown_button_visible); +	mTextEntry->setCommitCallback(boost::bind(&LLComboBox::onTextCommit, this, _2)); +	mTextEntry->setKeystrokeCallback(boost::bind(&LLComboBox::onTextEntry, this, _1), NULL); +	setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this)); +	setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2)); +} + +void LLSearchComboBox::rebuildSearchHistory(const std::string& filter) +{ +	LLSearchHistoryBuilder builder(this, filter); +	builder.buildSearchHistory(); +} + +void LLSearchComboBox::onSearchPrearrange(const LLSD& data) +{ +	std::string filter = data.asString(); +	rebuildSearchHistory(filter); + +	mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item. +} + +void LLSearchComboBox::onTextEntry(LLLineEditor* line_editor) +{ +	KEY key = gKeyboard->currentKey(); + +	if (line_editor->getText().empty()) +	{ +		prearrangeList(); // resets filter +		hideList(); +	} +	// Typing? (moving cursor should not affect showing the list) +	else if (key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) +	{ +		prearrangeList(line_editor->getText()); +		if (mList->getItemCount() != 0) +		{ +			showList(); +			focusTextEntry(); +		} +		else +		{ +			// Hide the list if it's empty. +			hideList(); +		} +	} +	LLComboBox::onTextEntry(line_editor); +} + +void LLSearchComboBox::focusTextEntry() +{ +	// We can't use "mTextEntry->setFocus(TRUE)" instead because +	// if the "select_on_focus" parameter is true it places the cursor +	// at the beginning (after selecting text), thus screwing up updateSelection(). +	if (mTextEntry) +	{ +		gFocusMgr.setKeyboardFocus(mTextEntry); +	} +} + +void LLSearchComboBox::hideList() +{ +	LLComboBox::hideList(); +	if (mTextEntry && hasFocus()) +		focusTextEntry(); +} + +LLSearchComboBox::~LLSearchComboBox() +{ +} + +void LLSearchComboBox::onSelectionCommit() +{ +	std::string search_query = getSimple(); +	LLStringUtil::trim(search_query); +	if(search_query.empty()) +	{ +		mTextEntry->setText(search_query); +		setControlValue(search_query); + +		return; +	} + +	remove(search_query); +	add(search_query, ADD_TOP); +	mTextEntry->setText(search_query); +	setControlValue(search_query); + +	LLUICtrl::onCommit(); +} + +BOOL LLSearchComboBox::remove(const std::string& name) +{ +	BOOL found = mList->selectItemByLabel(name, FALSE); + +	if (found) +	{ +		LLScrollListItem* item = mList->getFirstSelected(); +		if (item) +		{ +			LLComboBox::remove(mList->getItemIndex(item)); +		} +	} + +	return found; +} + +void LLSearchComboBox::clearHistory() +{ +	removeall(); +	setTextEntry(LLStringUtil::null); +} + +LLSearchHistoryBuilder::LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter) +: mComboBox(combo_box) +, mFilter(filter) +{ +} + +bool LLSearchHistoryBuilder::filterSearchHistory() +{ +	// *TODO: an STL algorithm would look nicer +	mFilteredSearchHistory.clear(); + +	std::string filter_copy = mFilter; +	LLStringUtil::toLower(filter_copy); + +	LLSearchHistory::search_history_list_t history =  +		LLSearchHistory::getInstance()->getSearchHistoryList(); + +	LLSearchHistory::search_history_list_t::const_iterator it = history.begin(); +	for ( ; it != history.end(); ++it) +	{ +		std::string search_query = (*it).search_query; +		LLStringUtil::toLower(search_query); + +		if (search_query.find(filter_copy) != std::string::npos) +			mFilteredSearchHistory.push_back(*it); +	} + +	return mFilteredSearchHistory.size(); +} + +void LLSearchHistoryBuilder::buildSearchHistory() +{ +	mFilteredSearchHistory.clear(); + +	LLSearchHistory::search_history_list_t filtered_items; +	LLSearchHistory::search_history_list_t* itemsp = NULL; +	LLSearchHistory* sh = LLSearchHistory::getInstance(); + +	if (mFilter.empty()) +	{ +		itemsp = &sh->getSearchHistoryList(); +	} +	else +	{ +		filterSearchHistory(); +		itemsp = &mFilteredSearchHistory; +		itemsp->sort(); +	} + +	mComboBox->removeall(); + +	LLSearchHistory::search_history_list_t::const_iterator it = itemsp->begin(); +	for ( ; it != itemsp->end(); it++) +	{ +		LLSearchHistory::LLSearchHistoryItem item = *it; +		mComboBox->add(item.search_query); +	} +} diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h new file mode 100644 index 0000000000..38f9a5a26b --- /dev/null +++ b/indra/newview/llsearchcombobox.h @@ -0,0 +1,108 @@ +/**  + * @file llsearchcombobox.h + * @brief LLSearchComboBox class definition + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSEARCHCOMBOBOX_H +#define LL_LLSEARCHCOMBOBOX_H + +#include "llcombobox.h" +#include "llsearchhistory.h" + +/** + * Search control with text box for search queries and a drop down list + * with recent queries. Supports text auto-complete and filtering of drop down list + * according to typed text. + */ +class LLSearchComboBox : public LLComboBox +{ +public: + +	struct Params :	public LLInitParam::Block<Params, LLComboBox::Params> +	{ +		Optional<LLButton::Params> search_button; +		Optional<bool> dropdown_button_visible; + +		Params(); +	}; + +	/** +	 * Removes an entry from combo box, case insensitive +	 */ +	BOOL remove(const std::string& name); + +	/** +	 * Clears search history +	 */ +	void clearHistory(); + +	~LLSearchComboBox(); + +protected: + +	LLSearchComboBox(const Params&p); +	friend class LLUICtrlFactory; + +	/** +	 * Handles typing in text box +	 */ +	void onTextEntry(LLLineEditor* line_editor); + +	/** +	 * Hides drop down list and focuses text box +	 */ +	void hideList(); + +	/** +	 * Rebuilds search history, case insensitive +	 * If filter is an empty string - whole history will be added to combo box +	 * if filter is valid string - only matching entries will be added +	 */ +	virtual void rebuildSearchHistory(const std::string& filter); + +	/** +	 * Callback for prearrange event +	 */ +	void onSearchPrearrange(const LLSD& data); + +	/** +	 * Callback for text box or combo box commit +	 */ +	void onSelectionCommit(); + +	/** +	 * Sets focus to text box +	 */ +	void focusTextEntry(); + +	LLButton* mSearchButton; +}; + +#endif //LL_LLSEARCHCOMBOBOX_H diff --git a/indra/newview/llsearchhistory.cpp b/indra/newview/llsearchhistory.cpp new file mode 100644 index 0000000000..d45a1efa0e --- /dev/null +++ b/indra/newview/llsearchhistory.cpp @@ -0,0 +1,154 @@ +/** + * @file llsearchhistory.cpp + * @brief Search history container implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llsearchhistory.h" + +#include "llfile.h" +#include "llsdserialize.h" +#include "llxmlnode.h" + +std::string LLSearchHistory::SEARCH_QUERY = "search_query"; +std::string LLSearchHistory::SEARCH_HISTORY_FILE_NAME = "search_history.txt"; + +LLSearchHistory::LLSearchHistory() +{ + +} + +bool LLSearchHistory::load() +{ +	// build filename for each user +	std::string resolved_filename = getHistoryFilePath(); +	llifstream file(resolved_filename); +	if (!file.is_open()) +	{ +		return false; +	} + +	clearHistory(); + +	// add each line in the file to the list +	std::string line; +	LLPointer<LLSDParser> parser = new LLSDNotationParser(); +	while (std::getline(file, line))  +	{ +		LLSD s_item; +		std::istringstream iss(line); +		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) +		{ +			break; +		} + +		mSearchHistory.push_back(s_item); +	} + +	file.close(); + +	return true; +} + +bool LLSearchHistory::save() +{ +	// build filename for each user +	std::string resolved_filename = getHistoryFilePath(); +	// open a file for writing +	llofstream file (resolved_filename); +	if (!file.is_open()) +	{ +		return false; +	} + +	search_history_list_t::const_iterator it = mSearchHistory.begin(); +	for (; mSearchHistory.end() != it; ++it) +	{ +		file << LLSDOStreamer<LLSDNotationFormatter>((*it).toLLSD()) << std::endl; +	} + +	file.close(); +	return true; +} + +std::string LLSearchHistory::getHistoryFilePath() +{ +	return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SEARCH_HISTORY_FILE_NAME); +} + +void LLSearchHistory::addEntry(const std::string& search_query) +{ +	if(search_query.empty()) +	{ +		return; +	} + +	search_history_list_t::iterator it =  +		find(mSearchHistory.begin(), mSearchHistory.end(), search_query); + +	if(mSearchHistory.end() != it) +	{ +		mSearchHistory.erase(it); +	} + +	LLSearchHistoryItem item(search_query); +	mSearchHistory.push_front(item); +} + +bool LLSearchHistory::LLSearchHistoryItem::operator < (const LLSearchHistory::LLSearchHistoryItem& right) +{ +	S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query); + +	return result < 0; +} + +bool LLSearchHistory::LLSearchHistoryItem::operator > (const LLSearchHistory::LLSearchHistoryItem& right) +{ +	S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query); + +	return result > 0; +} + +bool LLSearchHistory::LLSearchHistoryItem::operator==(const LLSearchHistory::LLSearchHistoryItem& right) +{ +	return 0 == LLStringUtil::compareInsensitive(search_query, right.search_query); +} + +bool LLSearchHistory::LLSearchHistoryItem::operator==(const std::string& right) +{ +	return 0 == LLStringUtil::compareInsensitive(search_query, right); +} + +LLSD LLSearchHistory::LLSearchHistoryItem::toLLSD() const +{ +	LLSD ret; +	ret[SEARCH_QUERY] = search_query; +	return ret; +} diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h new file mode 100644 index 0000000000..253ef21e9e --- /dev/null +++ b/indra/newview/llsearchhistory.h @@ -0,0 +1,138 @@ +/**  + * @file llsearchhistory.h + * @brief Search history container definition + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSEARCHHISTORY_H +#define LL_LLSEARCHHISTORY_H + +#include "llsingleton.h" +/** + * Search history container able to save and load history from file. + * History is stored in chronological order, most recent at the beginning. + */ +class LLSearchHistory : public LLSingleton<LLSearchHistory> +{ +public: + +	// Forward declaration +	class LLSearchHistoryItem; + +	// Search history container +	typedef std::list<LLSearchHistoryItem>	search_history_list_t; + +	/** +	 * Saves search history to file +	 */ +	bool save(); + +	/** +	 * loads search history from file +	 */ +	bool load(); + +	/** +	 * Returns search history list +	 */ +	search_history_list_t& getSearchHistoryList() { return mSearchHistory; } + +	/** +	 * Deletes all search history queries from list. +	 */ +	void clearHistory() { mSearchHistory.clear(); } + +	/** +	 * Adds unique entry to front of search history list, case insensitive +	 * If entry is already in list, it will be deleted and added to front. +	 */ +	void addEntry(const std::string& search_text); + +	LLSearchHistory(); + +	/** +	 * Class for storing data about single search request. +	 */ +	class LLSearchHistoryItem +	{ +	public: + +		LLSearchHistoryItem() +		{} + +		LLSearchHistoryItem(const std::string& query) +			: search_query(query) +		{} + +		LLSearchHistoryItem(const LLSD& item) +		{ +			if(item.has(SEARCH_QUERY)) +				search_query = item[SEARCH_QUERY].asString(); +		} + +		std::string search_query; + +		/** +		 * Allows std::list sorting +		 */ +		bool operator < (const LLSearchHistory::LLSearchHistoryItem& right); + +		/** +		 * Allows std::list sorting +		 */ +		bool operator > (const LLSearchHistory::LLSearchHistoryItem& right); + +		bool operator==(const LLSearchHistoryItem& right); + +		bool operator==(const std::string& right); + +		/** +		 * Serializes search history item to LLSD +		 */ +		LLSD toLLSD() const; +	}; + +protected: + +	/** +	 * Returns path to search history file. +	 */ +	std::string getHistoryFilePath(); + +	static std::string SEARCH_HISTORY_FILE_NAME; +	static std::string SEARCH_QUERY; + +private: + +	search_history_list_t mSearchHistory; +}; + +class LLSearchComboBox; + +#endif //LL_LLSEARCHHISTORY_H diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index afa8e5f072..381e63f020 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -241,6 +241,13 @@ LLSideTray::LLSideTray(Params& params)  	    ,mMaxBarWidth(params.rect.width)  {  	mCollapsed=params.collapsed; + + +	LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar(); + +	// register handler function to process data from the xml.  +	// panel_name should be specified via "parameter" attribute. +	commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6c0481feaa..8fb0f201cb 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -899,6 +899,10 @@ bool idle_startup()  	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())  	{ +		// Move the progress view in front of the UI immediately when login is performed +		// this allows not to see main menu after Alt+Tab was pressed while login. EXT-744. +		gViewerWindow->moveProgressViewToFront(); +  		//reset the values that could have come in from a slurl  		if (!gLoginHandler.getWebLoginKey().isNull())  		{ diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 15d77dbf88..7ddbf0a744 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -38,9 +38,9 @@  #include "llviewercontrol.h"  #include "llviewerwindow.h" +#include "llchiclet.h"  //--------------------------------------------------------------------------------- -LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()), -													mSysWell(NULL), +LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key),  													mChannel(NULL),  													mScrollContainer(NULL),  													mNotificationList(NULL) @@ -57,13 +57,9 @@ BOOL LLSysWellWindow::postBuild()  	mNotificationList = getChild<LLScrollingPanelList>("notification_list");  	mIMRowList = getChild<LLScrollingPanelList>("im_row_panel_list"); -	gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized  	mScrollContainer->setBorderVisible(FALSE); -	mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); - - -	return TRUE; +	return LLDockableFloater::postBuild();  }  //--------------------------------------------------------------------------------- @@ -82,7 +78,6 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)  	LLSysWellItem* new_item = new LLSysWellItem(p);  	mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item));  	reshapeWindow(); -	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized  	new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));  	new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1)); @@ -127,10 +122,6 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)  		return;  	reshapeWindow(); -	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized - -	// hide chiclet window if there are no items left -	setVisible(!isWindowEmpty());  }  //--------------------------------------------------------------------------------- @@ -148,11 +139,20 @@ void LLSysWellWindow::onItemClose(LLSysWellItem* item)  	removeItemByID(id);  	if(mChannel)  		mChannel->killToastByNotificationID(id); + +	// hide chiclet window if there are no items left +	setVisible(!isWindowEmpty());  }  //---------------------------------------------------------------------------------  void LLSysWellWindow::toggleWindow()  { +	if (getDockControl() == NULL) +	{ +		setDockControl(new LLDockControl( +				LLBottomTray::getInstance()->getSysWell(), this, +				getDockTongue(), LLDockControl::TOP, isDocked())); +	}  	setVisible(!getVisible());  } @@ -162,12 +162,20 @@ void LLSysWellWindow::setVisible(BOOL visible)  	// on Show adjust position of SysWell chiclet's window  	if(visible)  	{ +		if (LLBottomTray::instanceExists()) +		{ +			LLBottomTray::getInstance()->getSysWell()->setToggleState(TRUE); +		}  		if(mChannel)  			mChannel->removeAndStoreAllVisibleToasts(); - -		adjustWindowPosition();	// *TODO: won't be necessary after docking is realized  	} - +	else +	{ +		if (LLBottomTray::instanceExists()) +		{ +			LLBottomTray::getInstance()->getSysWell()->setToggleState(FALSE); +		} +	}  	if(mChannel)  		mChannel->setShowToasts(!visible); @@ -175,16 +183,6 @@ void LLSysWellWindow::setVisible(BOOL visible)  }  //--------------------------------------------------------------------------------- -void LLSysWellWindow::adjustWindowPosition()	// *TODO: won't be necessary after docking is realized -{ -	const S32 WINDOW_MARGIN	= 5; - -	LLRect btm_rect = LLBottomTray::getInstance()->getRect(); -	LLRect this_rect = getRect(); -	setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN);  -} - -//---------------------------------------------------------------------------------  void LLSysWellWindow::reshapeWindow()  {  	// Get size for scrollbar and floater's header @@ -272,7 +270,6 @@ void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,  {  	mIMRowList->addPanel(new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId)); -	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized  }  //--------------------------------------------------------------------------------- @@ -286,14 +283,12 @@ void LLSysWellWindow::delIMRow(const LLUUID& sessionId)  	// hide chiclet window if there are no items left  	setVisible(!isWindowEmpty()); - -	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized  }  //---------------------------------------------------------------------------------  bool LLSysWellWindow::isWindowEmpty()  { -	if(mIMRowList->getPanelList().size() == 0 && mNotificationList->getPanelList().size() == 0) +	if(mIMRowList->getPanelList().size() == 0 && LLBottomTray::getInstance()->getSysWell()->getCounter() == 0)  	{  		return true;  	} @@ -328,7 +323,7 @@ void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId)  {  	delIMRow(sessionId);  	reshapeWindow(); -	mSysWell->updateUreadIMNotifications(); +	LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();  }  //--------------------------------------------------------------------------------- @@ -396,5 +391,3 @@ void LLSysWellWindow::RowPanel::updatePanel(BOOL allow_modify)  }  //--------------------------------------------------------------------------------- - - diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index d9fdf77a04..ef0974b428 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -35,7 +35,7 @@  #include "llsyswellitem.h" -#include "llfloater.h" +#include "lldockablefloater.h"  #include "llbutton.h"  #include "llscreenchannel.h"  #include "llscrollcontainer.h" @@ -46,7 +46,7 @@ -class LLSysWellWindow : public LLFloater, LLIMSessionObserver +class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver  {  public:      LLSysWellWindow(const LLSD& key); @@ -58,7 +58,6 @@ public:  	// change attributes  	void setChannel(LLNotificationsUI::LLScreenChannel*	channel) {mChannel = channel;} -	void setSysWell(LLNotificationChiclet*	sys_well) {mSysWell = sys_well;}  	// Operating with items  	void addItem(LLSysWellItem::Params p); @@ -93,9 +92,6 @@ private:  	// pointer to a corresponding channel's instance  	LLNotificationsUI::LLScreenChannel*	mChannel; - -	LLNotificationChiclet*	mSysWell; -	LLUIImagePtr			mDockTongue;  	LLPanel*				mTwinListPanel;  	LLScrollContainer*		mScrollContainer;  	LLScrollingPanelList*	mIMRowList; diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index b31edf1e5d..0bb5a727e0 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -37,8 +37,11 @@  #include "llsd.h"  #include "llsdserialize.h"  #include "lldir.h" +#include "llteleporthistory.h" +#include "llagent.h" -static LLTeleportHistoryStorage tpstorage; +// Max offset for two global positions to consider them as equal +const F64 MAX_GLOBAL_POS_OFFSET = 5.0f;  LLTeleportHistoryPersistentItem::LLTeleportHistoryPersistentItem(const LLSD& val)  { @@ -58,15 +61,42 @@ LLSD LLTeleportHistoryPersistentItem::toLLSD() const  	return val;  } +struct LLSortItemsByDate +{ +	bool operator()(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b) +	{ +		return a.mDate < b.mDate; +	} +}; +  LLTeleportHistoryStorage::LLTeleportHistoryStorage() :  	mFilename("teleport_history.txt")  { +	LLTeleportHistory *th = LLTeleportHistory::getInstance(); +	if (th) +		th->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryStorage::onTeleportHistoryChange, this));	 + +	load();  }  LLTeleportHistoryStorage::~LLTeleportHistoryStorage()  {  } +void LLTeleportHistoryStorage::onTeleportHistoryChange() +{ +	LLTeleportHistory *th = LLTeleportHistory::getInstance(); +	if (!th) +		return; + +	const LLTeleportHistoryItem &item = th->getItems()[th->getCurrentItemIndex()]; + +	addItem(item.mTitle, item.mGlobalPos); +	save(); + +	mHistoryChangedSignal(); +} +  void LLTeleportHistoryStorage::purgeItems()  {  	mItems.clear(); @@ -74,12 +104,45 @@ void LLTeleportHistoryStorage::purgeItems()  void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos)  { -	mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos)); +	addItem(title, global_pos, LLDate::now()); +} + + +bool LLTeleportHistoryStorage::compareByTitleAndGlobalPos(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b) +{ +	return a.mTitle == b.mTitle && (a.mGlobalPos - b.mGlobalPos).length() < MAX_GLOBAL_POS_OFFSET;  }  void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date)  { -	mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos, date)); + +	LLTeleportHistoryPersistentItem item(title, global_pos, date); + +	slurl_list_t::iterator item_iter = std::find_if(mItems.begin(), mItems.end(), +							    boost::bind(&LLTeleportHistoryStorage::compareByTitleAndGlobalPos, this, _1, item)); + +	// If there is such item already, remove it, since new item is more recent +	if (item_iter != mItems.end()) +	{ +		mItems.erase(item_iter); +	} + +	mItems.push_back(item); + +	// Check whether sorting is needed +	if (mItems.size() > 1) +	{ +		item_iter = mItems.end(); + +		item_iter--; +		item_iter--; + +		// If second to last item is more recent than last, then resort items +		if (item_iter->mDate > item.mDate) +		{ +			std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate()); +		} +	}  }  void LLTeleportHistoryStorage::removeItem(S32 idx) @@ -145,6 +208,8 @@ void LLTeleportHistoryStorage::load()  	}  	file.close(); + +	std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());  }  void LLTeleportHistoryStorage::dump() const @@ -162,3 +227,30 @@ void LLTeleportHistoryStorage::dump() const  	}  } +boost::signals2::connection LLTeleportHistoryStorage::setHistoryChangedCallback(history_callback_t cb) +{ +	return mHistoryChangedSignal.connect(cb); +} + +void LLTeleportHistoryStorage::goToItem(S32 idx) + +{ +	// Validate specified index. +	if (idx < 0 || idx >= (S32)mItems.size()) +	{ +		llwarns << "Invalid teleport history index (" << idx << ") specified" << llendl; +		dump(); +		return; +	} +	 +	if (idx == (S32)mItems.size() - 1) +	{ +		llwarns << "Will not teleport to the same location." << llendl; +		dump(); +		return; +	} + +	// Attempt to teleport to the requested item. +	gAgent.teleportViaLocation(mItems[idx].mGlobalPos); +} + diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h index fa836c0326..f67c4e2fb9 100644 --- a/indra/newview/llteleporthistorystorage.h +++ b/indra/newview/llteleporthistorystorage.h @@ -78,7 +78,10 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>  public: -	typedef std::vector<LLTeleportHistoryPersistentItem> item_list_list_t; +	typedef std::vector<LLTeleportHistoryPersistentItem> slurl_list_t; + +	typedef boost::function<void()>		history_callback_t; +	typedef boost::signals2::signal<void()>	history_signal_t;  	LLTeleportHistoryStorage();  	~LLTeleportHistoryStorage(); @@ -86,7 +89,7 @@ public:  	/**  	 * @return history items.  	 */ -	const item_list_list_t& getItems() const { return mItems; } +	const slurl_list_t& getItems() const { return mItems; }  	void			purgeItems();  	void addItem(const std::string title, const LLVector3d& global_pos); @@ -99,10 +102,34 @@ public:  	void dump() const; +	/** +	 * Set a callback to be called upon history changes. +	 *  +	 * Multiple callbacks can be set. +	 */ +	boost::signals2::connection	setHistoryChangedCallback(history_callback_t cb); + +	/** +	 * Go to specific item in the history. +	 *  +	 * The item is specified by its index (starting from 0). +	 */ +	void					goToItem(S32 idx); +  private: -	item_list_list_t	mItems; -	std::string		mFilename; +	void onTeleportHistoryChange(); +	bool compareByTitleAndGlobalPos(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b); + +	slurl_list_t	mItems; +	std::string	mFilename; + +	/** +	 * Signal emitted when the history gets changed. +	 *  +	 * Invokes callbacks set with setHistoryChangedCallback(). +	 */ +	history_signal_t		mHistoryChangedSignal;  };  #endif //LL_LLTELEPORTHISTORYSTORAGE_H diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 969f3fd1cb..05e63a60c5 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -70,12 +70,16 @@ public:  		bool				enable_hide_btn;  		bool				is_modal;  		bool				is_tip; +		bool				force_show; +		bool				force_store;  		Params() :	can_fade(true),  					can_be_stored(true),  					is_modal(false),  					is_tip(false),  					enable_hide_btn(true), +					force_show(false), +					force_store(false),  					panel(NULL),  					timer_period(gSavedSettings.getS32("NotificationToastTime")) diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 6f26b4077c..6f373a74bd 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -40,7 +40,7 @@  #include "lliconctrl.h"  #include "llnotify.h"  #include "lltextbox.h" -#include "lltexteditor.h" +  #include "lluiconstants.h"  #include "llui.h"  #include "llviewercontrol.h" @@ -53,6 +53,8 @@  #include "llfloaterinventory.h"  #include "llinventorytype.h" +const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 4; +  LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)  :	LLToastPanel(notification),  	mInventoryOffer(NULL) @@ -65,8 +67,6 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  		llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;  	} -	static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor"); -  	//group icon  	LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);  	pGroupIcon->setValue(groupData.mInsigniaID); @@ -78,23 +78,16 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  	LLTextBox* pTitleText = getChild<LLTextBox>("title");  	pTitleText->setValue(from.str()); -	//message body +	//message subject  	const std::string& subject = payload["subject"].asString(); +	//message body  	const std::string& message = payload["message"].asString(); -	LLTextEditor* pMessageText = getChild<LLTextEditor>("message"); -	pMessageText->setValue(""); -	pMessageText->setEnabled(FALSE); -	LLStyle::Params date_style; -	date_style.color = textColor; -	date_style.font.name = "SANSSERIF"; - -	LLStyle::Params header_style_params; -	header_style_params.color = textColor; -	header_style_params.font = LLFontGL::getFontSansSerifBig(); -	pMessageText->appendStyledText(subject + "\n",false,false,header_style_params); +	LLTextBox* pSubjectText = getChild<LLTextBox>("subject"); +	pSubjectText->setValue(subject); +	LLTextBox* pDateTimeText = getChild<LLTextBox>("datetime");  	std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["  							+LLTrans::getString("UTCTimeDay")+"] ["  							+LLTrans::getString("UTCTimeMth")+"] [" @@ -108,25 +101,38 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  	LLSD substitution;  	substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();  	LLStringUtil::format(timeStr, substitution); -	LLStyle::Params date_style_params; -	date_style_params.color = textColor; -	date_style_params.font = LLFontGL::getFontMonospace(); -	pMessageText->appendStyledText(timeStr, false, false, date_style); -	pMessageText->appendColoredText(std::string("\n\n") + message, false, -			false, textColor); +	pDateTimeText->setValue(timeStr); + +	LLTextBox* pMessageText = getChild<LLTextBox>("message"); + +	//If message is empty let it be invisible and not take place at the panel +	if(message.size() != 0) +	{ +		pMessageText->setVisible(TRUE); +		pMessageText->setValue(message); +	} +	else +	{ +		pMessageText->setVisible(FALSE); +	}  	//attachment  	BOOL hasInventory = payload["inventory_offer"].isDefined(); + +	//attachment text  	LLTextBox * pAttachLink = getChild<LLTextBox>("attachment"); +	//attachment icon +	LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE); + +	//If attachment is empty let it be invisible and not take place at the panel  	pAttachLink->setVisible(hasInventory); +	pAttachIcon->setVisible(hasInventory);  	if (hasInventory) {  		pAttachLink->setValue(payload["inventory_name"]);  		mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);  		childSetActionTextbox("attachment", boost::bind(  				&LLToastGroupNotifyPanel::onClickAttachment, this)); -		//attachment icon -		LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);  		LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType,  												LLInventoryType::IT_TEXTURE,  												0, FALSE); @@ -137,8 +143,15 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  	LLButton* pOkBtn = getChild<LLButton>("btn_ok");  	pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this)));  	setDefaultBtn(pOkBtn); -} +	S32 maxLinesCount; +	std::istringstream ss( getString("message_max_lines_count") ); +	if (!(ss >> maxLinesCount)) +	{ +		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT; +	} +	snapToMessageHeight(pMessageText, maxLinesCount); +}  // virtual  LLToastGroupNotifyPanel::~LLToastGroupNotifyPanel() diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h index ba98531251..e3d0ef45cb 100644 --- a/indra/newview/lltoastgroupnotifypanel.h +++ b/indra/newview/lltoastgroupnotifypanel.h @@ -68,6 +68,8 @@ protected:  private:  	static bool isAttachmentOpenable(LLAssetType::EType); +	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT; +  	LLButton* mSaveInventoryBtn;  	LLUUID mGroupID; diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index e41181c9e1..913e46e05e 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -34,9 +34,7 @@  #include "lltoastimpanel.h"  #include "llimpanel.h" -const S32 LLToastIMPanel::MAX_MESSAGE_HEIGHT	= 50; -const S32 LLToastIMPanel::CAPTION_HEIGHT		= 30; -const S32 LLToastIMPanel::TOP_PAD 				= 5; +const S32 LLToastIMPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 6;  //--------------------------------------------------------------------------  LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notification), @@ -60,7 +58,13 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif  	mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this)); -	snapToMessageHeight(); +	S32 maxLinesCount; +	std::istringstream ss( getString("message_max_lines_count") ); +	if (!(ss >> maxLinesCount)) +	{ +		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT; +	} +	snapToMessageHeight(mMessage, maxLinesCount);  }  //-------------------------------------------------------------------------- @@ -69,22 +73,6 @@ LLToastIMPanel::~LLToastIMPanel()  }  //-------------------------------------------------------------------------- -void LLToastIMPanel::snapToMessageHeight() -{ -	S32 required_text_height = mMessage->getTextPixelHeight(); -	S32 text_height = llmin(required_text_height, MAX_MESSAGE_HEIGHT); -	LLRect text_rect = mMessage->getRect(); -	LLRect btn_rect = mReplyBtn->getRect(); - - -	mMessage->reshape( text_rect.getWidth(), text_height, TRUE); -	mMessage->setValue(mMessage->getText()); - -	S32 panel_height = CAPTION_HEIGHT + text_height + btn_rect.getHeight() + TOP_PAD*5; -	reshape( getRect().getWidth(), panel_height, TRUE); -} - -//--------------------------------------------------------------------------  void LLToastIMPanel::onClickReplyBtn()  {  	LLIMFloater::toggle(mSessionID); diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h index 7f5d6eca1d..11f489c12f 100644 --- a/indra/newview/lltoastimpanel.h +++ b/indra/newview/lltoastimpanel.h @@ -59,12 +59,9 @@ public:  	virtual ~LLToastIMPanel();  private: -	static const S32 MAX_MESSAGE_HEIGHT; -	static const S32 CAPTION_HEIGHT; -	static const S32 TOP_PAD; +	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;  	void onClickReplyBtn(); -	void snapToMessageHeight();  	LLUUID				mSessionID;  	LLAvatarIconCtrl*	mAvatar; diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 28052a33be..e884d89ce4 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -49,5 +49,36 @@ std::string LLToastPanel::getTitle()  	return mNotification->getMessage();  } +//snap to the message height if it is visible +void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount) +{ +	//Add message height if it is visible +	if (message->getVisible()) +	{ +		S32 heightDelta = 0; +		S32 maxTextHeight = (S32)(message->getFont()->getLineHeight() * maxLineCount); + +		LLRect messageRect = message->getRect(); +		S32 oldTextHeight = messageRect.getHeight(); + +		//Reshape the toast to give the message max height. +		//This needed to calculate lines count according to specified text +		heightDelta = maxTextHeight - oldTextHeight; +		reshape( getRect().getWidth(), getRect().getHeight() + heightDelta); +		message->setValue(message->getText()); + +		//Knowing the height is set to max allowed, getTextPixelHeight returns needed text height +		//Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape. +		S32 requiredTextHeight = message->getTextPixelHeight(); +		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); +		//Calculate last delta height deducting previous heightDelta  +		heightDelta = newTextHeight - oldTextHeight - heightDelta; + +		//reshape the panel with new height +		reshape( getRect().getWidth(), getRect().getHeight() + heightDelta); +		message->setValue(message->getText()); +	} + +} diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h index 2258eca273..bc9888f4b4 100644 --- a/indra/newview/lltoastpanel.h +++ b/indra/newview/lltoastpanel.h @@ -34,6 +34,7 @@  #define LL_LLTOASTPANEL_H  #include "llpanel.h" +#include "lltextbox.h"  #include "llnotifications.h"  #include <string> @@ -53,6 +54,7 @@ public:  	virtual const LLUUID& getID() { return mNotification->id();}  protected:  	LLNotificationPtr mNotification; +	void snapToMessageHeight(LLTextBox* message, S32 maxLineCount);  };  #endif /* LL_TOASTPANEL_H */ diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index acd6856061..c7c9f07504 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -60,6 +60,7 @@  #include "llui.h"  #include "llviewermenu.h"  #include "llfirstuse.h" +#include "llpanelblockedlist.h"  #include "llscrolllistctrl.h"  #include "llscrolllistitem.h"  #include "llscrolllistcell.h" @@ -69,7 +70,6 @@  #include "lltoolgrab.h"  #include "llcombobox.h"  #include "llfloaterchat.h" -#include "llfloatermute.h"  #include "llimpanel.h"  #include "lllayoutstack.h" @@ -297,11 +297,8 @@ void LLToolBar::updateCommunicateList()  	communicate_button->addSeparator(ADD_TOP);  	communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP);  	communicate_button->addSeparator(ADD_TOP); -	LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute"); -	if(mute_instance) -	{ -		communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP); -	} +	communicate_button->add(getString("Blocked List"), LLSD("mute list"), ADD_TOP); +  	std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;  	if (gIMMgr->getIMFloaterHandles().size() > 0) @@ -379,7 +376,7 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data)  	}  	else if (selected_option.asString() == "mute list")  	{ -		LLFloaterReg::showInstance("mute"); +		LLPanelBlockedList::showPanelAndSelect(LLUUID::null);  	}  	else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle  	{ diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index b85dc30e72..c8f2e03903 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -78,7 +78,6 @@  #include "llfloaterlandholdings.h"  #include "llfloatermap.h"  #include "llfloatermemleak.h" -#include "llfloatermute.h"  #include "llfloaternamedesc.h"  #include "llfloaternotificationsconsole.h"  #include "llfloateropenobject.h" @@ -110,6 +109,7 @@  #include "llmediaremotectrl.h"  #include "llmoveview.h"  #include "llnearbychat.h" +#include "llpanelblockedlist.h"  #include "llpreviewanim.h"  #include "llpreviewgesture.h"  #include "llpreviewnotecard.h" @@ -177,8 +177,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);  	LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);  	LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>); -	LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMute>); -	LLFloaterReg::add("mute_object", "floater_mute_object.xml", &LLFloaterMute::buildFloaterMuteObjectUI); +	LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);  	LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);  	LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 95ab40f9bf..ec20af46a1 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -120,6 +120,41 @@ LLViewerInventoryItem::~LLViewerInventoryItem()  {  } +BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const +{ +	using std::string; +	using std::stringstream; + +	const char separator = getSeparator(); +	const string::size_type separatorPos = mName.find(separator, 0); + +	BOOL result = FALSE; + +	if (separatorPos < string::npos) +	{ +		if (sortField) +		{ +			/* +			 * The conversion from string to S32 is made this way instead of old plain +			 * atoi() to ensure portability. If on some other platform S32 will not be +			 * defined to be signed int, this conversion will still work because of +			 * operators overloading, but atoi() may fail. +			 */ +			stringstream ss(mName.substr(0, separatorPos)); +			ss >> *sortField; +		} + +		if (displayName) +		{ +			*displayName = mName.substr(separatorPos + 1, string::npos); +		} + +		result = TRUE; +	} + +	return result; +} +  void LLViewerInventoryItem::copyViewerItem(const LLViewerInventoryItem* other)  {  	LLInventoryItem::copyItem(other); @@ -1102,7 +1137,70 @@ const std::string& LLViewerInventoryItem::getName() const  		return linked_category->getName();  	} -	return LLInventoryItem::getName(); +	return getDisplayName(); +} + +const std::string& LLViewerInventoryItem::getDisplayName() const +{ +	std::string result; +	BOOL hasSortField = extractSortFieldAndDisplayName(0, &result); + +	return mDisplayName = hasSortField ? result : LLInventoryItem::getName(); +} + +S32 LLViewerInventoryItem::getSortField() const +{ +	S32 result; +	BOOL hasSortField = extractSortFieldAndDisplayName(&result, 0); + +	return hasSortField ? result : -1; +} + +void LLViewerInventoryItem::setSortField(S32 sortField) +{ +	using std::string; + +	std::stringstream ss; +	ss << sortField; + +	string newSortField = ss.str(); + +	const char separator = getSeparator(); +	const string::size_type separatorPos = mName.find(separator, 0); + +	if (separatorPos < string::npos) +	{ +		// the name of the LLViewerInventoryItem already consists of sort field and display name. +		mName = newSortField + separator + mName.substr(separatorPos + 1, string::npos); +	} +	else +	{ +		// there is no sort field in the name of LLViewerInventoryItem, we should add it +		mName = newSortField + separator + mName; +	} +} + +void LLViewerInventoryItem::rename(const std::string& n) +{ +	using std::string; + +	string new_name(n); +	LLStringUtil::replaceNonstandardASCII(new_name, ' '); +	LLStringUtil::replaceChar(new_name, '|', ' '); +	LLStringUtil::trim(new_name); +	LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); + +	const char separator = getSeparator(); +	const string::size_type separatorPos = mName.find(separator, 0); + +	if (separatorPos < string::npos) +	{ +		mName.replace(separatorPos + 1, string::npos, new_name); +	} +	else +	{ +		mName = new_name; +	}  }  const LLPermissions& LLViewerInventoryItem::getPermissions() const diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 0bfb37f7e8..c4ff30bbfc 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -55,11 +55,18 @@ public:  protected:  	~LLViewerInventoryItem( void ); // ref counted +	BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const; +	static char getSeparator() { return '@'; } +	mutable std::string mDisplayName;  public:  	virtual LLAssetType::EType getType() const;  	virtual const LLUUID& getAssetUUID() const;  	virtual const std::string& getName() const; +	virtual const std::string& getDisplayName() const; +	virtual S32 getSortField() const; +	virtual void setSortField(S32 sortField); +	virtual void rename(const std::string& new_name);  	virtual const LLPermissions& getPermissions() const;  	virtual const LLUUID& getCreatorUUID() const;  	virtual const std::string& getDescription() const; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8a5928f4e9..5536951ce6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -113,7 +113,6 @@  #include "llfloaterland.h"  #include "llfloaterlandholdings.h"  #include "llfloatermap.h" -#include "llfloatermute.h"  #include "llfloateropenobject.h"  #include "llfloaterperms.h"  #include "llfloaterpostprocess.h" @@ -147,6 +146,7 @@  #include "llfloaterinventory.h"  #include "llkeyboard.h"  #include "llpanellogin.h" +#include "llpanelblockedlist.h"  #include "llmenucommands.h"  #include "llmenugl.h"  #include "llmimetypes.h" @@ -2896,7 +2896,7 @@ class LLObjectMute : public view_listener_t  		else  		{  			LLMuteList::getInstance()->add(mute); -			LLFloaterReg::showInstance("mute"); +			LLPanelBlockedList::showPanelAndSelect(mute.mID);  		}  		return true; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dfb1c330e5..177c987bc0 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -82,7 +82,6 @@  #include "llfloaterregioninfo.h"  #include "llfloaterlandholdings.h"  #include "llurldispatcher.h" -#include "llfloatermute.h"  #include "llfloaterpostcard.h"  #include "llfloaterpreference.h"  #include "llfollowcam.h" @@ -138,6 +137,7 @@  #include "llgroupactions.h"  #include "llagentui.h"  #include "llsidetray.h" +#include "llpanelblockedlist.h"  #include "llpanelplaceinfo.h"  #include <boost/tokenizer.hpp> @@ -1001,9 +1001,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,  	LLMute mute(blocked_id, from_name, type);  	if (LLMuteList::getInstance()->add(mute))  	{ -		LLFloaterReg::showInstance("mute"); -		LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute"); -		if(mute_instance) mute_instance->selectMute(blocked_id); +		LLPanelBlockedList::showPanelAndSelect(blocked_id);  	}  	// purge the message queue of any previously queued inventory offers from the same source. @@ -5576,7 +5574,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**)  	LLPanelLandCovenant::updateEstateName(estate_name);  	LLFloaterBuyLand::updateEstateName(estate_name); -	LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); +	LLPanelPlaceInfo* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceInfo>("panel_place_info");  	if (panel)  	{  		panel->updateEstateName(estate_name); @@ -5660,7 +5658,7 @@ void callbackCacheEstateOwnerName(const LLUUID& id,  	LLPanelLandCovenant::updateEstateOwnerName(name);  	LLFloaterBuyLand::updateEstateOwnerName(name); -	LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); +	LLPanelPlaceInfo* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceInfo>("panel_place_info");  	if (panel)  	{  		panel->updateEstateOwnerName(name); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 607c5d9ae8..241c6fd511 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1596,8 +1596,6 @@ void LLViewerWindow::initWorldUI()  	gFloaterView->setRect(floater_view_rect);  	gNotifyBoxView->setRect(notify_view_rect); -	// *Note: this is where gFloaterMute used to be initialized. -  	LLWorldMapView::initClass();  	// Force gFloaterWorldMap to initialize @@ -1636,6 +1634,11 @@ void LLViewerWindow::initWorldUI()  		navbar->showFavoritesPanel(FALSE);  	} +	if (!gSavedSettings.getBOOL("ShowCameraAndMoveControls")) +	{ +		LLBottomTray::getInstance()->showCameraAndMoveControls(FALSE); +	} +  	getRootView()->addChild(gStatusBar);  	getRootView()->addChild(navbar); @@ -1668,6 +1671,9 @@ void LLViewerWindow::initWorldUI()  		// put behind everything else in the UI  		getRootView()->addChildInBack(gHUDView);  	} + +	// this allows not to see UI elements created while UI initializing after Alt+Tab was pressed during login. EXT-744. +	moveProgressViewToFront();  }  // Destroy the UI @@ -4417,8 +4423,7 @@ void LLViewerWindow::moveProgressViewToFront()  {  	if( mProgressView && mRootView )  	{ -		mRootView->removeChild( mProgressView ); -		mRootView->addChild( mProgressView ); +		mRootView->sendChildToFront(mProgressView);  	}  } diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 0bd5f114ed..e32ea0944e 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -93,6 +93,7 @@    <texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false"/>    <texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" /> +  <texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" />    <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" /> diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml index bb5a4e51f7..6ef1eb9513 100644 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml @@ -15,4 +15,8 @@    <menu_item_call name="organize_offline" label="Organize Offline Friends">      <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="organize_offline" />    </menu_item_call> +  <menu_item_separator layout="topleft" /> +  <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> +    <menu_item_call.on_click function="SideTray.ShowPanel" parameter="panel_block_list_sidetray" /> +  </menu_item_call>  </menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml index 8c2c5e8c9e..2b0f029016 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml @@ -15,4 +15,8 @@    <menu_item_call name="view_icons" label="View People Icons">      <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="view_icons" />    </menu_item_call> +  <menu_item_separator layout="topleft" /> +  <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> +    <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" /> +  </menu_item_call>  </menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml index 00cf443cc6..88b0528e53 100644 --- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml @@ -12,4 +12,8 @@    <menu_item_call name="view_icons" label="View People Icons">      <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="view_icons" />    </menu_item_call> +  <menu_item_separator layout="topleft" /> +  <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> +    <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" /> +  </menu_item_call>  </menu> diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml new file mode 100644 index 0000000000..5c8a8ee208 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + follows="left|top|right|bottom" + height="305" + layout="topleft" + name="block_list_panel" + min_height="350" + min_width="240" + width="280"> +    <text  +     follows="top|left|right" +     font="SansSerifHugeBold" +     height="20" +     layout="topleft" +     left="10"  +     name="title_text" +     text_color="white" +     top="0"  +     width="250"> +        Blocked List +     </text> +     <button  +     follows="top|right" +     height="25" +     image_overlay="BackArrow_Off" +     layout="topleft" +     name="back" +     right="-9" +     tab_stop="false"  +     top="0" +     width="25"/> +    <scroll_list +     follows="left|top|right|bottom" +     height="200" +     layout="topleft" +     left="5" +     name="blocked" +     tool_tip="List of currently blocked residents" +     top="30" +     width="270" /> +    <button +     follows="left|bottom" +     height="20" +     label="Block Resident..." +     label_selected="Block Resident..." +     layout="topleft" +     left_delta="0" +     name="Block resident..." +     tool_tip="Pick a resident to block" +     top_pad="4" +     width="210"> +        <button.commit_callback +         function="Block.ClickPick" /> +    </button> +    <button +     follows="left|bottom" +     height="20" +     label="Block object by name..." +     label_selected="Block object by name..." +     layout="topleft" +     left_delta="0" +     name="Block object by name..." +     top_pad="4" +     width="210" > +        <button.commit_callback +         function="Block.ClickBlockByName" /> +    </button> +    <button +     enabled="false" +     follows="left|bottom" +     height="20" +     label="Unblock" +     label_selected="Unblock" +     layout="topleft" +     left_delta="0" +     name="Unblock" +     tool_tip="Remove resident or object from blocked list" +     top_pad="4" +     width="210" > +        <button.commit_callback +         function="Block.ClickRemove" /> +    </button> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 8fc029bea6..79ca839f28 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -266,7 +266,7 @@               top="2"               width="48">                <button -               image_selected="bottom_tray_sys_notifications.tga" +               image_selected="bottom_tray_sys_notifications_selected.tga"                 image_unselected="bottom_tray_sys_notifications.tga"/>                <unread_notifications                 width="20" 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 fa02cdb4b2..0d6d8ba97d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -13,10 +13,44 @@   top="10"   width="255">     <string +    name="CaptionTextAcctInfo"> +       [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION] +   </string> +   <string +    name="AcctTypeResident" +    value="Resident" /> +   <string +    name="AcctTypeTrial" +    value="Trial" /> +   <string +    name="AcctTypeCharterMember" +    value="Charter Member" /> +   <string +    name="AcctTypeEmployee" +    value="Linden Lab Employee" /> +   <string +    name="PaymentInfoUsed" +    value="Payment Info Used" /> +   <string +    name="PaymentInfoOnFile" +    value="Payment Info On File" /> +   <string +    name="NoPaymentInfoOnFile" +    value="No Payment Info On File" /> +   <string +    name="AgeVerified" +    value="Age-verified" /> +   <string +    name="NotAgeVerified" +    value="Not Age-verified" /> +   <string      name="partner_edit_link_url">         http://www.secondlife.com/account/partners.php?lang=en     </string> -   <scroll_container +   <string +    name="no_partner_text" +    value="None" /> +  <scroll_container       color="DkGray2"       follows="left|top|right|bottom"       height="300" @@ -38,7 +72,7 @@       background_visible="true"       bg_alpha_color="DkGray2"       follows="left|top|right|bottom"   -     height="620" +     height="750"       layout="topleft"       left="0"       name="data_panel"  diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml index 8ebf1b69a7..f97daf922f 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml @@ -1,8 +1,12 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel background_visible="true" bevel_style="in" bg_alpha_color="0 0 0 0" -	height="200" label="instant_message" layout="topleft" left="0" +	height="155" label="instant_message" layout="topleft" left="0"  	name="panel_group_notify" top="0" width="350"> -	<panel background_visible="true" bevel_style="in" bg_alpha_color="black" +    <string +     name="message_max_lines_count"> +        4 +    </string> +	<panel follows="top" background_visible="true" bevel_style="in" bg_alpha_color="black"  		height="50" label="header" layout="topleft" left="0" name="header"  		top="0" width="350">  		<icon follows="left|top|right|bottom" height="40"  width="40" layout="topleft" @@ -13,21 +17,61 @@  			Sender Name / Group Name          </text>  	</panel> -	<text_editor type="string" length="1" bg_readonly_color="0 0 0 0" -		follows="left|top|right|bottom" height="70" hide_scrollbar="true" -		hide_border="true" layout="topleft" top="55" left="25" name="message" -		text_color="GroupNotifyTextColor" text_readonly_color="GroupNotifyTextColor" width="300" word_wrap="true"> -		Message -		Body -    </text_editor> -	<icon follows="left|top|right|bottom" height="16" width="16" -		layout="topleft" top="135" left="25" mouse_opaque="true" name="attachment_icon" /> +	<text +     follows="top" +     height="20" +     layout="topleft" +     left="25" +     name="subject" +     text_color="GroupNotifyTextColor" +     font="SansSerifBig" +     top="60" +     use_ellipses="true" +     value="subject" +     width="300" +     word_wrap="true"> +     subject  +    </text> +    <text +     follows="top" +     height="20" +     layout="topleft" +     left="25" +     name="datetime" +     text_color="GroupNotifyTextColor" +     font="SansSerif" +     top="80" +     use_ellipses="true" +     value="datetime" +     width="300" +     word_wrap="true"> +     datetime +    </text> +    <text +     follows="left|top|bottom|right" +     height="0" +     layout="topleft" +     left="25" +     name="message" +     text_color="GroupNotifyTextColor" +     top="100" +     use_ellipses="true" +     value="message" +     width="300" +     word_wrap="true" +     visible="true" > +    </text> +    <icon +	  follows="left|bottom|right" height="15" width="15" +		layout="topleft" bottom="122" left="25" mouse_opaque="true" name="attachment_icon" visible="true" +	/>  	<text font="SansSerif" font.style="UNDERLINE" font_shadow="hard" -		type="string" length="1" follows="left|top|right|bottom" layout="topleft" -		left="45" top="135" height="15" width="280" name="attachment" -		text_color="GroupNotifyTextColor"> +		type="string" length="1" follows="left|bottom|right" layout="topleft" +		left="45" bottom="122" height="15" width="280" name="attachment" +		text_color="GroupNotifyTextColor" visible="true">  		Attachment -        </text> -	<button label="OK" layout="topleft" top="170" left="140" height="20" -		width="70" name="btn_ok" /> -</panel> +     </text> + +	<button label="OK" layout="topleft" bottom="145" left="140" height="20" +		width="70" name="btn_ok" follows="bottom" /> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml index 169fde7b47..ace456918c 100644 --- a/indra/newview/skins/default/xui/en/panel_instant_message.xml +++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml @@ -10,6 +10,10 @@   name="im_panel"   top="0"   width="350"> +    <string +     name="message_max_lines_count"> +        6 +    </string>      <panel       background_visible="true"       bevel_style="in" @@ -56,7 +60,7 @@           width="50" />      </panel>      <text -     follows="left|bottom|right" +     follows="left|top|bottom|right"       height="60"       layout="topleft"       left="10" 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 dee911a45d..80dca8c0c1 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -107,8 +107,8 @@  	<!--      picture_style="true" -->  	<!--      top_delta="0" -->  	<!--      width="168" /> --> -	     -	    <search_editor + +        <search_combo_box  	     bevel_style="none"  	     border_style="line"  	     border.border_thickness="0" @@ -118,12 +118,15 @@  	     height="22"  	     label="Search"  	     layout="topleft" -	     left_pad="7" +	     right="-10"  	     mouse_opaque="false" -	     name="search_input" +	     name="search_combo_box"  	     tool_tip="Search"  	     top_delta="0" -	     width="200" />         +	     width="200" > +         <combo_editor +          label="Search" /> +        </search_combo_box>  	</panel>      <favorites_bar diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 6f4110067b..4c8c4efbe7 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -8,6 +8,26 @@   name="picture_item"   top="0"   width="275"> +    <icon +     height="120"  +     image_name="ListItem_Over" +     left="0"  +     mouse_opaque="false" +     name="hovered_icon"  +     top="0" +     scale_image="true"  +     visible="false" +     width="270"/> +    <icon +     height="120"  +     image_name="ListItem_Select" +     left="0"  +     mouse_opaque="false" +     name="selected_icon" +     top="0" +     scale_image="true" +     visible="false" +     width="270"/>      <texture_picker       allow_no_texture="true"       default_image_name="None" diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index e9eac2c9dc..e166675364 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -57,6 +57,13 @@          label="Group Info"           border="true"        /> +      <panel  +        class="panel_block_list_sidetray" +        name="panel_block_list_sidetray"  +        filename="panel_block_list_sidetray.xml"  +        label="Blocked Residents & Objects" +        border="true" +      />      </panel_container>    </sidetray_tab> diff --git a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml new file mode 100644 index 0000000000..eabacbecb2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<accordion_tab  +    header_collapse_img="accordion_collapsed.tga"  +    header_collapse_img_pressed="accordion_collapsed.tga"  +    header_expand_img="accordion_expanded.tga" +    header_expand_img_pressed="accordion_expanded.tga" /> diff --git a/indra/newview/skins/default/xui/en/widgets/list.xml b/indra/newview/skins/default/xui/en/widgets/list.xml index 8c264205d5..4a59716464 100644 --- a/indra/newview/skins/default/xui/en/widgets/list.xml +++ b/indra/newview/skins/default/xui/en/widgets/list.xml @@ -6,4 +6,5 @@   background_visible="false"   background_opaque="false"   item_pad="5" + keep_one_selected="true"   multi_select="false" />
\ No newline at end of file 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 8f4d0edf95..297a3762f6 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -43,7 +43,7 @@                            label=""                            pad_right="0"                            tool_tip="My Location History"/> -  <combo_list bg_writeable_color="MenuDefaultBgColor"/> +  <combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10"/>    <combo_editor name="Combo Text Entry"                  text_pad_left="20"                  select_on_focus="false" diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml new file mode 100644 index 0000000000..1d43b25f1d --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<search_combo_box + allow_text_entry="true" + list_position="BELOW" + show_text_as_tentative="false" + dropdown_button_visible="false" + background_image="TextField_Search_Off" + background_image_disabled="TextField_Search_Disabled" + background_image_focused="TextField_Search_Active"> + <combo_editor +  select_on_focus="true" +  text_pad_left="20"  +  background_image="TextField_Search_Off" +  background_image_disabled="TextField_Search_Disabled" +  background_image_focused="TextField_Search_Active"/> + <combo_list +  multi_select="false" +  page_lines="10" /> + <search_button label="" +  top_pad="4" +  left_pad="4"  +  width="13" +  height="13"  +  image_unselected="Search" +  image_selected="Search" /> +</search_combo_box>
\ No newline at end of file | 
