diff options
72 files changed, 1567 insertions, 862 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 68dd00d880..32a83a88d9 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 @@ -37,7 +36,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 352a00645f..367c6c3c5b 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -138,6 +138,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"), @@ -200,6 +201,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) { @@ -686,8 +688,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() { @@ -700,7 +700,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 ); } } } @@ -712,7 +712,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 79fe185f11..8d00296183 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -109,7 +109,8 @@ public: // layout Optional<S32> column_padding, - page_lines, + row_padding, + page_lines, heading_height; // sort and search behavior @@ -284,8 +285,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; } @@ -470,6 +473,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 ee749ae923..e6b3765370 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), @@ -2301,7 +2303,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)); @@ -2325,7 +2327,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"); @@ -3501,7 +3503,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 f8603ad67a..4e966b7cef 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, @@ -453,6 +454,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; } @@ -696,6 +700,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 cf8f99ed25..800696825f 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 @@ -438,6 +439,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 @@ -1054,6 +1057,7 @@ set(viewer_HEADER_FILES llpanelface.h llpanelgenerictip.h llpanelgroup.h + llpanelgroupcreate.h llpanelgroupbulk.h llpanelgroupbulkimpl.h llpanelgroupbulkban.h diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index a7ee22c2e2..291cd91eb1 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.3.8 +6.3.9 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 31b8b90518..1545be3457 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" @@ -2984,7 +2985,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 10db8ac3bc..e694340b16 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 c9a689281e..87a741bb7b 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; @@ -63,7 +64,7 @@ const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; //----------------------------------------------------------------------------- LLFloaterNameDesc::LLFloaterNameDesc(const LLSD& filename ) : LLFloater(filename), - mIsAudio(FALSE) + mIsAudio(FALSE) { mFilenameAndPath = filename.asString(); mFilename = gDirUtilp->getBaseFileName(mFilenameAndPath, false); @@ -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 = NULL; - 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 b2b6de94b3..53416036c9 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 f63e604927..be31a2ed5d 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" @@ -227,16 +227,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 @@ -1504,36 +1504,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 58bc049338..6ad6a172b1 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 684d3bd421..be6e9e520a 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) @@ -1581,8 +1581,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(); @@ -2168,6 +2166,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) @@ -3284,10 +3287,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()) { @@ -3630,27 +3693,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 f882fd31ee..af6b37f2df 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 97fbb8c601..51c8f4ab79 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) { @@ -740,7 +758,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti return; } - 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 ee1806b782..08b03e3059 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 f859ced342..110e109a28 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" @@ -127,13 +128,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" using namespace LLAvatarAppearanceDefines; @@ -505,13 +506,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); @@ -8662,18 +8663,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(); } }; @@ -8699,19 +8713,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 a9a91b158b..741ce7a182 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,6 +404,77 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP return; } +void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // Cancel upload + return; + } + + for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) + { + std::string filename = (*in_iter); + + std::string name = gDirUtilp->getBaseFileName(filename, true); + std::string asset_name = name; + LLStringUtil::replaceNonstandardASCII(asset_name, '?'); + LLStringUtil::replaceChar(asset_name, '|', '?'); + 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, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost)); + + upload_new_resource(uploadInfo, NULL, NULL); + } + } +} + +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) { @@ -417,31 +486,50 @@ const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker:: // // Also fix single upload to charge first, then refund - S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); + // 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) { - std::string filename = (*in_iter); - if (!check_file_extension(filename, type)) continue; - - std::string name = gDirUtilp->getBaseFileName(filename, true); - std::string asset_name = name; - LLStringUtil::replaceNonstandardASCII(asset_name, '?'); - LLStringUtil::replaceChar(asset_name, '|', '?'); - LLStringUtil::stripNonprintable(asset_name); - LLStringUtil::trim(asset_name); + const std::string& filename = *in_iter; + if (check_file_extension(filename, type)) + { + filtered_filenames.push_back(filename); + } + } - LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( - filename, - asset_name, - asset_name, 0, - LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); + 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)); - upload_new_resource(uploadInfo, NULL, NULL); + 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 3dd2f402fe..f4603463e2 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) @@ -5445,16 +5445,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 75e707aaa3..654a028ec4 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -290,6 +290,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); @@ -2969,6 +2970,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 71ff441600..b524db478e 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 29724b0270..05dd8f827d 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 @@ -253,4 +253,4 @@ parameter="eyes" /> </menu_item_call> </menu> -</menu>
\ No newline at end of file +</menu> 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 04b5d808ec..2c9bf99fe2 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1296,7 +1296,7 @@ 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])..." @@ -1309,7 +1309,7 @@ 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])..." @@ -1322,7 +1322,7 @@ 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..." @@ -1337,9 +1337,12 @@ 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 e3776cdc1a..57183ac3a6 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" @@ -8520,9 +8550,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 e1aff135a5..41ec0f8cfb 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2351,6 +2351,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> @@ -3914,6 +3916,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 62da61cd6b..e31f0ebb69 100644 --- a/indra/newview/skins/default/xui/it/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/it/menu_inventory_add.xml @@ -6,7 +6,7 @@ <menu_item_call label="Animazione ([COST]L$)..." name="Upload Animation"/> <menu_item_call label="Modella..." name="Upload Model"/> <menu_item_call label="Procedura guidata modellazione..." name="Upload Model Wizard"/> - <menu_item_call label="In blocco ([COST]L$ per file)..." name="Bulk Upload"/> + <menu_item_call label="In blocco..." name="Bulk Upload"/> <menu_item_call label="Definisci diritti di caricamento predefiniti" name="perm prefs"/> </menu> <menu_item_call label="Nuova cartella" name="New Folder"/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index ae82a89d28..795a23ca9b 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -168,7 +168,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 e6ad1faee6..2dfafff7f5 100644 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -159,7 +159,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 7a7ebc50af..92621e8493 100644 --- a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml @@ -6,7 +6,7 @@ <menu_item_call label="Animação (L$[COST])..." name="Upload Animation"/> <menu_item_call label="Modelar..." name="Upload Model"/> <menu_item_call label="Assistente de modelagem..." name="Upload Model Wizard"/> - <menu_item_call label="Volume (L$[COST] per file)..." name="Bulk Upload"/> + <menu_item_call label="Volume..." name="Bulk Upload"/> <menu_item_call label="Autorizações de upload padrão" name="perm prefs"/> </menu> <menu_item_call label="Nova pasta" name="New Folder"/> |