diff options
71 files changed, 1556 insertions, 851 deletions
| diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index b28b04f643..fd40910d9e 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1,3 +1,4 @@ + diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index f1bc28427d..e829788c91 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -19,7 +19,6 @@ include_directories(  set(llinventory_SOURCE_FILES      llcategory.cpp -    lleconomy.cpp      llfoldertype.cpp      llinventory.cpp      llinventorydefines.cpp @@ -42,7 +41,6 @@ set(llinventory_HEADER_FILES      CMakeLists.txt      llcategory.h -    lleconomy.h      llfoldertype.h      llinventory.h      llinventorydefines.h diff --git a/indra/llinventory/lleconomy.cpp b/indra/llinventory/lleconomy.cpp deleted file mode 100644 index 2a023d8c24..0000000000 --- a/indra/llinventory/lleconomy.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/**  - * @file lleconomy.cpp - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "lleconomy.h" -#include "llerror.h" -#include "message.h" -#include "v3math.h" - - -LLBaseEconomy::LLBaseEconomy() -:	mObjectCount( -1 ), -	mObjectCapacity( -1 ), -	mPriceObjectClaim( -1 ), -	mPricePublicObjectDecay( -1 ), -	mPricePublicObjectDelete( -1 ), -	mPriceEnergyUnit( -1 ), -	mPriceUpload( -1 ), -	mPriceRentLight( -1 ), -	mTeleportMinPrice( -1 ), -	mTeleportPriceExponent( -1 ), -	mPriceGroupCreate( -1 ) -{ } - -LLBaseEconomy::~LLBaseEconomy() -{ } - -void LLBaseEconomy::addObserver(LLEconomyObserver* observer) -{ -	mObservers.push_back(observer); -} - -void LLBaseEconomy::removeObserver(LLEconomyObserver* observer) -{ -	std::list<LLEconomyObserver*>::iterator it = -		std::find(mObservers.begin(), mObservers.end(), observer); -	if (it != mObservers.end()) -	{ -		mObservers.erase(it); -	} -} - -void LLBaseEconomy::notifyObservers() -{ -	for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin(); -		it != mObservers.end(); -		++it) -	{ -		(*it)->onEconomyDataChange(); -	} -} - -// static -void LLBaseEconomy::processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data) -{ -	S32 i; -	F32 f; - -	msg->getS32Fast(_PREHASH_Info, _PREHASH_ObjectCapacity, i); -	econ_data->setObjectCapacity(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_ObjectCount, i); -	econ_data->setObjectCount(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceEnergyUnit, i); -	econ_data->setPriceEnergyUnit(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceObjectClaim, i); -	econ_data->setPriceObjectClaim(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PricePublicObjectDecay, i); -	econ_data->setPricePublicObjectDecay(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PricePublicObjectDelete, i); -	econ_data->setPricePublicObjectDelete(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceUpload, i); -	econ_data->setPriceUpload(i); -#if LL_LINUX -	// We can optionally fake the received upload price for testing. -	// Note that the server is within its rights to not obey our fake -	// price. :) -	const char* fakeprice_str = getenv("LL_FAKE_UPLOAD_PRICE"); -	if (fakeprice_str) -	{ -		S32 fakeprice = (S32)atoi(fakeprice_str); -		LL_WARNS() << "LL_FAKE_UPLOAD_PRICE: Faking upload price as L$" << fakeprice << LL_ENDL; -		econ_data->setPriceUpload(fakeprice); -	} -#endif -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceRentLight, i); -	econ_data->setPriceRentLight(i); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_TeleportMinPrice, i); -	econ_data->setTeleportMinPrice(i); -	msg->getF32Fast(_PREHASH_Info, _PREHASH_TeleportPriceExponent, f); -	econ_data->setTeleportPriceExponent(f); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceGroupCreate, i); -	econ_data->setPriceGroupCreate(i); - -	econ_data->notifyObservers(); -} - -S32	LLBaseEconomy::calculateTeleportCost(F32 distance) const -{ -	S32 min_cost = getTeleportMinPrice(); -	F32 exponent = getTeleportPriceExponent(); -	F32 divisor = 100.f * pow(3.f, exponent); -	S32 cost = (U32)(distance * pow(log10(distance), exponent) / divisor); -	if (cost < 0) -	{ -		cost = 0; -	} -	else if (cost < min_cost) -	{ -		cost = min_cost; -	} - -	return cost; -} - -S32	LLBaseEconomy::calculateLightRent(const LLVector3& object_size) const -{ -	F32 intensity_mod = llmax(object_size.magVec(), 1.f); -	return (S32)(intensity_mod * getPriceRentLight()); -} - -void LLBaseEconomy::print() -{ -	LL_INFOS() << "Global Economy Settings: " << LL_ENDL; -	LL_INFOS() << "Object Capacity: " << mObjectCapacity << LL_ENDL; -	LL_INFOS() << "Object Count: " << mObjectCount << LL_ENDL; -	LL_INFOS() << "Claim Price Per Object: " << mPriceObjectClaim << LL_ENDL; -	LL_INFOS() << "Claim Price Per Public Object: " << mPricePublicObjectDecay << LL_ENDL; -	LL_INFOS() << "Delete Price Per Public Object: " << mPricePublicObjectDelete << LL_ENDL; -	LL_INFOS() << "Release Price Per Public Object: " << getPricePublicObjectRelease() << LL_ENDL; -	LL_INFOS() << "Price Per Energy Unit: " << mPriceEnergyUnit << LL_ENDL; -	LL_INFOS() << "Price Per Upload: " << mPriceUpload << LL_ENDL; -	LL_INFOS() << "Light Base Price: " << mPriceRentLight << LL_ENDL; -	LL_INFOS() << "Teleport Min Price: " << mTeleportMinPrice << LL_ENDL; -	LL_INFOS() << "Teleport Price Exponent: " << mTeleportPriceExponent << LL_ENDL; -	LL_INFOS() << "Price for group creation: " << mPriceGroupCreate << LL_ENDL; -} - -LLRegionEconomy::LLRegionEconomy() -:	mPriceObjectRent( -1.f ), -	mPriceObjectScaleFactor( -1.f ), -	mEnergyEfficiency( -1.f ), -	mBasePriceParcelClaimDefault(-1), -	mBasePriceParcelClaimActual(-1), -	mPriceParcelClaimFactor(-1.f), -	mBasePriceParcelRent(-1), -	mAreaOwned(-1.f), -	mAreaTotal(-1.f) -{ } - -LLRegionEconomy::~LLRegionEconomy() -{ } - -BOOL LLRegionEconomy::hasData() const -{ -	return (mBasePriceParcelRent != -1); -} - -// static -void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data) -{ -	S32 i; -	F32 f; - -	LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data; - -	LLBaseEconomy::processEconomyData(msg, this_ptr); - -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelClaim, i); -	this_ptr->setBasePriceParcelClaimDefault(i); -	msg->getF32(_PREHASH_Info, _PREHASH_PriceParcelClaimFactor, f); -	this_ptr->setPriceParcelClaimFactor(f); -	msg->getF32Fast(_PREHASH_Info, _PREHASH_EnergyEfficiency, f); -	this_ptr->setEnergyEfficiency(f); -	msg->getF32Fast(_PREHASH_Info, _PREHASH_PriceObjectRent, f); -	this_ptr->setPriceObjectRent(f); -	msg->getF32Fast(_PREHASH_Info, _PREHASH_PriceObjectScaleFactor, f); -	this_ptr->setPriceObjectScaleFactor(f); -	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelRent, i); -	this_ptr->setBasePriceParcelRent(i); -} - -// static -void LLRegionEconomy::processEconomyDataRequest(LLMessageSystem *msg, void **user_data) -{ -	LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data; -	if (!this_ptr->hasData()) -	{ -		LL_WARNS() << "Dropping EconomyDataRequest, because EconomyData message " -				<< "has not been processed" << LL_ENDL; -	} - -	msg->newMessageFast(_PREHASH_EconomyData); -	msg->nextBlockFast(_PREHASH_Info); -	msg->addS32Fast(_PREHASH_ObjectCapacity, this_ptr->getObjectCapacity()); -	msg->addS32Fast(_PREHASH_ObjectCount, this_ptr->getObjectCount()); -	msg->addS32Fast(_PREHASH_PriceEnergyUnit, this_ptr->getPriceEnergyUnit()); -	msg->addS32Fast(_PREHASH_PriceObjectClaim, this_ptr->getPriceObjectClaim()); -	msg->addS32Fast(_PREHASH_PricePublicObjectDecay, this_ptr->getPricePublicObjectDecay()); -	msg->addS32Fast(_PREHASH_PricePublicObjectDelete, this_ptr->getPricePublicObjectDelete()); -	msg->addS32Fast(_PREHASH_PriceParcelClaim, this_ptr->mBasePriceParcelClaimActual); -	msg->addF32Fast(_PREHASH_PriceParcelClaimFactor, this_ptr->mPriceParcelClaimFactor); -	msg->addS32Fast(_PREHASH_PriceUpload, this_ptr->getPriceUpload()); -	msg->addS32Fast(_PREHASH_PriceRentLight, this_ptr->getPriceRentLight()); -	msg->addS32Fast(_PREHASH_TeleportMinPrice, this_ptr->getTeleportMinPrice()); -	msg->addF32Fast(_PREHASH_TeleportPriceExponent, this_ptr->getTeleportPriceExponent()); - -	msg->addF32Fast(_PREHASH_EnergyEfficiency, this_ptr->getEnergyEfficiency()); -	msg->addF32Fast(_PREHASH_PriceObjectRent, this_ptr->getPriceObjectRent()); -	msg->addF32Fast(_PREHASH_PriceObjectScaleFactor, this_ptr->getPriceObjectScaleFactor()); -	msg->addS32Fast(_PREHASH_PriceParcelRent, this_ptr->getPriceParcelRent()); -	msg->addS32Fast(_PREHASH_PriceGroupCreate, this_ptr->getPriceGroupCreate()); - -	msg->sendReliable(msg->getSender()); -} - - -S32 LLRegionEconomy::getPriceParcelClaim() const -{ -	//return (S32)((F32)mBasePriceParcelClaim * (mAreaTotal / (mAreaTotal - mAreaOwned))); -	return (S32)((F32)mBasePriceParcelClaimActual * mPriceParcelClaimFactor); -} - -S32 LLRegionEconomy::getPriceParcelRent() const -{ -	return mBasePriceParcelRent; -} - - -void LLRegionEconomy::print() -{ -	this->LLBaseEconomy::print(); - -	LL_INFOS() << "Region Economy Settings: " << LL_ENDL; -	LL_INFOS() << "Land (square meters): " << mAreaTotal << LL_ENDL; -	LL_INFOS() << "Owned Land (square meters): " << mAreaOwned << LL_ENDL; -	LL_INFOS() << "Daily Object Rent: " << mPriceObjectRent << LL_ENDL; -	LL_INFOS() << "Daily Land Rent (per meter): " << getPriceParcelRent() << LL_ENDL; -	LL_INFOS() << "Energey Efficiency: " << mEnergyEfficiency << LL_ENDL; -} - - -void LLRegionEconomy::setBasePriceParcelClaimDefault(S32 val) -{ -	mBasePriceParcelClaimDefault = val; -	if(mBasePriceParcelClaimActual == -1) -	{ -		mBasePriceParcelClaimActual = val; -	} -} - -void LLRegionEconomy::setBasePriceParcelClaimActual(S32 val) -{ -	mBasePriceParcelClaimActual = val; -} - -void LLRegionEconomy::setPriceParcelClaimFactor(F32 val) -{ -	mPriceParcelClaimFactor = val; -} - -void LLRegionEconomy::setBasePriceParcelRent(S32 val) -{ -	mBasePriceParcelRent = val; -} diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h deleted file mode 100644 index cdfde171c1..0000000000 --- a/indra/llinventory/lleconomy.h +++ /dev/null @@ -1,157 +0,0 @@ -/**  - * @file lleconomy.h - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLECONOMY_H -#define LL_LLECONOMY_H - -#include "llsingleton.h" -#include <list> - -class LLMessageSystem; -class LLVector3; - -/** - * Register an observer to be notified of economy data updates coming from server. - */ -class LLEconomyObserver -{ -public: -	virtual ~LLEconomyObserver() {} -	virtual void onEconomyDataChange() = 0; -}; - -class LLBaseEconomy -{ -public: -	LLBaseEconomy(); -	virtual ~LLBaseEconomy(); - -	virtual void print(); - -	void	addObserver(LLEconomyObserver* observer); -	void	removeObserver(LLEconomyObserver* observer); -	void	notifyObservers(); - -	static void processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data); - -	S32		calculateTeleportCost(F32 distance) const; -	S32		calculateLightRent(const LLVector3& object_size) const; - -	S32		getObjectCount() const				{ return mObjectCount; } -	S32		getObjectCapacity() const			{ return mObjectCapacity; } -	S32		getPriceObjectClaim() const			{ return mPriceObjectClaim; } -	S32		getPricePublicObjectDecay() const	{ return mPricePublicObjectDecay; } -	S32		getPricePublicObjectDelete() const	{ return mPricePublicObjectDelete; } -	S32		getPricePublicObjectRelease() const	{ return mPriceObjectClaim - mPricePublicObjectDelete; } -	S32		getPriceEnergyUnit() const			{ return mPriceEnergyUnit; } -	S32		getPriceUpload() const				{ return mPriceUpload; } -	S32		getPriceRentLight() const			{ return mPriceRentLight; } -	S32		getTeleportMinPrice() const			{ return mTeleportMinPrice; } -	F32		getTeleportPriceExponent() const 	{ return mTeleportPriceExponent; } -	S32		getPriceGroupCreate() const			{ return mPriceGroupCreate; } - - -	void	setObjectCount(S32 val)				{ mObjectCount = val; } -	void	setObjectCapacity(S32 val)			{ mObjectCapacity = val; } -	void	setPriceObjectClaim(S32 val)		{ mPriceObjectClaim = val; } -	void	setPricePublicObjectDecay(S32 val)	{ mPricePublicObjectDecay = val; } -	void	setPricePublicObjectDelete(S32 val)	{ mPricePublicObjectDelete = val; } -	void	setPriceEnergyUnit(S32 val)			{ mPriceEnergyUnit = val; } -	void	setPriceUpload(S32 val)				{ mPriceUpload = val; } -	void	setPriceRentLight(S32 val)			{ mPriceRentLight = val; } -	void	setTeleportMinPrice(S32 val)		{ mTeleportMinPrice = val; } -	void	setTeleportPriceExponent(F32 val) 	{ mTeleportPriceExponent = val; } -	void	setPriceGroupCreate(S32 val)		{ mPriceGroupCreate = val; } - -private: -	S32		mObjectCount; -	S32		mObjectCapacity; -	S32		mPriceObjectClaim;			// per primitive -	S32		mPricePublicObjectDecay;	// per primitive -	S32		mPricePublicObjectDelete;	// per primitive -	S32		mPriceEnergyUnit; -	S32		mPriceUpload; -	S32		mPriceRentLight; -	S32		mTeleportMinPrice; -	F32		mTeleportPriceExponent; -	S32     mPriceGroupCreate; - -	std::list<LLEconomyObserver*> mObservers; -}; - -class LLGlobalEconomy: public LLSingleton<LLGlobalEconomy>, public LLBaseEconomy -{ -	LLSINGLETON_EMPTY_CTOR(LLGlobalEconomy); -}; - -class LLRegionEconomy : public LLBaseEconomy -{ -public: -	LLRegionEconomy(); -	~LLRegionEconomy(); - -	static void processEconomyData(LLMessageSystem *msg, void **user_data); -	static void processEconomyDataRequest(LLMessageSystem *msg, void **user_data); - -	void print(); - -	BOOL	hasData() const; -	F32		getPriceObjectRent() const	{ return mPriceObjectRent; } -	F32		getPriceObjectScaleFactor() const {return mPriceObjectScaleFactor;} -	F32		getEnergyEfficiency() const	{ return mEnergyEfficiency; } -	S32		getPriceParcelClaim() const; -	S32		getPriceParcelRent() const; -	F32		getAreaOwned() const		{ return mAreaOwned; } -	F32		getAreaTotal() const		{ return mAreaTotal; } -	S32 getBasePriceParcelClaimActual() const { return mBasePriceParcelClaimActual; } - -	void	setPriceObjectRent(F32 val)			{ mPriceObjectRent = val; } -	void	setPriceObjectScaleFactor(F32 val) { mPriceObjectScaleFactor = val; } -	void	setEnergyEfficiency(F32 val)		{ mEnergyEfficiency = val; } - -	void setBasePriceParcelClaimDefault(S32 val); -	void setBasePriceParcelClaimActual(S32 val); -	void setPriceParcelClaimFactor(F32 val); -	void setBasePriceParcelRent(S32 val); - -	void	setAreaOwned(F32 val)				{ mAreaOwned = val; } -	void	setAreaTotal(F32 val)				{ mAreaTotal = val; } - -private: -	F32		mPriceObjectRent; -	F32		mPriceObjectScaleFactor; -	F32		mEnergyEfficiency; - -	S32	mBasePriceParcelClaimDefault; -	S32 mBasePriceParcelClaimActual; -	F32 mPriceParcelClaimFactor; -	S32 mBasePriceParcelRent; - -	F32		mAreaOwned; -	F32		mAreaTotal; - -}; - -#endif diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 6c8fde580f..763c3aeb81 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -137,6 +137,7 @@ LLScrollListCtrl::Params::Params()  	background_visible("background_visible"),  	draw_stripes("draw_stripes"),  	column_padding("column_padding"), +	row_padding("row_padding", 2),  	fg_unselected_color("fg_unselected_color"),  	fg_selected_color("fg_selected_color"),  	bg_selected_color("bg_selected_color"), @@ -199,6 +200,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  	mHoveredColor(p.hovered_color()),  	mSearchColumn(p.search_column),  	mColumnPadding(p.column_padding), +	mRowPadding(p.row_padding),  	mContextMenuType(MENU_NONE),  	mIsFriendSignal(NULL)  { @@ -685,8 +687,6 @@ bool LLScrollListCtrl::updateColumnWidths()  	return width_changed;  } -const S32 SCROLL_LIST_ROW_PAD = 2; -  // Line height is the max height of all the cells in all the items.  void LLScrollListCtrl::updateLineHeight()  { @@ -699,7 +699,7 @@ void LLScrollListCtrl::updateLineHeight()  		S32 i = 0;  		for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))  		{ -			mLineHeight = llmax( mLineHeight, cell->getHeight() + SCROLL_LIST_ROW_PAD ); +			mLineHeight = llmax( mLineHeight, cell->getHeight() + mRowPadding );  		}  	}  } @@ -711,7 +711,7 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp)  	S32 i = 0;  	for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))  	{ -		mLineHeight = llmax( mLineHeight, cell->getHeight() + SCROLL_LIST_ROW_PAD ); +		mLineHeight = llmax( mLineHeight, cell->getHeight() + mRowPadding );  	}  } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index d7572d9fcf..43e1c0d707 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -108,7 +108,8 @@ public:  		// layout  		Optional<S32>	column_padding, -							page_lines, +						row_padding, +						page_lines,  						heading_height;  		// sort and search behavior @@ -283,8 +284,10 @@ public:  	void setBackgroundVisible(BOOL b)			{ mBackgroundVisible = b; }  	void setDrawStripes(BOOL b)					{ mDrawStripes = b; } -	void setColumnPadding(const S32 c)          { mColumnPadding = c; } -	S32  getColumnPadding()						{ return mColumnPadding; } +	void setColumnPadding(const S32 c)			{ mColumnPadding = c; } +	S32  getColumnPadding() const				{ return mColumnPadding; } +	void setRowPadding(const S32 c)				{ mColumnPadding = c; } +	S32  getRowPadding() const					{ return mColumnPadding; }  	void setCommitOnKeyboardMovement(BOOL b)	{ mCommitOnKeyboardMovement = b; }  	void setCommitOnSelectionChange(BOOL b)		{ mCommitOnSelectionChange = b; }  	void setAllowKeyboardMovement(BOOL b)		{ mAllowKeyboardMovement = b; } @@ -469,6 +472,7 @@ private:  	LLRect			mItemListRect;  	S32             mColumnPadding; +	S32             mRowPadding;  	BOOL			mBackgroundVisible;  	BOOL			mDrawStripes; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index e64078828b..83b851eed2 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -152,6 +152,7 @@ LLTextBase::Params::Params()  	plain_text("plain_text",false),  	track_end("track_end", false),  	read_only("read_only", false), +	skip_link_underline("skip_link_underline", false),  	spellcheck("spellcheck", false),  	v_pad("v_pad", 0),  	h_pad("h_pad", 0), @@ -183,6 +184,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)  	mFontShadow(p.font_shadow),  	mPopupMenuHandle(),  	mReadOnly(p.read_only), +	mSkipLinkUnderline(p.skip_link_underline),  	mSpellCheck(p.spellcheck),  	mSpellCheckStart(-1),  	mSpellCheckEnd(-1), @@ -2289,7 +2291,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig  			S32 cur_length = getLength();  			LLStyleConstSP sp(new LLStyle(highlight_params));  			LLTextSegmentPtr segmentp; -			if(underline_on_hover_only) +			if (underline_on_hover_only || mSkipLinkUnderline)  			{  				highlight_params.font.style("NORMAL");  				LLStyleConstSP normal_sp(new LLStyle(highlight_params)); @@ -2313,7 +2315,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig  		S32 segment_start = old_length;  		S32 segment_end = old_length + wide_text.size();  		LLStyleConstSP sp(new LLStyle(style_params)); -		if (underline_on_hover_only) +		if (underline_on_hover_only || mSkipLinkUnderline)  		{  			LLStyle::Params normal_style_params(style_params);  			normal_style_params.font.style("NORMAL"); @@ -3489,7 +3491,7 @@ F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start  /*virtual*/  BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask)  { -	mStyle = mHoveredStyle; +	mStyle = mEditor.getSkipLinkUnderline() ? mNormalStyle : mHoveredStyle;  	return LLNormalTextSegment::handleHover(x, y, mask);  } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 058b804714..8687e7aa2a 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -310,6 +310,7 @@ public:  								border_visible,  								track_end,  								read_only, +								skip_link_underline,  								spellcheck,  								allow_scroll,  								plain_text, @@ -451,6 +452,9 @@ public:  	void					setReadOnly(bool read_only) { mReadOnly = read_only; }  	bool					getReadOnly() { return mReadOnly; } +	void					setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; } +	bool					getSkipLinkUnderline() { return mSkipLinkUnderline;  } +  	void					setPlainText(bool value) { mPlainText = value;}  	bool					getPlainText() const { return mPlainText; } @@ -694,6 +698,8 @@ protected:  	bool						mAutoIndent;  	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes +	bool						mSkipLinkUnderline; +  	// support widgets  	LLHandle<LLContextMenu>		mPopupMenuHandle;  	LLView*						mDocumentView; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 289346a5c0..c9d5fb89ba 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -115,6 +115,7 @@ set(viewer_SOURCE_FILES      llaisapi.cpp      llagent.cpp      llagentaccess.cpp +    llagentbenefits.cpp      llagentcamera.cpp      llagentdata.cpp      llagentlanguage.cpp @@ -441,6 +442,7 @@ set(viewer_SOURCE_FILES      llpanelface.cpp      llpanelgenerictip.cpp      llpanelgroup.cpp +    llpanelgroupcreate.cpp      llpanelgroupbulk.cpp      llpanelgroupbulkban.cpp      llpanelgroupexperiences.cpp @@ -737,6 +739,7 @@ set(viewer_HEADER_FILES      llaisapi.h      llagent.h      llagentaccess.h +    llagentbenefits.h      llagentcamera.h      llagentdata.h      llagentlanguage.h @@ -1056,6 +1059,7 @@ set(viewer_HEADER_FILES      llpanelface.h      llpanelgenerictip.h      llpanelgroup.h +    llpanelgroupcreate.h      llpanelgroupbulk.h      llpanelgroupbulkimpl.h      llpanelgroupbulkban.h diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index a36e82b155..c8d2524e0e 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -32,6 +32,7 @@  #include "pipeline.h"  #include "llagentaccess.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llagentlistener.h"  #include "llagentwearables.h" @@ -2997,7 +2998,7 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO  BOOL LLAgent::canJoinGroups() const  { -	return (S32)mGroups.size() < gMaxAgentGroups; +	return (S32)mGroups.size() < LLAgentBenefitsMgr::current().getGroupMembershipLimit();  }  LLQuaternion LLAgent::getHeadRotation() diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp new file mode 100644 index 0000000000..2d219735a0 --- /dev/null +++ b/indra/newview/llagentbenefits.cpp @@ -0,0 +1,236 @@ +/** +* @file llagentbenefits.cpp +* +* $LicenseInfo:firstyear=2019&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2019, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llagentbenefits.h" + +LLAgentBenefits::LLAgentBenefits(): +	m_initalized(false), +	m_animated_object_limit(-1), +	m_animation_upload_cost(-1), +	m_attachment_limit(-1), +	m_group_membership_limit(-1), +	m_picks_limit(-1), +	m_sound_upload_cost(-1), +	m_texture_upload_cost(-1) +{ +} + +LLAgentBenefits::~LLAgentBenefits() +{ +} + +// This could be extended to a template scheme or otherwise modified +// to support other types, if and when needed. Currently all fields +// the viewer cares about are integer. +bool get_required_S32(const LLSD& sd, const LLSD::String& key, S32& value) +{ +	value = -1; +	if (sd.has(key)) +	{ +		value = sd[key].asInteger(); +		return true; +	} + +	LL_WARNS("Benefits") << "Missing required benefit field " << key << LL_ENDL; +	return false; +} + +bool LLAgentBenefits::init(const LLSD& benefits_sd) +{ +	LL_DEBUGS("Benefits") << "initializing benefits from " << benefits_sd << LL_ENDL; + +	if (!get_required_S32(benefits_sd, "animated_object_limit", m_animated_object_limit)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "animation_upload_cost", m_animation_upload_cost)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "attachment_limit", m_attachment_limit)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "create_group_cost", m_create_group_cost)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "group_membership_limit", m_group_membership_limit)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "picks_limit", m_picks_limit)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "sound_upload_cost", m_sound_upload_cost)) +	{ +		return false; +	} +	if (!get_required_S32(benefits_sd, "texture_upload_cost", m_texture_upload_cost)) +	{ +		return false; +	} + +	// FIXME PREMIUM - either use this field or get rid of it +	m_initalized = true; +	return true; +} + +S32 LLAgentBenefits::getAnimatedObjectLimit() const +{ +	return m_animated_object_limit; +} + +S32 LLAgentBenefits::getAnimationUploadCost() const +{ +	return m_animation_upload_cost; +} + +S32 LLAgentBenefits::getAttachmentLimit() const +{ +	return m_attachment_limit; +} + +S32 LLAgentBenefits::getCreateGroupCost() const +{ +	return m_create_group_cost; +} + +S32 LLAgentBenefits::getGroupMembershipLimit() const +{ +	return m_group_membership_limit; +} + +S32 LLAgentBenefits::getPicksLimit() const +{ +	return m_picks_limit; +} + +S32 LLAgentBenefits::getSoundUploadCost() const +{ +	return m_sound_upload_cost; +} + +S32 LLAgentBenefits::getTextureUploadCost() const +{ +	return m_texture_upload_cost; +} + +bool LLAgentBenefits::findUploadCost(LLAssetType::EType& asset_type, S32& cost) const +{ +	bool succ = false; +	if (asset_type == LLAssetType::AT_TEXTURE) +	{ +		cost = getTextureUploadCost(); +		succ = true; +	} +	else if (asset_type == LLAssetType::AT_SOUND) +	{ +		cost = getSoundUploadCost(); +		succ = true; +	} +	else if (asset_type == LLAssetType::AT_ANIMATION) +	{ +		cost = getAnimationUploadCost(); +		succ = true; +	} +	return succ; +} + +LLAgentBenefitsMgr::LLAgentBenefitsMgr() +{ +} + +LLAgentBenefitsMgr::~LLAgentBenefitsMgr() +{ +} + +// static +const LLAgentBenefits& LLAgentBenefitsMgr::current() +{ +	return instance().mCurrent; +} + +// static +const LLAgentBenefits& LLAgentBenefitsMgr::get(const std::string& package) +{ +	if (instance().mPackageMap.find(package) != instance().mPackageMap.end()) +	{ +		return instance().mPackageMap[package]; +	} +	else +	{ +		return instance().mDefault; +	} +} + +// static +bool LLAgentBenefitsMgr::init(const std::string& package, const LLSD& benefits_sd) +{ +	LLAgentBenefits benefits; +	if (!benefits.init(benefits_sd)) +	{ +		LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL; +		return false; +	} +	else +	{ +		instance().mPackageMap[package] = benefits; +	} +	return true; + +} + +// static +bool LLAgentBenefitsMgr::initCurrent(const std::string& package, const LLSD& benefits_sd) +{ +	LLAgentBenefits benefits; +	if (!benefits.init(benefits_sd)) +	{ +		LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL; +		return false; +	} +	else +	{ +		instance().mCurrent = benefits; +		instance().mCurrentName = package; +	} +	return true; + +} + +// static +bool LLAgentBenefitsMgr::has(const std::string& package) +{ +	return instance().mPackageMap.find(package) != instance().mPackageMap.end(); +} + +//static +bool LLAgentBenefitsMgr::isCurrent(const std::string& package) +{ +	return instance().mCurrentName == package; +} diff --git a/indra/newview/llagentbenefits.h b/indra/newview/llagentbenefits.h new file mode 100644 index 0000000000..48aa6bd869 --- /dev/null +++ b/indra/newview/llagentbenefits.h @@ -0,0 +1,88 @@ +/** +* @file llagentbenefits.h +* +* $LicenseInfo:firstyear=2019&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2019, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#ifndef LL_AGENTBENEFITS_H +#define LL_AGENTBENEFITS_H + +#include "llsingleton.h" +#include "llsd.h" +#include "llassettype.h" + +class LLAgentBenefits +{ +public: +	LLAgentBenefits(); +	~LLAgentBenefits(); +	LOG_CLASS(LLAgentBenefits); + +	bool init(const LLSD& benefits_sd); + +	S32 getAnimatedObjectLimit() const; +	S32 getAnimationUploadCost() const; +	S32 getAttachmentLimit() const; +	S32 getCreateGroupCost() const; +	S32 getGroupMembershipLimit() const; +	S32 getPicksLimit() const; +	S32 getSoundUploadCost() const; +	S32 getTextureUploadCost() const; + +	bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const; +	 +private: +	S32 m_animated_object_limit; +	S32 m_animation_upload_cost; +	S32 m_attachment_limit; +	S32 m_create_group_cost; +	S32 m_group_membership_limit; +	S32 m_picks_limit; +	S32 m_sound_upload_cost; +	S32 m_texture_upload_cost; + +	bool m_initalized; +}; + +class LLAgentBenefitsMgr: public LLSingleton<LLAgentBenefitsMgr>  +{ +	LLSINGLETON(LLAgentBenefitsMgr); +	~LLAgentBenefitsMgr(); +	LOG_CLASS(LLAgentBenefitsMgr); + +public: +	static const LLAgentBenefits& current(); +	static const LLAgentBenefits& get(const std::string& package); +	static bool init(const std::string& package, const LLSD& benefits_sd); +	static bool initCurrent(const std::string& package, const LLSD& benefits_sd); +	static bool has(const std::string& package); +	static bool isCurrent(const std::string& package); + +private: +	std::string     mCurrentName; +	LLAgentBenefits mCurrent; +	LLAgentBenefits mDefault; +	std::map<std::string, LLAgentBenefits> mPackageMap; +}; + + +#endif diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index ee7e6f8562..131d9b077b 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -31,13 +31,13 @@  #include "llbvhloader.h"  #include "lldatapacker.h"  #include "lldir.h" -#include "lleconomy.h"  #include "llnotificationsutil.h"  #include "llvfile.h"  #include "llapr.h"  #include "llstring.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llanimationstates.h"  #include "llbbox.h"  #include "llbutton.h" @@ -68,7 +68,8 @@  const S32 PREVIEW_BORDER_WIDTH = 2;  const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;  const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; -const S32 PREF_BUTTON_HEIGHT = 16; +const S32 PREVIEW_VPAD = 35; +const S32 PREF_BUTTON_HEIGHT = 16 + 35;  const S32 PREVIEW_TEXTURE_HEIGHT = 300;  const F32 PREVIEW_CAMERA_DISTANCE = 4.f; @@ -203,7 +204,7 @@ BOOL LLFloaterBvhPreview::postBuild()  	setDefaultBtn();  	mPreviewRect.set(PREVIEW_HPAD,  -		PREVIEW_TEXTURE_HEIGHT, +		PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,  		getRect().getWidth() - PREVIEW_HPAD,   		PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);  	mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f); @@ -403,13 +404,13 @@ void LLFloaterBvhPreview::draw()  		gGL.begin( LLRender::QUADS );  		{  			gGL.texCoord2f(0.f, 1.f); -			gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); +			gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);  			gGL.texCoord2f(0.f, 0.f);  			gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);  			gGL.texCoord2f(1.f, 0.f);  			gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);  			gGL.texCoord2f(1.f, 1.f); -			gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); +			gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);  		}  		gGL.end(); @@ -1004,16 +1005,18 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)  			{  				std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();  				std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString(); -				S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); +				S32 expected_upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost(); -                LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo( +                LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(                      floaterp->mTransactionID, LLAssetType::AT_ANIMATION,                      name, desc, 0,                      LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION, -                    LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), +                    LLFloaterPerms::getNextOwnerPerms("Uploads"), +					LLFloaterPerms::getGroupPerms("Uploads"), +					LLFloaterPerms::getEveryonePerms("Uploads"),                      expected_upload_cost)); -                upload_new_resource(assetUpdloadInfo); +                upload_new_resource(assetUploadInfo);  			}  			else  			{ diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index dbe7fee108..f341e2ebcb 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -38,6 +38,7 @@  #include "roles_constants.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llbutton.h"  #include "llgroupactions.h"  #include "llscrolllistctrl.h" @@ -172,7 +173,7 @@ void LLPanelGroups::reset()  		group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);  	}  	getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size())); -	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",gMaxAgentGroups)); +	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",LLAgentBenefitsMgr::current().getGroupMembershipLimit()));  	init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());  	enableButtons(); @@ -183,7 +184,7 @@ BOOL LLPanelGroups::postBuild()  	childSetCommitCallback("group list", onGroupList, this);  	getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size())); -	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",gMaxAgentGroups)); +	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",LLAgentBenefitsMgr::current().getGroupMembershipLimit()));  	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("group list");  	if (list) diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index d4b0fa85ab..696f748613 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -63,8 +63,8 @@  const S32 PREVIEW_BORDER_WIDTH = 2;  const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;  const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; -const S32 PREVIEW_VPAD = -24;	// yuk, hard coded -const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16; +const S32 PREVIEW_VPAD = -24 + 35;	// yuk, hard coded +const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16 + 35;  const S32 PREVIEW_TEXTURE_HEIGHT = 320;  //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 8a894c4ec8..bc44e37c5a 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -44,7 +44,6 @@  #include "lldrawable.h"  #include "llrender.h"  #include "llface.h" -#include "lleconomy.h"  #include "llfocusmgr.h"  #include "llfloaterperms.h"  #include "lliconctrl.h" diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 7cde061515..1e9549a04e 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -46,12 +46,13 @@  #include "llnotificationsutil.h"  #include "lluictrlfactory.h"  #include "llstring.h" -#include "lleconomy.h"  #include "llpermissions.h" +#include "lltrans.h"  // linden includes  #include "llassetstorage.h"  #include "llinventorytype.h" +#include "llagentbenefits.h"  const S32 PREVIEW_LINE_HEIGHT = 19;  const S32 PREVIEW_BORDER_WIDTH = 2; @@ -123,13 +124,39 @@ BOOL LLFloaterNameDesc::postBuild()  	// Cancel button  	getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this)); -	getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload() )); +	S32 expected_upload_cost = getExpectedUploadCost(); +	getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", expected_upload_cost)); + +	LLTextBox* info_text = getChild<LLTextBox>("info_text"); +	if (info_text) +	{ +		info_text->setValue(LLTrans::getString("UploadFeeInfo")); +	}  	setDefaultBtn("ok_btn");  	return TRUE;  } +S32 LLFloaterNameDesc::getExpectedUploadCost() const +{ +    std::string exten = gDirUtilp->getExtension(mFilename); +	LLAssetType::EType asset_type; +	S32 upload_cost = -1; +	if (LLResourceUploadInfo::findAssetTypeOfExtension(exten, asset_type)) +	{ +		if (!LLAgentBenefitsMgr::current().findUploadCost(asset_type, upload_cost)) +		{ +			LL_WARNS() << "Unable to find upload cost for asset type " << asset_type << LL_ENDL; +		} +	} +	else +	{ +		LL_WARNS() << "Unable to find upload cost for " << mFilename << LL_ENDL; +	} +	return upload_cost; +} +  //-----------------------------------------------------------------------------  // LLFloaterNameDesc()  //----------------------------------------------------------------------------- @@ -162,8 +189,7 @@ void LLFloaterNameDesc::onBtnOK( )  	getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads  	LLAssetStorage::LLStoreAssetCallback callback; -	S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). - +	S32 expected_upload_cost = getExpectedUploadCost();      if (can_afford_transaction(expected_upload_cost))      {          void *nruserdata = NULL; @@ -185,7 +211,7 @@ void LLFloaterNameDesc::onBtnOK( )      {          LLSD args;          args["COST"] = llformat("%d", expected_upload_cost); -        LLNotificationsUtil::add("ErrorTextureCannotAfford", args); +        LLNotificationsUtil::add("ErrorCannotAffordUpload", args);      }  	closeFloater(false); diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h index 41643681ac..589f470e82 100644 --- a/indra/newview/llfloaternamedesc.h +++ b/indra/newview/llfloaternamedesc.h @@ -30,6 +30,7 @@  #include "llfloater.h"  #include "llresizehandle.h"  #include "llstring.h" +#include "llassettype.h"  class LLLineEditor;  class LLButton; @@ -45,6 +46,8 @@ public:  	void		onBtnOK();  	void		onBtnCancel();  	void		doCommit(); + +	S32			getExpectedUploadCost() const;  protected:  	virtual void		onCommit(); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 960fd9620d..4cc43254a5 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -102,7 +102,6 @@ public:      virtual LLSD        prepareUpload();      virtual LLSD        generatePostBody(); -    virtual S32         getEconomyUploadCost();      virtual LLUUID      finishUpload(LLSD &result);      virtual bool        showInventoryPanel() const { return false; } @@ -129,11 +128,6 @@ LLSD LLARScreenShotUploader::generatePostBody()      return mReport;  } -S32 LLARScreenShotUploader::getEconomyUploadCost() -{   // Abuse report screen shots do not cost anything to upload. -    return 0; -} -  LLUUID LLARScreenShotUploader::finishUpload(LLSD &result)  {      /* *TODO$: Report success or failure. Carried over from previous todo on responder*/ diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 599790d2bb..d2bd716f55 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -400,10 +400,10 @@ void LLGroupActions::createGroup()  {  	LLSD params;  	params["group_id"] = LLUUID::null; -	params["open_tab_name"] = "panel_group_info_sidetray"; +	params["open_tab_name"] = "panel_group_creation_sidetray";  	params["action"] = "create"; -	LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params); +	LLFloaterSidePanelContainer::showPanel("people", "panel_group_creation_sidetray", params);  }  //static diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 088d052533..dbf7639539 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -44,9 +44,8 @@  #include "roles_constants.h"  #include "lltransactiontypes.h"  #include "llstatusbar.h" -#include "lleconomy.h"  #include "llviewerwindow.h" -#include "llpanelgroup.h" +#include "llpanelgroupcreate.h"  #include "llgroupactions.h"  #include "llnotificationsutil.h"  #include "lluictrlfactory.h" @@ -1452,7 +1451,7 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)  		gAgent.mGroups.push_back(gd); -		LLPanelGroup::refreshCreatedGroup(group_id); +		LLPanelGroupCreate::refreshCreatedGroup(group_id);  		//FIXME  		//LLFloaterGroupInfo::closeCreateGroup();  		//LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab"); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 95322cce6d..1d76dd7928 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -41,7 +41,6 @@  #include "lldeadmantimer.h"  #include "llfloatermodelpreview.h"  #include "llfloaterperms.h" -#include "lleconomy.h"  #include "llimagej2c.h"  #include "llhost.h"  #include "llmath.h" diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 278d83bab7..520c9adcd1 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -36,7 +36,7 @@  #include "llaccordionctrltab.h"  #include "llappearancemgr.h" -#include "lleconomy.h" +#include "llagentbenefits.h"  #include "llerror.h"  #include "llfilepicker.h"  #include "llfloaterperms.h" @@ -910,6 +910,7 @@ bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param)  bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param)  { +	mMenuHandle.get()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));      if ("remove_photo" == param)      {          LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); @@ -1205,7 +1206,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filename              return;          } -        S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). +        S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();          void *nruserdata = NULL;          nruserdata = (void *)&outfit_id; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index f2a284a561..71ab826e1c 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -35,6 +35,7 @@  #include "llaccordionctrltab.h"  #include "llagentwearables.h"  #include "llappearancemgr.h" +#include "llagentbenefits.h"  #include "llfloatersidepanelcontainer.h"  #include "llinventoryfunctions.h"  #include "llinventorymodel.h" @@ -1235,6 +1236,7 @@ bool LLOutfitListGearMenuBase::onEnable(LLSD::String param)  bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)  { +	getMenu()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));      const LLUUID& selected_outfit_id = getSelectedOutfitID();      if (selected_outfit_id.isNull()) // no selection or invalid outfit selected      { diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 451f41cd3b..3bae0cebfb 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -30,7 +30,6 @@  #include "llpanelcontents.h"  // linden library includes -#include "lleconomy.h"  #include "llerror.h"  #include "llfloaterreg.h"  #include "llfontgl.h" diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index e41211ddbd..ab255d5215 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -128,10 +128,6 @@ void LLPanelGroup::onOpen(const LLSD& key)  	{  		onBackBtnClick();  	} -	else if(str_action == "create") -	{ -		setGroupID(LLUUID::null); -	}  	else if(str_action == "refresh_notices")  	{  		LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel"); @@ -162,12 +158,8 @@ BOOL LLPanelGroup::postBuild()  	button = getChild<LLButton>("btn_refresh");  	button->setClickedCallback(onBtnRefresh, this); -	getChild<LLButton>("btn_create")->setVisible(false); -  	childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL); -	childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL); -  	LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");  	LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");  	LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel"); @@ -223,7 +215,6 @@ void LLPanelGroup::reposButtons()  	}  	reposButton("btn_apply"); -	reposButton("btn_create");  	reposButton("btn_refresh");  	reposButton("btn_cancel");  	reposButton("btn_chat"); @@ -246,23 +237,6 @@ void LLPanelGroup::onBackBtnClick()  	}  } - -void LLPanelGroup::onBtnCreate() -{ -	LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel"); -	if(!panel_general) -		return; -	std::string apply_mesg; -	if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create... -		return; -	if ( !apply_mesg.empty() ) -	{ -		LLSD args; -		args["MESSAGE"] = apply_mesg; -		LLNotificationsUtil::add("GenericAlert", args); -	} -} -  void LLPanelGroup::onBtnRefresh(void* user_data)  {  	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); @@ -378,7 +352,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	LLButton* button_apply = findChild<LLButton>("btn_apply");  	LLButton* button_refresh = findChild<LLButton>("btn_refresh"); -	LLButton* button_create = findChild<LLButton>("btn_create");  	LLButton* button_cancel = findChild<LLButton>("btn_cancel");  	LLButton* button_call = findChild<LLButton>("btn_call"); @@ -391,8 +364,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	if(button_refresh)  		button_refresh->setVisible(!is_null_group_id); -	if(button_create) -		button_create->setVisible(is_null_group_id);  	if(button_cancel)  		button_cancel->setVisible(!is_null_group_id); @@ -611,18 +582,6 @@ void LLPanelGroup::showNotice(const std::string& subject,  	panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);  } - - - -//static -void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id) -{ -	LLPanelGroup* panel = LLFloaterSidePanelContainer::getPanel<LLPanelGroup>("people", "panel_group_info_sidetray"); -	if(!panel) -		return; -	panel->setGroupID(group_id); -} -  //static  void LLPanelGroup::showNotice(const std::string& subject, diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 0b40c8b5d3..be40b08a6d 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -79,8 +79,6 @@ public:  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); -	static void refreshCreatedGroup(const LLUUID& group_id); -  	static void showNotice(const std::string& subject,  						   const std::string& message,  						   const LLUUID& group_id, @@ -92,7 +90,6 @@ public:  protected:  	virtual void update(LLGroupChange gc); -	void onBtnCreate();  	void onBackBtnClick();  	void onBtnJoin(); diff --git a/indra/newview/llpanelgroupcreate.cpp b/indra/newview/llpanelgroupcreate.cpp new file mode 100644 index 0000000000..052212dc27 --- /dev/null +++ b/indra/newview/llpanelgroupcreate.cpp @@ -0,0 +1,237 @@ +/**  + * @file llpanelgroupcreate.cpp + * + * $LicenseInfo:firstyear=2019&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupcreate.h" + +// UI includes +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloatersidepanelcontainer.h" +#include "llsidetraypanelcontainer.h" +#include "llscrolllistctrl.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lluictrlfactory.h" + +// Viewer includes +#include "llagentbenefits.h" +#include "llfloaterreg.h" +#include "llfloater.h" +#include "llgroupmgr.h" +#include "lltrans.h" +#include "llnotificationsutil.h" +#include "lluicolortable.h" + + +const S32 MATURE_CONTENT = 1; +const S32 NON_MATURE_CONTENT = 2; +const S32 DECLINE_TO_STATE = 0; + +static LLPanelInjector<LLPanelGroupCreate> t_panel_group_creation("panel_group_creation_sidetray"); + +LLPanelGroupCreate::LLPanelGroupCreate() +:    LLPanel() +{ +} + +LLPanelGroupCreate::~LLPanelGroupCreate() +{ +} + +BOOL LLPanelGroupCreate::postBuild() +{ +    childSetCommitCallback("back", boost::bind(&LLPanelGroupCreate::onBackBtnClick, this), NULL); + +    mComboMature = getChild<LLComboBox>("group_mature_check", TRUE); +    mCtrlOpenEnrollment = getChild<LLCheckBoxCtrl>("open_enrollement", TRUE); +    mCtrlEnrollmentFee = getChild<LLCheckBoxCtrl>("check_enrollment_fee", TRUE); +    mEditCharter = getChild<LLTextEditor>("charter", TRUE); +    mSpinEnrollmentFee = getChild<LLSpinCtrl>("spin_enrollment_fee", TRUE); +    mMembershipList = getChild<LLScrollListCtrl>("membership_list", TRUE); + +    mCreateButton = getChild<LLButton>("btn_create", TRUE); +    mCreateButton->setCommitCallback(boost::bind(&LLPanelGroupCreate::onBtnCreate, this)); + +    mGroupNameEditor = getChild<LLLineEditor>("group_name_editor", TRUE); +    mGroupNameEditor->setPrevalidate(LLTextValidate::validateASCIINoLeadingSpace); + +    mInsignia = getChild<LLTextureCtrl>("insignia", TRUE); +    mInsignia->setAllowLocalTexture(FALSE); +    mInsignia->setCanApplyImmediately(FALSE); + +    return TRUE; +} + +void LLPanelGroupCreate::onOpen(const LLSD& key) +{ +    mInsignia->setImageAssetID(LLUUID::null); +    mInsignia->setImageAssetName(mInsignia->getDefaultImageName()); +    mGroupNameEditor->clear(); +    mEditCharter->clear(); +    mSpinEnrollmentFee->set(0.f); +    mCtrlEnrollmentFee->set(FALSE); +    mCtrlOpenEnrollment->set(FALSE); +    mMembershipList->clearRows(); + +    // populate list +    addMembershipRow("Base"); +    addMembershipRow("Premium"); +    addMembershipRow("Premium Plus"); +    addMembershipRow("Internal");// Present only if you are already in one, needed for testing + +    S32 cost = LLAgentBenefitsMgr::current().getCreateGroupCost(); +    mCreateButton->setLabelArg("[COST]", llformat("%d", cost)); +} + +//static +void LLPanelGroupCreate::refreshCreatedGroup(const LLUUID& group_id) +{ +    LLSD params; +    params["group_id"] = group_id; +    params["open_tab_name"] = "panel_group_info_sidetray"; +    LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params); +} + +void LLPanelGroupCreate::addMembershipRow(const std::string &name) +{ +    if (LLAgentBenefitsMgr::has(name)) +    { +        bool is_current = LLAgentBenefitsMgr::isCurrent(name); + +        LLScrollListItem::Params item_params; +        LLScrollListCell::Params cell_params; +        cell_params.font = LLFontGL::getFontSansSerif(); +        // Start out right justifying numeric displays +        cell_params.font_halign = LLFontGL::LEFT; +        if (is_current) +        { +            cell_params.color = LLUIColorTable::instance().getColor("DrYellow"); +        } + +        cell_params.column = "clmn_name"; +        std::string mem_str = name + "Membership"; +        if (is_current) +        { +            cell_params.value = LLTrans::getString(mem_str) + " " + getString("current_membership"); +        } +        else +        { +            cell_params.value = LLTrans::getString(mem_str); +        } +        item_params.columns.add(cell_params); +        cell_params.column = "clmn_price"; +        cell_params.value = llformat("L$ %d",LLAgentBenefitsMgr::get(name).getCreateGroupCost()); +        item_params.columns.add(cell_params); +        mMembershipList->addRow(item_params); +    } +} + +void LLPanelGroupCreate::onBackBtnClick() +{ +    LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); +    if(parent) +    { +        parent->openPreviousPanel(); +    } +} + +bool LLPanelGroupCreate::confirmMatureApply(const LLSD& notification, const LLSD& response) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    // 0 == Yes +    // 1 == No +    // 2 == Cancel +    switch (option) +    { +    case 0: +        mComboMature->setCurrentByIndex(MATURE_CONTENT); +        createGroup(); +        break; +    case 1: +        mComboMature->setCurrentByIndex(NON_MATURE_CONTENT); +        createGroup(); +        break; +    default: +        break; +    } + +    return true; +} + +void LLPanelGroupCreate::onBtnCreate() +{ +    LL_INFOS() << "Validating group creation" << LL_ENDL; + +    // Validate the group name length. +    std::string gr_name = mGroupNameEditor->getText(); +    LLStringUtil::trim(gr_name); +    S32 group_name_len = gr_name.size(); +    if (group_name_len < DB_GROUP_NAME_MIN_LEN +        || group_name_len > DB_GROUP_NAME_STR_LEN) +    { +        LLSD args; +        args["MIN_LEN"] = DB_GROUP_NAME_MIN_LEN; +        args["MAX_LEN"] = DB_GROUP_NAME_STR_LEN; +        LLNotificationsUtil::add("GroupNameLengthWarning", args); +    } +    else +    // Check to make sure mature has been set +    if (mComboMature && +        mComboMature->getCurrentIndex() == DECLINE_TO_STATE) +    { +        LLNotificationsUtil::add("SetGroupMature", LLSD(), LLSD(), +            boost::bind(&LLPanelGroupCreate::confirmMatureApply, this, _1, _2)); +    } +    else +    { +        createGroup(); +    } +} + +void LLPanelGroupCreate::createGroup() +{ +    LL_INFOS() << "Creating group" << LL_ENDL; + +    U32 enrollment_fee = (mCtrlEnrollmentFee->get() ? +        (U32)mSpinEnrollmentFee->get() : 0); +    LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID(); + +    std::string gr_name = mGroupNameEditor->getText(); +    LLStringUtil::trim(gr_name); +    LLGroupMgr::getInstance()->sendCreateGroupRequest(gr_name, +        mEditCharter->getText(), +        true, +        insignia_id, +        enrollment_fee, +        mCtrlOpenEnrollment->get(), +        false, +        mComboMature->getCurrentIndex() == MATURE_CONTENT); +} + diff --git a/indra/newview/llpanelgroupcreate.h b/indra/newview/llpanelgroupcreate.h new file mode 100644 index 0000000000..3ae2e7f24a --- /dev/null +++ b/indra/newview/llpanelgroupcreate.h @@ -0,0 +1,73 @@ +/**  + * @file llpanelgroupcreate.h + * + * $LicenseInfo:firstyear=2019&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELGROUPCREATE_H +#define LL_LLPANELGROUPCREATE_H + +#include "llpanel.h" + + +// Forward declares +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLLineEditor; +class LLTextEditor; +class LLTextureCtrl; +class LLScrollListCtrl; +class LLSpinCtrl; + + +class LLPanelGroupCreate : public LLPanel +{ +public: +    LLPanelGroupCreate(); +    virtual ~LLPanelGroupCreate(); + +    virtual BOOL postBuild(); + +    void onOpen(const LLSD& key); + +    static void refreshCreatedGroup(const LLUUID& group_id); + +private: +    void addMembershipRow(const std::string &name); +    bool confirmMatureApply(const LLSD& notification, const LLSD& response); +    void onBtnCreate(); +    void onBackBtnClick(); +    void createGroup(); + +    LLComboBox       *mComboMature; +    LLButton         *mCreateButton; +    LLCheckBoxCtrl   *mCtrlOpenEnrollment; +    LLCheckBoxCtrl   *mCtrlEnrollmentFee; +    LLTextEditor     *mEditCharter; +    LLTextureCtrl    *mInsignia; +    LLLineEditor     *mGroupNameEditor; +    LLScrollListCtrl *mMembershipList; +    LLSpinCtrl       *mSpinEnrollmentFee; +}; + +#endif // LL_LLPANELGROUPCREATE_H diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index b53cd222e7..375daf60f8 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -30,6 +30,7 @@  #include "llavatarnamecache.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llsdparam.h"  #include "lluictrlfactory.h"  #include "roles_constants.h" @@ -303,6 +304,11 @@ void LLPanelGroupGeneral::draw()  bool LLPanelGroupGeneral::apply(std::string& mesg)  { +	if (mGroupID.isNull()) +	{ +		return false; +	} +  	if (!mGroupID.isNull() && mAllowEdit && mComboActiveTitle && mComboActiveTitle->isDirty())  	{  		LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID()); @@ -312,7 +318,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)  	BOOL has_power_in_group = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY); -	if (has_power_in_group || mGroupID.isNull()) +	if (has_power_in_group)  	{  		LL_INFOS() << "LLPanelGroupGeneral::apply" << LL_ENDL; @@ -325,25 +331,6 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)  			return false;  		} -		if (mGroupID.isNull()) -		{ -			// Validate the group name length. -			S32 group_name_len = mGroupNameEditor->getText().size(); -			if ( group_name_len < DB_GROUP_NAME_MIN_LEN  -				|| group_name_len > DB_GROUP_NAME_STR_LEN) -			{ -				std::ostringstream temp_error; -				temp_error << "A group name must be between " << DB_GROUP_NAME_MIN_LEN -					<< " and " << DB_GROUP_NAME_STR_LEN << " characters."; -				mesg = temp_error.str(); -				return false; -			} - -			LLNotificationsUtil::add("CreateGroupCost",  LLSD(), LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2)); - -			return false; -		} -  		LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);  		if (!gdatap)  		{ @@ -450,37 +437,6 @@ bool LLPanelGroupGeneral::confirmMatureApply(const LLSD& notification, const LLS  	return ret;  } -// static -bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LLSD& response) -{ -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -	switch(option) -	{ -	case 0: -		{ -			// Yay!  We are making a new group! -			U32 enrollment_fee = (mCtrlEnrollmentFee->get() ?  -									(U32) mSpinEnrollmentFee->get() : 0); -			LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID(); - -			LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(), -												mEditCharter->getText(), -												mCtrlShowInGroupList->get(), -												insignia_id, -												enrollment_fee, -												mCtrlOpenEnrollment->get(), -												false, -												mComboMature->getCurrentIndex() == MATURE_CONTENT); - -		} -		break; -	case 1: -	default: -		break; -	} -	return false; -} -  // virtual  void LLPanelGroupGeneral::update(LLGroupChange gc)  { diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 11972bafa9..1d0789521c 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -51,7 +51,6 @@ public:  	virtual bool needsApply(std::string& mesg);  	virtual bool apply(std::string& mesg);  	virtual void cancel(); -	bool createGroupCallback(const LLSD& notification, const LLSD& response);  	virtual void update(LLGroupChange gc); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index b40a7ef1f0..02cd22c307 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -28,12 +28,12 @@  #include "llpanelmaininventory.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llavataractions.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h"  #include "lldndbutton.h" -#include "lleconomy.h"  #include "llfilepicker.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" @@ -231,16 +231,16 @@ BOOL LLPanelMainInventory::postBuild()  	initListCommandsHandlers(); -	// *TODO:Get the cost info from the server -	const std::string upload_cost("10"); +	const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()); +	const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); +	const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());  	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();  	if (menu)  	{ -		menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost); -		menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost); -		menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost); -		menu->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost); +		menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str); +		menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); +		menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);  	}  	// Trigger callback for focus received so we can deselect items in inbox/outbox @@ -1517,36 +1517,16 @@ bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType  void LLPanelMainInventory::setUploadCostIfNeeded()  { -	// *NOTE dzaporozhan -	// Upload cost is set in process_economy_data() (llviewermessage.cpp). But since we -	// have two instances of Inventory panel at the moment(and two instances of context menu), -	// call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances. -  	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();  	if(mNeedUploadCost && menu)  	{ -		LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload"); -		if(upload_menu) -		{ -			S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); -			std::string cost_str; - -			// getPriceUpload() returns -1 if no data available yet. -			if(upload_cost >= 0) -			{ -				mNeedUploadCost = false; -				cost_str = llformat("%d", upload_cost); -			} -			else -			{ -				cost_str = llformat("%d", gSavedSettings.getU32("DefaultUploadCost")); -			} +		const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()); +		const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); +		const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); -			upload_menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", cost_str); -			upload_menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", cost_str); -			upload_menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", cost_str); -			upload_menu->getChild<LLView>("Bulk Upload")->setLabelArg("[COST]", cost_str); -		} +		menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str); +		menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); +		menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);  	}  } diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 3665910c63..6bff95ab36 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -30,7 +30,6 @@  #include "llpanelobject.h"  // linden library includes -#include "lleconomy.h"  #include "llerror.h"  #include "llfontgl.h"  #include "llpermissionsflags.h" diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index be174475e1..e5142f2b5f 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -47,6 +47,7 @@  #include "llaccordionctrl.h"  #include "llaccordionctrltab.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llavataractions.h"  #include "llavatarlist.h"  #include "llavatarlistitem.h" @@ -85,11 +86,6 @@ static const std::string RECENT_TAB_NAME	= "recent_panel";  static const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars  static const std::string COLLAPSED_BY_USER  = "collapsed_by_user"; -const S32 BASE_MAX_AGENT_GROUPS = 42; -const S32 PREMIUM_MAX_AGENT_GROUPS = 60; - -extern S32 gMaxAgentGroups; -  /** Comparator for comparing avatar items by last interaction date */  class LLAvatarItemRecentComparator : public LLAvatarItemComparator  { @@ -612,26 +608,17 @@ void LLPanelPeople::removePicker()  BOOL LLPanelPeople::postBuild()  { -	S32 max_premium = PREMIUM_MAX_AGENT_GROUPS;  -	if (gAgent.getRegion()) -	{ -		LLSD features; -		gAgent.getRegion()->getSimulatorFeatures(features); -		if (features.has("MaxAgentGroupsPremium")) -		{ -			max_premium = features["MaxAgentGroupsPremium"].asInteger(); -		} -	} +	S32 max_premium = LLAgentBenefitsMgr::get("Premium").getGroupMembershipLimit();  	getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); -	if(gMaxAgentGroups < max_premium) +	if(LLAgentBenefitsMgr::current().getGroupMembershipLimit() < max_premium)  	{ -	    getChild<LLTextBox>("groupcount")->setText(getString("GroupCountWithInfo")); -	    getChild<LLTextBox>("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this)); +		getChild<LLTextBox>("groupcount")->setText(getString("GroupCountWithInfo")); +		getChild<LLTextBox>("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));  	}  	mTabContainer = getChild<LLTabContainer>("tabs"); @@ -876,9 +863,10 @@ void LLPanelPeople::updateButtons()  		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected  		U32 groups_count = gAgent.mGroups.size(); -		U32 groups_ramaining = gMaxAgentGroups > groups_count ? gMaxAgentGroups - groups_count : 0; +		S32 max_groups = LLAgentBenefitsMgr::current().getGroupMembershipLimit(); +		U32 groups_remaining = max_groups > groups_count ? max_groups - groups_count : 0;  		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d", groups_count)); -		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d", groups_ramaining)); +		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d", groups_remaining));  	}  	else  	{ @@ -1095,25 +1083,22 @@ void LLPanelPeople::onGroupLimitInfo()  {  	LLSD args; -	S32 max_basic = BASE_MAX_AGENT_GROUPS; -	S32 max_premium = PREMIUM_MAX_AGENT_GROUPS; -	if (gAgent.getRegion()) +	S32 max_basic = LLAgentBenefitsMgr::get("Base").getGroupMembershipLimit(); +	S32 max_premium = LLAgentBenefitsMgr::get("Premium").getGroupMembershipLimit(); +	 +	args["MAX_BASIC"] = max_basic; +	args["MAX_PREMIUM"] = max_premium; + +	if (LLAgentBenefitsMgr::has("Premium Plus"))  	{ -		LLSD features; -		gAgent.getRegion()->getSimulatorFeatures(features); -		if (features.has("MaxAgentGroupsBasic")) -		{ -			max_basic = features["MaxAgentGroupsBasic"].asInteger(); -		} -		if (features.has("MaxAgentGroupsPremium")) -		{ -			max_premium = features["MaxAgentGroupsPremium"].asInteger(); -		} +		S32 max_premium_plus = LLAgentBenefitsMgr::get("Premium Plus").getGroupMembershipLimit(); +		args["MAX_PREMIUM_PLUS"] = max_premium_plus; +		LLNotificationsUtil::add("GroupLimitInfoPlus", args);  	} -	args["MAX_BASIC"] = max_basic;  -	args["MAX_PREMIUM"] = max_premium;  - -	LLNotificationsUtil::add("GroupLimitInfo", args); +	else +	{ +		LLNotificationsUtil::add("GroupLimitInfo", args); +	}	  }  void LLPanelPeople::onTabSelected(const LLSD& param) diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp index a17e3f9e78..c3524a8c87 100644 --- a/indra/newview/llpanelsnapshot.cpp +++ b/indra/newview/llpanelsnapshot.cpp @@ -39,6 +39,8 @@  #include "llsidetraypanelcontainer.h"  #include "llviewercontrol.h" // gSavedSettings +#include "llagentbenefits.h" +  const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512  S32 power_of_two(S32 sz, S32 upper) @@ -59,6 +61,7 @@ LLPanelSnapshot::LLPanelSnapshot()  // virtual  BOOL LLPanelSnapshot::postBuild()  { +	getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));  	getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1));      if (!getWidthSpinnerName().empty())      { diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index 21ac7604ff..9e56a04b3b 100644 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -27,7 +27,6 @@  #include "llviewerprecompiledheaders.h"  #include "llcombobox.h" -#include "lleconomy.h"  #include "llsidetraypanelcontainer.h"  #include "llspinctrl.h" @@ -38,6 +37,8 @@  #include "llstatusbar.h"	// can_afford_transaction()  #include "llnotificationsutil.h" +#include "llagentbenefits.h" +  /**   * The panel provides UI for saving snapshot as an inventory texture.   */ @@ -135,7 +136,6 @@ BOOL LLPanelSnapshotInventory::postBuild()  // virtual  void LLPanelSnapshotInventory::onOpen(const LLSD& key)  { -	getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload()));  	LLPanelSnapshot::onOpen(key);  } @@ -155,7 +155,7 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)  void LLPanelSnapshotInventoryBase::onSend()  { -    S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); +    S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();      if (can_afford_transaction(expected_upload_cost))      {          if (mSnapshotFloater) @@ -191,7 +191,7 @@ BOOL LLPanelOutfitSnapshotInventory::postBuild()  // virtual  void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key)  { -    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); +    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost()));      LLPanelSnapshot::onOpen(key);  } diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 1a3e946127..8cc2fbc770 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -26,19 +26,20 @@  #include "llviewerprecompiledheaders.h" -#include "lleconomy.h"  #include "llpanel.h"  #include "llsidetraypanelcontainer.h"  #include "llfloatersnapshot.h" // FIXME: create a snapshot model  #include "llfloaterreg.h" +#include "llagentbenefits.h" + +  /**   * Provides several ways to save a snapshot.   */  class LLPanelSnapshotOptions  :	public LLPanel -,	public LLEconomyObserver  {  	LOG_CLASS(LLPanelSnapshotOptions); @@ -47,7 +48,6 @@ public:  	~LLPanelSnapshotOptions();  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); -	/*virtual*/ void onEconomyDataChange() { updateUploadCost(); }  private:  	void updateUploadCost(); @@ -68,13 +68,10 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()  	mCommitCallbackRegistrar.add("Snapshot.SaveToEmail",		boost::bind(&LLPanelSnapshotOptions::onSaveToEmail,		this));  	mCommitCallbackRegistrar.add("Snapshot.SaveToInventory",	boost::bind(&LLPanelSnapshotOptions::onSaveToInventory,	this));  	mCommitCallbackRegistrar.add("Snapshot.SaveToComputer",		boost::bind(&LLPanelSnapshotOptions::onSaveToComputer,	this)); - -	LLGlobalEconomy::getInstance()->addObserver(this);  }  LLPanelSnapshotOptions::~LLPanelSnapshotOptions()  { -	LLGlobalEconomy::getInstance()->removeObserver(this);  }  // virtual @@ -92,7 +89,7 @@ void LLPanelSnapshotOptions::onOpen(const LLSD& key)  void LLPanelSnapshotOptions::updateUploadCost()  { -	S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); +	S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();  	getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost));  } diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index d50cda2113..2b531b6acc 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -31,7 +31,6 @@  // linden library includes  #include "llclickaction.h" -#include "lleconomy.h"  #include "llerror.h"  #include "llfontgl.h"  #include "llflexibleobject.h" diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index aee6bcb05e..56068b3bbb 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -35,7 +35,6 @@  #include "llcachename.h"  #include "llavatarnamecache.h"  #include "lldbstrings.h" -#include "lleconomy.h"  #include "llgl.h"  #include "llmediaentry.h"  #include "llrender.h" diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index b448caeb0b..356f2e81ce 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -28,10 +28,10 @@  #include "llviewerprecompiledheaders.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llagentui.h"  #include "llcombobox.h" -#include "lleconomy.h"  #include "llfloaterperms.h"  #include "llfloaterreg.h"  #include "llimagefilter.h" @@ -1009,7 +1009,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)  		LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);  		std::string who_took_it;  		LLAgentUI::buildFullname(who_took_it); -		S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); +		S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();          std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string;          std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string;          LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 42cf04fba7..8093a3a589 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -88,6 +88,7 @@  #include "v3math.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llagentpicksinfo.h"  #include "llagentwearables.h" @@ -209,7 +210,6 @@  // exported globals  //  bool gAgentMovementCompleted = false; -S32  gMaxAgentGroups;  const std::string SCREEN_HOME_FILENAME = "screen_home%s.png";  const std::string SCREEN_LAST_FILENAME = "screen_last%s.png"; @@ -246,9 +246,8 @@ static std::string gFirstSimSeedCap;  static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);  static std::string gAgentStartLocation = "safe";  static bool mLoginStatePastUI = false; +static bool mBenefitsSuccessfullyInit = false; -const S32 DEFAULT_MAX_AGENT_GROUPS = 42; -const S32 ALLOWED_MAX_AGENT_GROUPS = 500;  const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds  boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState")); @@ -279,6 +278,7 @@ void general_cert_done(const LLSD& notification, const LLSD& response);  void trust_cert_done(const LLSD& notification, const LLSD& response);  void apply_udp_blacklist(const std::string& csv);  bool process_login_success_response(); +void on_benefits_failed_callback(const LLSD& notification, const LLSD& response);  void transition_back_to_login_panel(const std::string& emsg);  void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group) @@ -1564,8 +1564,6 @@ bool idle_startup()  			send_complete_agent_movement(regionp->getHost());  			gAssetStorage->setUpstream(regionp->getHost());  			gCacheName->setUpstream(regionp->getHost()); -			msg->newMessageFast(_PREHASH_EconomyDataRequest); -			gAgent.sendReliableMessage();  		}  		display_startup(); @@ -2151,6 +2149,11 @@ bool idle_startup()  		set_startup_status(1.0, "", "");  		display_startup(); +		if (!mBenefitsSuccessfullyInit) +		{ +			LLNotificationsUtil::add("FailedToGetBenefits", LLSD(), LLSD(), boost::bind(on_benefits_failed_callback, _1, _2)); +		} +  		// Let the map know about the inventory.  		LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();  		if(floater_world_map) @@ -3268,10 +3271,70 @@ void apply_udp_blacklist(const std::string& csv)  } +void on_benefits_failed_callback(const LLSD& notification, const LLSD& response) +{ +	LL_WARNS("Benefits") << "Failed to load benefits information" << LL_ENDL;  +} + +bool init_benefits(LLSD& response) +{ +	bool succ = true; + +	std::string package_name = response["account_type"].asString(); +	const LLSD& benefits_sd = response["account_level_benefits"]; +	if (!LLAgentBenefitsMgr::init(package_name, benefits_sd) || +		!LLAgentBenefitsMgr::initCurrent(package_name, benefits_sd)) +	{ +		succ = false; +	} +	else +	{ +		LL_DEBUGS("Benefits") << "Initialized current benefits, level " << package_name << " from " << benefits_sd << LL_ENDL; +	} +	const LLSD& packages_sd = response["premium_packages"]; +	for(LLSD::map_const_iterator package_iter = packages_sd.beginMap(); +		package_iter != packages_sd.endMap(); +		++package_iter) +	{ +		std::string package_name = package_iter->first; +		const LLSD& benefits_sd = package_iter->second["benefits"]; +		if (LLAgentBenefitsMgr::init(package_name, benefits_sd)) +		{ +			LL_DEBUGS("Benefits") << "Initialized benefits for package " << package_name << " from " << benefits_sd << LL_ENDL; +		} +		else +		{ +			LL_WARNS("Benefits") << "Failed init for package " << package_name << " from " << benefits_sd << LL_ENDL; +			succ = false; +		} +	} + +	if (!LLAgentBenefitsMgr::has("Base")) +	{ +		LL_WARNS("Benefits") << "Benefits info did not include required package Base" << LL_ENDL; +		succ = false; +	} +	if (!LLAgentBenefitsMgr::has("Premium")) +	{ +		LL_WARNS("Benefits") << "Benefits info did not include required package Premium" << LL_ENDL; +		succ = false; +	} + +	// FIXME PREMIUM - for testing if login does not yet provide Premium Plus. Should be removed thereafter. +	//if (succ && !LLAgentBenefitsMgr::has("Premium Plus")) +	//{ +	//	LLAgentBenefitsMgr::init("Premium Plus", packages_sd["Premium"]["benefits"]); +	//	llassert(LLAgentBenefitsMgr::has("Premium Plus")); +	//} +	return succ; +} +  bool process_login_success_response()  {  	LLSD response = LLLoginInstance::getInstance()->getResponse(); +	mBenefitsSuccessfullyInit = init_benefits(response); +  	std::string text(response["udp_blacklist"]);  	if(!text.empty())  	{ @@ -3594,27 +3657,6 @@ bool process_login_success_response()  		LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);  	} -	gMaxAgentGroups = DEFAULT_MAX_AGENT_GROUPS; -	if(response.has("max-agent-groups")) -	{ -		S32 agent_groups = atoi(std::string(response["max-agent-groups"]).c_str()); -		if (agent_groups > 0 && agent_groups <= ALLOWED_MAX_AGENT_GROUPS) -		{ -			gMaxAgentGroups = agent_groups; -			LL_INFOS("LLStartup") << "gMaxAgentGroups read from login.cgi: " -				<< gMaxAgentGroups << LL_ENDL; -		} -		else -		{ -			LL_INFOS("LLStartup") << "Invalid value received, using defaults for gMaxAgentGroups: " -				<< gMaxAgentGroups << LL_ENDL; -		} -	} -	else { -		LL_INFOS("LLStartup") << "Missing max-agent-groups, using default value for gMaxAgentGroups: " -							  << gMaxAgentGroups << LL_ENDL; -	} -		  	bool success = false;  	// JC: gesture loading done below, when we have an asset system  	// in place.  Don't delete/clear gUserCredentials until then. diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 5ce74b8fae..d7d294e9f4 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -80,7 +80,6 @@ typedef enum {  // exported symbols  extern bool gAgentMovementCompleted; -extern S32  gMaxAgentGroups;  extern LLPointer<LLViewerTexture> gStartTexture;  class LLStartUp diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 6dcd20dc21..6a29be4aa1 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -192,6 +192,11 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  			- 3*VPAD - BTN_HEIGHT;  	// reshape to calculate real text width and height  	msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height ); + +	if ("GroupLimitInfo" == mNotification->getName() || "GroupLimitInfoPlus" == mNotification->getName()) +	{ +		msg_box->setSkipLinkUnderline(true); +	}  	msg_box->setValue(msg);  	S32 pixel_width = msg_box->getTextPixelWidth(); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 2544f75926..d53cc3f745 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -36,7 +36,6 @@  #include "lluploaddialog.h"  #include "llpreviewscript.h"  #include "llnotificationsutil.h" -#include "lleconomy.h"  #include "llagent.h"  #include "llfloaterreg.h"  #include "llfloatersnapshot.h" @@ -171,22 +170,6 @@ void LLResourceUploadInfo::logPreparedUpload()          "Asset Type: " << LLAssetType::lookup(mAssetType) << LL_ENDL;  } -S32 LLResourceUploadInfo::getEconomyUploadCost() -{ -    // Update L$ and ownership credit information -    // since it probably changed on the server -    if (getAssetType() == LLAssetType::AT_TEXTURE || -        getAssetType() == LLAssetType::AT_SOUND || -        getAssetType() == LLAssetType::AT_ANIMATION || -        getAssetType() == LLAssetType::AT_MESH) -    { -        return LLGlobalEconomy::instance().getPriceUpload(); -    } - -    return 0; -} - -  LLUUID LLResourceUploadInfo::finishUpload(LLSD &result)  {      if (getFolderId().isNull()) @@ -323,6 +306,42 @@ std::string LLResourceUploadInfo::getDisplayName() const      return (mName.empty()) ? mAssetId.asString() : mName;  }; +bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LLAssetType::EType& asset_type) +{ +	U32 codec; +	return findAssetTypeAndCodecOfExtension(exten, asset_type, codec, false); +} + +// static +bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload) +{ +	bool succ = false; + +    codec = LLImageBase::getCodecFromExtension(exten); +	if (codec != IMG_CODEC_INVALID) +	{ +		asset_type = LLAssetType::AT_TEXTURE;  +		succ = true; +	} +	else if (exten == "wav") +	{ +		asset_type = LLAssetType::AT_SOUND;  +		succ = true; +	} +	else if (exten == "anim") +	{ +		asset_type = LLAssetType::AT_ANIMATION;  +		succ = true; +	} +	else if (!bulk_upload && (exten == "bvh")) +	{ +		asset_type = LLAssetType::AT_ANIMATION; +		succ = true; +	} + +	return succ; +} +  //=========================================================================  LLNewFileResourceUploadInfo::LLNewFileResourceUploadInfo(      std::string fileName, @@ -360,9 +379,11 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()      std::string filename = gDirUtilp->getTempFilename();      std::string exten = gDirUtilp->getExtension(getFileName()); -    U32 codec = LLImageBase::getCodecFromExtension(exten);      LLAssetType::EType assetType = LLAssetType::AT_NONE; +	U32 codec = IMG_CODEC_INVALID; +	bool found_type = findAssetTypeAndCodecOfExtension(exten, assetType, codec); +      std::string errorMessage;      std::string errorLabel; @@ -379,10 +400,16 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()          errorLabel = "NoFileExtension";          error = true;      } -    else if (codec != IMG_CODEC_INVALID) +    else if (!found_type) +    { +        // Unknown extension +        errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); +        errorLabel = "ErrorMessage"; +        error = TRUE;; +    } +    else if (assetType == LLAssetType::AT_TEXTURE)      {          // It's an image file, the upload procedure is the same for all -        assetType = LLAssetType::AT_TEXTURE;          if (!LLViewerTextureList::createUploadFile(getFileName(), filename, codec))          {              errorMessage = llformat("Problem with file %s:\n\n%s\n", @@ -391,9 +418,8 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()              error = true;          }      } -    else if (exten == "wav") +    else if (assetType == LLAssetType::AT_SOUND)      { -        assetType = LLAssetType::AT_SOUND;  // tag it as audio          S32 encodeResult = 0;          LL_INFOS() << "Attempting to encode wav as an ogg file" << LL_ENDL; @@ -423,18 +449,10 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()          errorLabel = "DoNotSupportBulkAnimationUpload";          error = true;      } -    else if (exten == "anim") +    else if (assetType == LLAssetType::AT_ANIMATION)      { -        assetType = LLAssetType::AT_ANIMATION;          filename = getFileName();      } -    else -    { -        // Unknown extension -        errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); -        errorLabel = "ErrorMessage"; -        error = TRUE;; -    }      if (error)      { @@ -744,7 +762,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti              result["success"] = LLSD::Boolean((ulstate == "complete") && status);          } -        S32 uploadPrice = result["upload_price"].asInteger();//uploadInfo->getEconomyUploadCost(); +        S32 uploadPrice = result["upload_price"].asInteger();          if (uploadPrice > 0)          { diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h index 4241c22c3e..d9eacf3167 100644 --- a/indra/newview/llviewerassetupload.h +++ b/indra/newview/llviewerassetupload.h @@ -62,7 +62,6 @@ public:      virtual LLSD        prepareUpload();      virtual LLSD        generatePostBody();      virtual void        logPreparedUpload(); -    virtual S32         getEconomyUploadCost();      virtual LLUUID      finishUpload(LLSD &result);      LLTransactionID     getTransactionId() const { return mTransactionId; } @@ -88,6 +87,9 @@ public:      LLUUID              getItemId() const { return mItemId; }      LLAssetID           getAssetId() const { return mAssetId; } +	static bool			findAssetTypeOfExtension(const std::string& exten, LLAssetType::EType& asset_type); +	static bool			findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload = true); +  protected:      LLResourceUploadInfo(          std::string name, diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 94ee425405..162acb74f1 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -45,6 +45,7 @@  // newview includes  #include "llagent.h"  #include "llagentaccess.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llagentui.h"  #include "llagentwearables.h" @@ -123,13 +124,13 @@  #include "lluilistener.h"  #include "llappearancemgr.h"  #include "lltrans.h" -#include "lleconomy.h"  #include "lltoolgrab.h"  #include "llwindow.h"  #include "llpathfindingmanager.h"  #include "llstartup.h"  #include "boost/unordered_map.hpp"  #include <boost/regex.hpp> +#include <boost/algorithm/string.hpp>  #include "llcleanup.h"  #include "llviewershadermgr.h" @@ -502,13 +503,13 @@ void init_menus()      gViewerWindow->setMenuBackgroundColor(false,           LLGridManager::getInstance()->isInProductionGrid()); -	// Assume L$10 for now, the server will tell us the real cost at login  	// *TODO:Also fix cost in llfolderview.cpp for Inventory menus -	const std::string upload_cost("10"); -	gMenuHolder->childSetLabelArg("Upload Image", "[COST]", upload_cost); -	gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost); -	gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost); -	gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost); +	const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()); +	const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); +	const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); +	gMenuHolder->childSetLabelArg("Upload Image", "[COST]", texture_upload_cost_str); +	gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str); +	gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);  	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);  	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); @@ -8703,18 +8704,31 @@ class LLUploadCostCalculator : public view_listener_t  	bool handleEvent(const LLSD& userdata)  	{ -		std::string menu_name = userdata.asString(); +		std::vector<std::string> fields; +		std::string str = userdata.asString();  +		boost::split(fields, str, boost::is_any_of(",")); +		if (fields.size()<1) +		{ +			return false; +		} +		std::string menu_name = fields[0]; +		std::string asset_type_str = "texture"; +		if (fields.size()>1) +		{ +			asset_type_str = fields[1]; +		} +		LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL; +		calculateCost(asset_type_str);  		gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr);  		return true;  	} -	void calculateCost(); +	void calculateCost(const std::string& asset_type_str);  public:  	LLUploadCostCalculator()  	{ -		calculateCost();  	}  }; @@ -8740,19 +8754,27 @@ class LLToggleUIHints : public view_listener_t  	}  }; -void LLUploadCostCalculator::calculateCost() +void LLUploadCostCalculator::calculateCost(const std::string& asset_type_str)  { -	S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); +	S32 upload_cost = -1; -	// getPriceUpload() returns -1 if no data available yet. -	if(upload_cost >= 0) +	if (asset_type_str == "texture")  	{ -		mCostStr = llformat("%d", upload_cost); +		upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();  	} -	else +	else if (asset_type_str == "animation") +	{ +		upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost(); +	} +	else if (asset_type_str == "sound") +	{ +		upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost(); +	} +	if (upload_cost < 0)  	{ -		mCostStr = llformat("%d", gSavedSettings.getU32("DefaultUploadCost")); +		LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL;  	} +	mCostStr = std::to_string(upload_cost);  }  void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y) diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 07873f482f..d1d3a7fc12 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -30,6 +30,7 @@  // project includes  #include "llagent.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llfilepicker.h"  #include "llfloaterreg.h" @@ -67,7 +68,6 @@  #include "llviewerassetupload.h"  // linden libraries -#include "lleconomy.h"  #include "llnotificationsutil.h"  #include "llsdserialize.h"  #include "llsdutil.h" @@ -85,8 +85,6 @@ class LLFileEnableUpload : public view_listener_t  	bool handleEvent(const LLSD& userdata)  	{          return true; -// 		bool new_value = gStatusBar && LLGlobalEconomy::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::getInstance()->getPriceUpload()); -// 		return new_value;  	}  }; @@ -406,22 +404,18 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP  	return;  } - -const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type) +void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification, const LLSD& response)  { -	// TODO: -	// Check user balance for entire cost -	// Charge user entire cost -	// Loop, uploading -	// If an upload fails, refund the user for that one -	// -	// Also fix single upload to charge first, then refund +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if (option != 0) +	{ +		// Cancel upload +		return; +	} -	S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();  	for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)  	{  		std::string filename = (*in_iter); -		if (!check_file_extension(filename, type)) continue;  		std::string name = gDirUtilp->getBaseFileName(filename, true);  		std::string asset_name = name; @@ -430,6 +424,13 @@ const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::  		LLStringUtil::stripNonprintable(asset_name);  		LLStringUtil::trim(asset_name); +		std::string ext = gDirUtilp->getExtension(filename); +		LLAssetType::EType asset_type; +		U32 codec; +		S32 expected_upload_cost; +		if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) && +			LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost)) +		{  		LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(  			filename,  			asset_name, @@ -443,6 +444,93 @@ const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::  		upload_new_resource(uploadInfo);  	}  } +} + +bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S32& total_cost, S32& file_count, S32& bvh_count) +{ +	total_cost = 0; +	file_count = 0; +	bvh_count = 0; +	for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) +	{ +		std::string filename = (*in_iter); +		std::string ext = gDirUtilp->getExtension(filename); + +		if (ext == "bvh") +		{ +			bvh_count++; +		} + +		LLAssetType::EType asset_type; +		U32 codec; +		S32 cost; + +		if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) && +			LLAgentBenefitsMgr::current().findUploadCost(asset_type, cost)) +		{ +			total_cost += cost; +			file_count++; +		} +	} +	 +    return file_count > 0; +} + +const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type) +{ +	// TODO: +	// Check user balance for entire cost +	// Charge user entire cost +	// Loop, uploading +	// If an upload fails, refund the user for that one +	// +	// Also fix single upload to charge first, then refund + +	// FIXME PREMIUM what about known types that can't be bulk uploaded +	// (bvh)? These will fail in the item by item upload but won't be +	// mentioned in the notification. +	std::vector<std::string> filtered_filenames; +	for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) +	{ +		const std::string& filename = *in_iter; +		if (check_file_extension(filename, type)) +		{ +			filtered_filenames.push_back(filename); +		} +	} + +	S32 expected_upload_cost; +	S32 expected_upload_count; +	S32 bvh_count; +	if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count)) +	{ +		LLSD args; +		args["COST"] = expected_upload_cost; +		args["COUNT"] = expected_upload_count; +		LLNotificationsUtil::add("BulkUploadCostConfirmation",  args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2)); + +		if (filtered_filenames.size() > expected_upload_count) +		{ +			if (bvh_count == filtered_filenames.size() - expected_upload_count) +			{ +				LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload"); +			} +			else +			{ +				LLNotificationsUtil::add("BulkUploadIncompatibleFiles"); +			} +		} +	} +	else if (bvh_count == filtered_filenames.size()) +	{ +		LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload"); +	} +	else +	{ +		LLNotificationsUtil::add("BulkUploadNoCompatibleFiles"); +	} + +}  class LLFileUploadImage : public view_listener_t  { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 318160dfc7..e077626461 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -32,7 +32,6 @@  #include "llaudioengine.h"   #include "llavataractions.h"  #include "llavatarnamecache.h"		// IDEVO HACK -#include "lleconomy.h"  #include "lleventtimer.h"  #include "llfloaterreg.h"  #include "llfolderview.h" @@ -51,6 +50,7 @@  #include "mean_collision_data.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llcallingcard.h"  #include "llbuycurrencyhtml.h" @@ -908,7 +908,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)  	if(option == 0 && !group_id.isNull())  	{  		// check for promotion or demotion. -		S32 max_groups = gMaxAgentGroups; +		S32 max_groups = LLAgentBenefitsMgr::current().getGroupMembershipLimit();  		if(gAgent.isInGroup(group_id)) ++max_groups;  		if(gAgent.mGroups.size() < max_groups) @@ -5444,16 +5444,7 @@ void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)  // do some extra stuff once we get our economy data  void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)  { -	LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::getInstance()); - -	S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); - -	LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL; - -	gMenuHolder->getChild<LLUICtrl>("Upload Image")->setLabelArg("[COST]", llformat("%d", upload_cost)); -	gMenuHolder->getChild<LLUICtrl>("Upload Sound")->setLabelArg("[COST]", llformat("%d", upload_cost)); -	gMenuHolder->getChild<LLUICtrl>("Upload Animation")->setLabelArg("[COST]", llformat("%d", upload_cost)); -	gMenuHolder->getChild<LLUICtrl>("Bulk Upload")->setLabelArg("[COST]", llformat("%d", upload_cost)); +	LL_DEBUGS("Benefits") << "Received economy data, not currently used" << LL_ENDL;  }  void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 9e5c58572a..e67826454b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -291,6 +291,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)          LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url                                               << " region name " << regionp->getName()                                              << " (attempt #" << mSeedCapAttempts + 1 << ")" << LL_ENDL; +		LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL;          regionp = NULL;          result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames); @@ -2974,6 +2975,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("UploadBakedTexture");      capabilityNames.append("UserInfo");  	capabilityNames.append("ViewerAsset");  +	capabilityNames.append("ViewerBenefits");  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d32881e737..7579eb1a90 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -38,6 +38,7 @@  #include "raytrace.h"  #include "llagent.h" //  Get state values from here +#include "llagentbenefits.h"  #include "llagentcamera.h"  #include "llagentwearables.h"  #include "llanimationstates.h" @@ -7063,20 +7064,7 @@ U32 LLVOAvatar::getNumAttachments() const  //-----------------------------------------------------------------------------  S32 LLVOAvatar::getMaxAttachments() const  { -	const S32 MAX_AGENT_ATTACHMENTS = 38; - -	S32 max_attach = MAX_AGENT_ATTACHMENTS; -	 -	if (gAgent.getRegion()) -	{ -		LLSD features; -		gAgent.getRegion()->getSimulatorFeatures(features); -		if (features.has("MaxAgentAttachments")) -		{ -			max_attach = features["MaxAgentAttachments"].asInteger(); -		} -	} -	return max_attach; +	return LLAgentBenefitsMgr::current().getAttachmentLimit();  }  //----------------------------------------------------------------------------- @@ -7110,24 +7098,7 @@ U32 LLVOAvatar::getNumAnimatedObjectAttachments() const  //-----------------------------------------------------------------------------  S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const  { -    S32 max_attach = 0; -    if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) -    { -        max_attach = getMaxAttachments();  -    } -    else -    { -        if (gAgent.getRegion()) -        { -            LLSD features; -            gAgent.getRegion()->getSimulatorFeatures(features); -            if (features.has("AnimatedObjects")) -            { -                max_attach = features["AnimatedObjects"]["MaxAgentAnimatedObjectAttachments"].asInteger(); -            } -        } -    } -    return max_attach; +	return LLAgentBenefitsMgr::current().getAnimatedObjectLimit();  }  //----------------------------------------------------------------------------- diff --git a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml index b5538a511c..c4ffba33fd 100644 --- a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater   legacy_header_height="18" - height="190" + height="180"   layout="topleft"   name="Anim Preview"   help_topic="animation_anim_preview" @@ -60,9 +60,9 @@       height="22"       label="Upload (L$[AMOUNT])"       layout="topleft" -     left="45" +     left="35"       name="ok_btn" -     top_pad="60" +     top_pad="15"       width="150" />      <button       follows="right|bottom" @@ -73,4 +73,17 @@       name="cancel_btn"       left_pad="5"       width="90" /> +    <text +     type="string" +     length="1" +     follows="left|top" +     height="35" +     layout="topleft" +     left="10" +     mouse_opaque="false" +     skip_link_underline="true" +     name="info_text" +     word_wrap="true" +     top_pad="10" +     width="270"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml index cb6b2f6ebc..0c62bfe304 100644 --- a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml @@ -2,7 +2,7 @@  <floater   legacy_header_height="18"   can_minimize="false" - height="610" + height="645"   layout="topleft"   name="Animation Preview"   help_topic="animation_preview" @@ -570,4 +570,17 @@ We recommend BVH files exported from Poser 4.       name="cancel_btn"       left="142"       width="128" /> +    <text +     type="string" +     length="1" +     follows="left|top" +     height="35" +     layout="topleft" +     left="10" +     mouse_opaque="false" +     skip_link_underline="true" +     name="info_text" +     word_wrap="true" +     top_pad="10" +     width="270"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml index 44d2c14cc8..3daff1a132 100644 --- a/indra/newview/skins/default/xui/en/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml @@ -2,7 +2,7 @@  <floater   legacy_header_height="18"   can_minimize="false" - height="460" + height="495"   layout="topleft"   name="Image Preview"   help_topic="image_preview" @@ -148,4 +148,17 @@ Try saving image as 24 bit Targa (.tga).       name="ok_btn"       top_delta="0"       width="125" /> +    <text +     type="string" +     length="1" +     follows="left|top" +     height="35" +     layout="topleft" +     left="10" +     mouse_opaque="false" +     skip_link_underline="true" +     name="info_text" +     word_wrap="true" +     top_pad="10" +     width="270"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml index 701233ba4a..0cc0ca1ce4 100644 --- a/indra/newview/skins/default/xui/en/floater_people.xml +++ b/indra/newview/skins/default/xui/en/floater_people.xml @@ -31,5 +31,11 @@          filename="panel_group_info_sidetray.xml"          label="Group Profile"          font="SansSerifBold"/> +      <panel +        class="panel_group_creation_sidetray" +        name="panel_group_creation_sidetray" +        filename="panel_group_creation_sidetray.xml" +        label="Create Group" +        font="SansSerifBold"/>      </panel_container>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_sound_preview.xml b/indra/newview/skins/default/xui/en/floater_sound_preview.xml index af791466b6..3889b975a9 100644 --- a/indra/newview/skins/default/xui/en/floater_sound_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_sound_preview.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater   legacy_header_height="18" - height="190" + height="180"   layout="topleft"   name="Sound Preview"   help_topic="sound_preview" @@ -60,9 +60,9 @@       height="22"       label="Upload (L$[AMOUNT])"       layout="topleft" -     left="45" +     left="35"       name="ok_btn" -     top_pad="60" +     top_pad="15"       width="150" />      <button       follows="right|bottom" @@ -73,4 +73,17 @@       name="cancel_btn"       left_pad="5"       width="90" /> +    <text +     type="string" +     length="1" +     follows="left|top" +     height="35" +     layout="topleft" +     left="10" +     mouse_opaque="false" +     skip_link_underline="true" +     name="info_text" +     word_wrap="true" +     top_pad="10" +     width="270"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml index 1b08767edc..99ca910062 100755 --- a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml @@ -42,7 +42,7 @@          parameter="take_off" />      </menu_item_call>      <menu_item_call -        label="Upload Photo (L$10)" +        label="Upload Photo (L$[UPLOAD_COST])"          layout="topleft"          name="upload_photo">          <on_click diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index 331e64984b..3385a29a6c 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -56,7 +56,7 @@                  function="File.VisibleUploadModel"/>                  </menu_item_call>                  <menu_item_call -                 label="Bulk (L$[COST] per file)..." +                 label="Bulk..."                   layout="topleft"                   name="Bulk Upload">                      <menu_item_call.on_click @@ -194,7 +194,7 @@                       function="Inventory.DoCreate"                       parameter="tattoo" />                  </menu_item_call> -                <menu_item_call +              <menu_item_call                   label="New Universal"                   layout="topleft"                   name="New Universal"> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index 61cb74f230..32d9d28434 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -40,7 +40,7 @@           parameter="take_off" />      </menu_item_call>      <menu_item_call -     label="Upload Photo (L$10)" +     label="Upload Photo (L$[UPLOAD_COST])"       layout="topleft"       name="upload_photo">          <on_click diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 59e098f07e..e228c5bdba 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1286,7 +1286,7 @@ function="World.EnvPreset"                   function="File.EnableUpload" />                  <menu_item_call.on_visible                   function="Upload.CalculateCosts" -                 parameter="Upload Image" /> +                 parameter="Upload Image,texture" />              </menu_item_call>              <menu_item_call               label="Sound (L$[COST])..." @@ -1299,7 +1299,7 @@ function="World.EnvPreset"                   function="File.EnableUpload" />                  <menu_item_call.on_visible                   function="Upload.CalculateCosts" -                 parameter="Upload Sound" /> +                 parameter="Upload Sound,sound" />              </menu_item_call>              <menu_item_call               label="Animation (L$[COST])..." @@ -1312,7 +1312,7 @@ function="World.EnvPreset"                   function="File.EnableUpload" />                  <menu_item_call.on_visible                   function="Upload.CalculateCosts" -                 parameter="Upload Animation" /> +                 parameter="Upload Animation,animation" />              </menu_item_call>              <menu_item_call             label="Model..." @@ -1327,9 +1327,12 @@ function="World.EnvPreset"              function="File.VisibleUploadModel"/>              </menu_item_call>  	   <menu_item_call -             label="Bulk (L$[COST] per file)..." +             label="Bulk..."               layout="topleft"               name="Bulk Upload"> +                <menu_item_call.on_visible +                 function="Upload.CalculateCosts" +                 parameter="Bulk Upload,texture" />                  <menu_item_call.on_click                   function="File.UploadBulk"                   parameter="" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a10152d81e..61a23851ed 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -686,6 +686,18 @@ Do you want to revoke modify rights for the selected Residents?    <notification     icon="alertmodal.tga" +   name="GroupNameLengthWarning" +   type="alertmodal"> +A group name must be between [MIN_LEN] and [MAX_LEN] characters. +    <tag>group</tag> +    <tag>fail</tag> +    <usetemplate +       name="okbutton" +       yestext="OK"/> +  </notification> +   +  <notification +   icon="alertmodal.tga"     name="UnableToCreateGroup"     type="alertmodal">  Unable to create group. @@ -920,7 +932,7 @@ You do not have enough L$ to join this group.     icon="alertmodal.tga"     name="CreateGroupCost"     type="alertmodal"> -Creating this group will cost L$100. +Creating this group will cost L$[COST].  Groups need more than one member, or they are deleted forever.  Please invite members within 48 hours.      <tag>group</tag> @@ -929,7 +941,7 @@ Please invite members within 48 hours.       canceltext="Cancel"       name="okcancelbuttons"       notext="Cancel" -     yestext="Create group for L$100"/> +     yestext="Create group for L$[COST]"/>    </notification>    <notification @@ -1291,6 +1303,14 @@ Error encoding snapshot.    <notification     icon="alertmodal.tga" +   name="ErrorCannotAffordUpload" +   type="alertmodal"> +    You need L$[COST] to upload this item. +    <tag>fail</tag> +  </notification> +   +  <notification +   icon="alertmodal.tga"     name="ErrorTextureCannotAfford"     type="alertmodal">      You need L$[COST] to save a texture to your inventory. You may either buy L$ or save the photo to your computer instead. @@ -4358,11 +4378,21 @@ You have reached your maximum number of groups. Please leave some group before j     icon="alert.tga"     name="GroupLimitInfo"     type="alert"> -The group limit for base accounts is [MAX_BASIC], and for [https://secondlife.com/premium/ premium] -accounts is [MAX_PREMIUM]. -If you downgraded your account, you will need to get below [MAX_BASIC] group limit before you can join more. +Residents with Basic memberships may join up to [MAX_BASIC] groups. +Premium memberships allow up to [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Learn more or upgrade] +    <tag>group</tag> +    <usetemplate +     name="okbutton" +     yestext="Close"/> +  </notification> -[https://secondlife.com/my/account/membership.php Upgrade today!] +  <notification +   icon="alert.tga" +   name="GroupLimitInfoPlus" +   type="alert"> +Residents with Basic memberships may join up to [MAX_BASIC] groups. +Premium memberships allow up to [MAX_PREMIUM]. Premium Plus +memberships allow up to [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Learn more or upgrade]      <tag>group</tag>      <usetemplate       name="okbutton" @@ -8550,9 +8580,50 @@ Your voice has been muted by moderator.           name="okbutton"           yestext="OK"/>      </notification> + +    <notification +        icon="alertmodal.tga" +        name="FailedToGetBenefits" +        type="alertmodal"> +      Unfortunately, we were unable to get benefits information for this session. This should not happen in a normal production environment. Please contact support. This session will not work normally and we recommend that you restart. +      <usetemplate +          name="okbutton" +          yestext="OK"/> +    </notification> + +   <notification +    icon="alertmodal.tga" +    name="BulkUploadCostConfirmation" +    type="alertmodal"> +This will upload [COUNT] items at a total cost of L$[COST]. Do you wish to continue with the upload? +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="Upload"/> +   </notification>     <notification      icon="alertmodal.tga" +    name="BulkUploadNoCompatibleFiles" +    type="alertmodal"> +Selected files can not be bulk-uploaded. +    <usetemplate +     name="okbutton" +     yestext="OK"/> +   </notification> + +  <notification +   icon="alertmodal.tga" +   name="BulkUploadIncompatibleFiles" +   type="alertmodal"> +Some of the selected files can not be bulk-uploaded. +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +   <notification +    icon="alertmodal.tga"      name="UploadCostConfirmation"      type="alertmodal">  This upload will cost L$[PRICE], do you wish to continue with the upload? diff --git a/indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml new file mode 100644 index 0000000000..c0265c2fa2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml @@ -0,0 +1,314 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +background_visible="true" + follows="all" + height="570" + label="Group Creation" + layout="topleft" + min_height="350" + left="0" + top="20" + name="GroupCreation" + width="313"> +  <panel.string +   name="current_membership"> +(your membership) +  </panel.string> +  <panel +    name="group_info_top" +    follows="top|left" +    top="0" +    left="0" +    height="29" +    width="313" +    layout="topleft"> +    <line_editor +     follows="left|top" +     font="SansSerif" +     label="Type your new group name here" +     layout="topleft" +     max_length_bytes="35" +     name="group_name_editor" +     left="12" +     top="5" +     width="270" +     height="20" +     visible="true" /> +  </panel> +  <layout_stack +    name="layout" +    orientation="vertical" +     follows="all" +    left="8" +    top_pad="0" +    height="538" +    width="300" +    border_size="0"> +    <layout_panel +        bg_alpha_color="DkGray2" +        bg_opaque_color="DkGray2" +        background_visible="true" +        background_opaque="true" +        name="group_info" +        follows="all" +        layout="topleft" +        auto_resize="false" +        user_resize="false" +        height="206" +        width="313"> +      <panel +         name="group_info_top" +         follows="top|left|right" +         top="0" +         left="0" +         height="99" +         width="312" +         layout="topleft"> +        <texture_picker +         default_image_name="Generic_Group_Large" +         follows="left|top" +         name="insignia" +         label="" +         no_commit_on_selection="true" +         tool_tip="Click to choose a picture" +         layout="topleft" +         height="110" +         left="5" +         top="5" +         width="100" /> +        <text_editor +         follows="left|top|right" +         layout="topleft" +         type="string" +         name="charter" +         left_pad="3" +         height="86" +         max_length="511" +         top="6" +         right="-4" +         bg_readonly_color="DkGray2" +         text_readonly_color="White" +         word_wrap="true"> +          Group Charter +        </text_editor> +      </panel> +      <panel +            layout="topleft" +            follows="left|top|right" +            background_visible="false" +            bevel_style="none" +            border="false" +            bg_alpha_color="FloaterUnfocusBorderColor" +            height="100" +            width="313" +            left="0" +            name="preferences_container" +            top_pad="5"> +        <check_box +         follows="right|top|left" +         layout="topleft" +         label="Anyone can join" +         height="16" +         left="10" +         name="open_enrollement" +         tool_tip="Sets whether this group allows new members to join without being invited." +         width="90" /> +        <check_box +         label="Cost to join" +         layout="topleft" +         name="check_enrollment_fee" +         tool_tip="Sets whether to require an enrollment fee to join the group" +         top_pad="5" +         left_delta="0" +         height="16" +         width="300" /> +        <spinner +         decimal_digits="0" +         follows="left|top" +         halign="left" +         increment="1" +         label_width="15" +         label="L$" +         layout="topleft" +         max_val="99999" +         height="23" +         left="30" +         name="spin_enrollment_fee" +         tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked." +         width="170" /> +        <combo_box +         follows="left|top" +         layout="topleft" +         name="group_mature_check" +         tool_tip="Maturity ratings designate the type of content and behavior allowed in a group" +         height="23" +         left="10" +         top_pad="4" +         width="190"> +          <combo_item name="select_mature" value="Select"> +            - Select maturity rating - +          </combo_item> +          <combo_box.item +           label="Moderate Content" +           name="mature" +           value="Mature" /> +          <combo_box.item +           label="General Content" +           name="pg" +           value="Not Mature" /> +        </combo_box> +      </panel> +    </layout_panel> +    <layout_panel +      background_visible="false" +      background_opaque="true" +      name="create_info" +      follows="all" +      layout="topleft" +      auto_resize="false" +      user_resize="false" +      height="200" +      width="313"> +      <text +        font="SansSerifSmall" +        follows="top|left|right" +        layout="topleft" +        mouse_opaque="false" +        type="string" +        name="fee_information" +        skip_link_underline="true" +        height="26" +        left="8" +        right="-8" +        top="5" +        word_wrap="true"> +        The fee to create a group is based on your membership level. [https://secondlife.com/my/account/membership.php More info] +      </text> +      <scroll_list +        draw_border="false" +        background_visible="false" +        follows="left|top|bottom|right" +        layout="topleft" +        multi_select="true" +        name="membership_list" +        row_padding="4" +        enabled="false" +        height="150" +        left="2" +        top_pad="8" +        width="290"> +        <scroll_list.columns +          dynamic_width="false" +          name="clmn_name" +          width="220"/> +        <scroll_list.columns +          dynamic_width="true" +          name="clmn_price"/> +        <scroll_list.rows +          name="basic" +          value="Basic (placeholder)"/> +        <scroll_list.rows +          name="plc2" +          value="" /> +        <scroll_list.rows +          name="premium" +          value="Premium (placeholder)" /> +      </scroll_list> +    </layout_panel> +    <layout_panel +      background_visible="false" +      background_opaque="true" +      name="create_actions" +      follows="all" +      layout="topleft" +      auto_resize="true" +      user_resize="true" +      height="200" +      width="313"> +    </layout_panel> +    <layout_panel +      background_visible="false" +      background_opaque="true" +      name="create_actions" +      follows="all" +      layout="topleft" +      auto_resize="false" +      user_resize="false" +      height="75" +      width="313"> + +      <layout_stack +        follows="bottom|left|right" +        layout="topleft" +        name="button_row_ls" +        left="1" +        right="-1" +        orientation="horizontal" +        height="25" +        top="1"> +        <layout_panel +          follows="bottom|left|right" +          layout="bottomleft" +          name="layout_crt" +          auto_resize="true" +          height="23" +          width="91"> +          <!-- placeholder to autoadjust buttons (since they are of different sizes)--> +        </layout_panel> +        <layout_panel +          follows="bottom|left|right" +          layout="bottomleft" +          name="layout_crt" +          auto_resize="false" +          height="23" +          width="245"> +          <button +            follows="bottom|left|right" +            layout="topleft" +            label="Create group for L$ [COST]" +            name="btn_create" +            visible="true" +            tool_tip="Create a new Group" +            height="23" +            left="1" +            top="0" +            width="160" /> +          <button +            follows="bottom|left|right" +            name="back" +            label="Cancel" +            layout="topleft" +            tool_tip="Return to list of groups" +            left_pad="13" +            height="23" +            top="0" +            width="70" /> +        </layout_panel> +        <layout_panel +          follows="bottom|left|right" +          layout="bottomleft" +          name="layout_crt" +          auto_resize="true" +          height="23" +          width="91"> +          <!-- placeholder to autoadjust buttons--> +        </layout_panel> +      </layout_stack> +      <text +        font="SansSerifSmall" +        follows="top|left|right" +        layout="topleft" +        mouse_opaque="false" +        type="string" +        height="26" +        left="6" +        right="-6" +        name="info_deletion" +        top_pad="8" +        word_wrap="true" +        halign="center"> +        Note: After 7 days, a group with no members (other than the creator) is deleted +      </text> +    </layout_panel> +  </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 95312edfb9..05de249d22 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -280,17 +280,6 @@ background_visible="true"  				     left="1"  				     top="0"  				     width="90" /> -					<button -    				 follows="bottom|left|right" -	                 height="23" -	                 layout="topleft" -	                 left="1" -	                 top="0" -	                 label="Create Group" -     				 name="btn_create" -               		 visible="true" -                 	 tool_tip="Create a new Group" -                 	 width="90" />	  				</layout_panel>  		   </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml index 800faabc2a..441cf97e87 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml @@ -41,7 +41,7 @@      <text       follows="top|left"       font="SansSerif" -     height="56" +     height="126"       layout="topleft"       left="10"       length="1" @@ -50,7 +50,9 @@       width="200"       type="string"       word_wrap="true"> -        Uploading an image to your inventory costs L$[UPLOAD_COST]. +Uploading an image to your inventory costs L$[UPLOAD_COST]. + +Fee is based on your subscription level. Higher levels are charged lower fees.      </text>      <button       follows="right|bottom" @@ -67,7 +69,7 @@      <button       follows="left|bottom"       height="23" -     label="UPLOAD L$10" +     label="UPLOAD L$[UPLOAD_COST]"       layout="topleft"       left="10"       name="save_btn" @@ -76,4 +78,4 @@        <button.commit_callback         function="Inventory.SaveOutfitPhoto" />      </button> -</panel>
\ No newline at end of file +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index a47121ae99..c4248d9b92 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -55,7 +55,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M  	 value="[REGION](Double-click to teleport, shift-drag to pan)"/>  	<string  	 name="GroupCountWithInfo" -	 value="You belong to [COUNT] groups, and can join [REMAINING] more.  [secondlife:/// Want more?]"/> +	 value="You belong to [COUNT] groups, and can join [REMAINING] more.  [secondlife:/// Raise your limit]"/>      <tab_container       bottom="-10"       follows="all" @@ -493,6 +493,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M                  top_pad="4"                  left="3"                  use_ellipses="true" +                skip_link_underline="true"                  name="groupcount">                You belong to [COUNT] groups, and can join [REMAINING] more.              </text> diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml index d019a0a310..8cc27d9eef 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml @@ -118,7 +118,7 @@       width="200"       type="string"       word_wrap="true"> -        Saving an image to your inventory costs L$[UPLOAD_COST]. To save your image as a texture select one of the square formats. +        To save your image as a texture select one of the square formats.      </text>      <button       follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml index 2fe4cf8183..8fc5cd7e63 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml @@ -73,4 +73,18 @@      <button.commit_callback       function="Snapshot.SaveToEmail" />    </button> +  <text +   follows="top|left" +   font="SansSerif" +   height="56" +   layout="topleft" +   left="10" +   length="1" +   name="fee_hint_lbl" +   top_pad="7" +   width="200" +   type="string" +   word_wrap="true"> +    Fee is based on your subscription level. Higher levels are charged lower fees. +  </text>  </panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 463147d80d..1bfac6aeb7 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2369,6 +2369,8 @@ If you continue to receive this message, please contact Second Life support for  	<string name="MarketplaceNoStock">out of stock</string>  	<string name="MarketplaceUpdating">updating...</string> +	<string name="UploadFeeInfo">Fee is based on your subscription level. Higher levels are charged lower fees. [https://secondlife.com/my/account/membership.php? Learn more]</string> +  	<string name="Open landmarks">Open landmarks</string>    <string name="Unconstrained">Unconstrained</string> @@ -3946,6 +3948,12 @@ Please check http://status.secondlifegrid.net to see if there is a known problem    <string name="Accounting">Accounting</string>    <string name="Notices">Notices</string>    <string name="Chat">Chat</string> +   +  <!-- SL Membership --> +  <string name="BaseMembership">Base</string> +  <string name="PremiumMembership">Premium</string> +  <string name="Premium PlusMembership">Premium Plus</string> +  <string name="InternalMembership">Internal</string> <!-- No need to translate -->    <!-- Question strings for delete items notifications -->    <string name="DeleteItems">Delete selected items?</string> diff --git a/indra/newview/skins/default/xui/it/menu_inventory_add.xml b/indra/newview/skins/default/xui/it/menu_inventory_add.xml index 83ba78294a..6f9212f56b 100644 --- a/indra/newview/skins/default/xui/it/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/it/menu_inventory_add.xml @@ -5,7 +5,7 @@  		<menu_item_call label="Suono ([COST]L$)..." name="Upload Sound"/>  		<menu_item_call label="Animazione ([COST]L$)..." name="Upload Animation"/>  		<menu_item_call label="Modella..." name="Upload Model"/> -		<menu_item_call label="In blocco ([COST]L$ per file)..." name="Bulk Upload"/> +		<menu_item_call label="In blocco..." name="Bulk Upload"/>  	</menu>  	<menu_item_call label="Nuova cartella" name="New Folder"/>  	<menu_item_call label="Nuovo script" name="New Script"/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index 2c7ecfa6e7..c7a10df910 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -153,7 +153,7 @@  			<menu_item_call label="Suono ([COST] L$)..." name="Upload Sound"/>  			<menu_item_call label="Animazione ([COST] L$)..." name="Upload Animation"/>  			<menu_item_call label="Modella..." name="Upload Model"/> -			<menu_item_call label="In blocco ([COST] L$ per file)..." name="Bulk Upload"/> +			<menu_item_call label="In blocco..." name="Bulk Upload"/>  		</menu>  		<menu_item_call label="Annulla" name="Undo"/>  		<menu_item_call label="Ripeti" name="Redo"/> diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index 5190723660..4d03e7c780 100644 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -156,7 +156,7 @@  			<menu_item_call label="Dźwięk ([COST]L$)..." name="Upload Sound" />  			<menu_item_call label="Animację ([COST]L$)..." name="Upload Animation" />  			<menu_item_call label="Model meszowy..." name="Upload Model" /> -			<menu_item_call label="Zbiór wielu plików ([COST]L$ per file)..." name="Bulk Upload" /> +			<menu_item_call label="Zbiór wielu plików..." name="Bulk Upload" />  		</menu>  		<menu_item_call label="Cofnij" name="Undo" />  		<menu_item_call label="Ponów" name="Redo" />	   diff --git a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml index d59b109aa8..0eaf3c7c5f 100644 --- a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml @@ -5,7 +5,7 @@  		<menu_item_call label="Som (L$[COST])..." name="Upload Sound"/>  		<menu_item_call label="Animação (L$[COST])..." name="Upload Animation"/>  		<menu_item_call label="Modelar..." name="Upload Model"/> -		<menu_item_call label="Volume (L$[COST] per file)..." name="Bulk Upload"/> +		<menu_item_call label="Volume..." name="Bulk Upload"/>  	</menu>  	<menu_item_call label="Nova pasta" name="New Folder"/>  	<menu_item_call label="Novo script" name="New Script"/> | 
