Merge branch 'master' into DRTVWR-486

master
Andrey Lihatskiy 2020-03-18 21:07:30 +02:00
commit e77134ea89
72 changed files with 1570 additions and 865 deletions

View File

@ -1,3 +1,4 @@

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -137,6 +137,7 @@ LLScrollListCtrl::Params::Params()
background_visible("background_visible"),
draw_stripes("draw_stripes"),
column_padding("column_padding"),
row_padding("row_padding", 2),
fg_unselected_color("fg_unselected_color"),
fg_selected_color("fg_selected_color"),
bg_selected_color("bg_selected_color"),
@ -199,6 +200,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mHoveredColor(p.hovered_color()),
mSearchColumn(p.search_column),
mColumnPadding(p.column_padding),
mRowPadding(p.row_padding),
mContextMenuType(MENU_NONE),
mIsFriendSignal(NULL)
{
@ -685,8 +687,6 @@ bool LLScrollListCtrl::updateColumnWidths()
return width_changed;
}
const S32 SCROLL_LIST_ROW_PAD = 2;
// Line height is the max height of all the cells in all the items.
void LLScrollListCtrl::updateLineHeight()
{
@ -699,7 +699,7 @@ void LLScrollListCtrl::updateLineHeight()
S32 i = 0;
for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
{
mLineHeight = llmax( mLineHeight, cell->getHeight() + SCROLL_LIST_ROW_PAD );
mLineHeight = llmax( mLineHeight, cell->getHeight() + mRowPadding );
}
}
}
@ -711,7 +711,7 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp)
S32 i = 0;
for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
{
mLineHeight = llmax( mLineHeight, cell->getHeight() + SCROLL_LIST_ROW_PAD );
mLineHeight = llmax( mLineHeight, cell->getHeight() + mRowPadding );
}
}

View File

@ -108,7 +108,8 @@ public:
// layout
Optional<S32> column_padding,
page_lines,
row_padding,
page_lines,
heading_height;
// sort and search behavior
@ -283,8 +284,10 @@ public:
void setBackgroundVisible(BOOL b) { mBackgroundVisible = b; }
void setDrawStripes(BOOL b) { mDrawStripes = b; }
void setColumnPadding(const S32 c) { mColumnPadding = c; }
S32 getColumnPadding() { return mColumnPadding; }
void setColumnPadding(const S32 c) { mColumnPadding = c; }
S32 getColumnPadding() const { return mColumnPadding; }
void setRowPadding(const S32 c) { mColumnPadding = c; }
S32 getRowPadding() const { return mColumnPadding; }
void setCommitOnKeyboardMovement(BOOL b) { mCommitOnKeyboardMovement = b; }
void setCommitOnSelectionChange(BOOL b) { mCommitOnSelectionChange = b; }
void setAllowKeyboardMovement(BOOL b) { mAllowKeyboardMovement = b; }
@ -469,6 +472,7 @@ private:
LLRect mItemListRect;
S32 mColumnPadding;
S32 mRowPadding;
BOOL mBackgroundVisible;
BOOL mDrawStripes;

View File

@ -152,6 +152,7 @@ LLTextBase::Params::Params()
plain_text("plain_text",false),
track_end("track_end", false),
read_only("read_only", false),
skip_link_underline("skip_link_underline", false),
spellcheck("spellcheck", false),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
@ -183,6 +184,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mFontShadow(p.font_shadow),
mPopupMenuHandle(),
mReadOnly(p.read_only),
mSkipLinkUnderline(p.skip_link_underline),
mSpellCheck(p.spellcheck),
mSpellCheckStart(-1),
mSpellCheckEnd(-1),
@ -2289,7 +2291,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 cur_length = getLength();
LLStyleConstSP sp(new LLStyle(highlight_params));
LLTextSegmentPtr segmentp;
if(underline_on_hover_only)
if (underline_on_hover_only || mSkipLinkUnderline)
{
highlight_params.font.style("NORMAL");
LLStyleConstSP normal_sp(new LLStyle(highlight_params));
@ -2313,7 +2315,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 segment_start = old_length;
S32 segment_end = old_length + wide_text.size();
LLStyleConstSP sp(new LLStyle(style_params));
if (underline_on_hover_only)
if (underline_on_hover_only || mSkipLinkUnderline)
{
LLStyle::Params normal_style_params(style_params);
normal_style_params.font.style("NORMAL");
@ -3489,7 +3491,7 @@ F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start
/*virtual*/
BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask)
{
mStyle = mHoveredStyle;
mStyle = mEditor.getSkipLinkUnderline() ? mNormalStyle : mHoveredStyle;
return LLNormalTextSegment::handleHover(x, y, mask);
}

View File

@ -310,6 +310,7 @@ public:
border_visible,
track_end,
read_only,
skip_link_underline,
spellcheck,
allow_scroll,
plain_text,
@ -451,6 +452,9 @@ public:
void setReadOnly(bool read_only) { mReadOnly = read_only; }
bool getReadOnly() { return mReadOnly; }
void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; }
bool getSkipLinkUnderline() { return mSkipLinkUnderline; }
void setPlainText(bool value) { mPlainText = value;}
bool getPlainText() const { return mPlainText; }
@ -694,6 +698,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipLinkUnderline;
// support widgets
LLHandle<LLContextMenu> mPopupMenuHandle;
LLView* mDocumentView;

View File

@ -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

View File

@ -1 +1 @@
6.3.8
6.3.9

View File

@ -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()

View File

@ -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;
}

View File

@ -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

View File

@ -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
{

View File

@ -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)

View File

@ -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;
//-----------------------------------------------------------------------------

View File

@ -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"

View File

@ -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);

View File

@ -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();

View File

@ -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*/

View File

@ -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

View File

@ -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");

View File

@ -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"

View File

@ -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;

View File

@ -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
{

View File

@ -30,7 +30,6 @@
#include "llpanelcontents.h"
// linden library includes
#include "lleconomy.h"
#include "llerror.h"
#include "llfloaterreg.h"
#include "llfontgl.h"

View File

@ -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,

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
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());
// 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"));
}
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);
}
}

View File

@ -30,7 +30,6 @@
#include "llpanelobject.h"
// linden library includes
#include "lleconomy.h"
#include "llerror.h"
#include "llfontgl.h"
#include "material_codes.h" // LL_MCODE_MASK

View File

@ -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())
{
LLSD features;
gAgent.getRegion()->getSimulatorFeatures(features);
if (features.has("MaxAgentGroupsBasic"))
{
max_basic = features["MaxAgentGroupsBasic"].asInteger();
}
if (features.has("MaxAgentGroupsPremium"))
{
max_premium = features["MaxAgentGroupsPremium"].asInteger();
}
}
args["MAX_BASIC"] = max_basic;
args["MAX_PREMIUM"] = max_premium;
S32 max_basic = LLAgentBenefitsMgr::get("Base").getGroupMembershipLimit();
S32 max_premium = LLAgentBenefitsMgr::get("Premium").getGroupMembershipLimit();
args["MAX_BASIC"] = max_basic;
args["MAX_PREMIUM"] = max_premium;
LLNotificationsUtil::add("GroupLimitInfo", args);
if (LLAgentBenefitsMgr::has("Premium Plus"))
{
S32 max_premium_plus = LLAgentBenefitsMgr::get("Premium Plus").getGroupMembershipLimit();
args["MAX_PREMIUM_PLUS"] = max_premium_plus;
LLNotificationsUtil::add("GroupLimitInfoPlus", args);
}
else
{
LLNotificationsUtil::add("GroupLimitInfo", args);
}
}
void LLPanelPeople::onTabSelected(const LLSD& param)

View File

@ -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())
{

View File

@ -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);
}

View File

@ -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));
}

View File

@ -31,7 +31,6 @@
// linden library includes
#include "llclickaction.h"
#include "lleconomy.h"
#include "llerror.h"
#include "llfontgl.h"
#include "llflexibleobject.h"

View File

@ -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"

View File

@ -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;

View File

@ -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.

View File

@ -80,7 +80,6 @@ typedef enum {
// exported symbols
extern bool gAgentMovementCompleted;
extern S32 gMaxAgentGroups;
extern LLPointer<LLViewerTexture> gStartTexture;
class LLStartUp

View File

@ -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();

View File

@ -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)
{

View File

@ -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,

View File

@ -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")
{
mCostStr = llformat("%d", gSavedSettings.getU32("DefaultUploadCost"));
upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
}
else if (asset_type_str == "sound")
{
upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost();
}
if (upload_cost < 0)
{
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)

View File

@ -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);
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);
const std::string& filename = *in_iter;
if (check_file_extension(filename, type))
{
filtered_filenames.push_back(filename);
}
}
S32 expected_upload_cost;
S32 expected_upload_count;
S32 bvh_count;
if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count))
{
LLSD args;
args["COST"] = expected_upload_cost;
args["COUNT"] = expected_upload_count;
LLNotificationsUtil::add("BulkUploadCostConfirmation", args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2));
if (filtered_filenames.size() > expected_upload_count)
{
if (bvh_count == filtered_filenames.size() - expected_upload_count)
{
LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
}
else
{
LLNotificationsUtil::add("BulkUploadIncompatibleFiles");
}
}
}
else if (bvh_count == filtered_filenames.size())
{
LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
}
else
{
LLNotificationsUtil::add("BulkUploadNoCompatibleFiles");
}
}
class LLFileUploadImage : public view_listener_t

View File

@ -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)

View File

@ -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");

View File

@ -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();
}
//-----------------------------------------------------------------------------

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>
</menu>

View File

@ -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

View File

@ -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="" />

View File

@ -684,6 +684,18 @@ Do you want to revoke modify rights for the selected Residents?
yestext="Yes"/>
</notification>
<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"
@ -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
@ -1289,6 +1301,14 @@ Error encoding snapshot.
<tag>fail</tag>
</notification>
<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"
@ -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,7 +8550,48 @@ 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"

View File

@ -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>

View File

@ -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>

View File

@ -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>
</panel>

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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" />

View File

@ -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"/>