A Massive Experience Tools (and Unstable Branch) Merge
[XP Tools] Initial merge Cherry Pick Also modernize llfloaterauction internally, but leave the ui the same for now. Breaks out script_question_mute() in llviewermessage.cpp to better sync with upstream Adds support for UnknownScriptQuestion notification (translators need to translate this one~) RLVa note: Rewrote RLVa permissions handling block just a bit. Added 13 new capabilities from the XP Tools, I doubt all of them really exist. Minor update to LLComboBox, decided against implementing LLIconsComboBox for now. Modified LLExperienceLog::notify to lookup names and display them along with the slurls since our editors don't do that automatically. Experience tweak: Changed a few notify's to notifytips so that we can click the links to experience profiles from chat instead of via hacked in buttons Migrated LLFloaterCompileQueue to a proper Instance Tracker so we can call getKey Modernized LLSD, gives us reverse iterators and the new debugging impl. We needed the reverse iterators. Experience tweak: Added virtual destructors to responders. Updated llhandle.h to allow calling getDerivedHandle in public. Updated LLScrollContainer and LLScrollBar to be more modern. Added LLFlatListView/flat_list_view from upstream - these don't seem work though? Added some newer login/logout strings to strings.xml Thanks for the default timeout policies, Aleric~ To avoid needing to scroll through tabs, about land tabs now are as big as they need to be to display their labels, same on groups Group Members and Roles has been renamed to just Members because this allows the new Experiences tab enough room to display. Thanks to Henri Beauchamp (Cool VL Viewer) for the setupList augmentation. (without it, I'd still be stuck) Thanks to Shyotl for the helpsies~ Added the LSL constants, events, and functions that LL neglected to put in. Added click callbacks and name lookups for profile linky texts~ Merge is up to 22b4cdc Old TODO: Get the uis looking nice (profiles? Experiences... floater) - done Old TODO: Make sure flatlistviews look okay... - Not using Old TODO: Fix LLFloaterExperiencePicker, right now the panel does not show. - unsure Old TODO: Remove the llfloaterabout.cpp change. - done Merges llexperiencecache with upstream and unstable Introduces LLCoroResponder, TODO: Make everything use this. Updates Reporter floater to the latest, supports the new cap thingy Also adds these commits/changes: [XPTools] Double clicking experiences in namelists should open the profile Add List.CopyNames support for Experiences [XP Tools] Some UI work, I'll do more later [XPTools] More UI Stuff, Later is now! Allow getSLURL for experiences WIP Experience list menu Also make EXPERIENCE > OBJECT, because mainline started OBJECT already [XPTools] Add Experience support to Name UI [XPTools] Fix experience profile UI 9c3067e843265587e91c659200a8d783acf2d9b2 [XPTools] Fix experience location showing "last" and getting set to "last" [XPTools] Move Experiences floater from view menu to world menu [XPTools] Fix up more UI [XPTools] Fix experiences panels [XPTools] Hide pieces of the Experiences menu when they're not usable [XPTools] More UI work, mostly to get the menus working [XPTools] The events list is for events, not experiences, remove menu # Conflicts: # indra/llcommon/llsd.cpp - merge with unstable branch # indra/llmessage/message_prehash.cpp # indra/llmessage/message_prehash.h # indra/llui/llscrollbar.cpp # indra/llui/llscrollcontainer.cpp # indra/llui/llurlentry.cpp # indra/llui/llurlregistry.cpp # indra/newview/app_settings/keywords.ini # indra/newview/app_settings/settings.xml # indra/newview/llappviewer.cpp # indra/newview/llappviewer.h # indra/newview/llassetuploadresponders.cpp # indra/newview/llcompilequeue.* - merge stable # indra/newview/llfloaterabout.cpp # indra/newview/llfloaterland.* - merge unstable # indra/newview/llfloaterproperties.cpp # indra/newview/llfloaterregioninfo.* - merge unstable # indra/newview/llmenucommands.cpp - merge unstable # indra/newview/llpreviewscript.cpp - merge unstable # indra/newview/llviewermessage.cpp - merge unstable # indra/newview/llviewerregion.cpp - merge unstable # indra/newview/skins/default/textures/textures.xml - merge unstable # indra/newview/skins/default/xui/en-us/strings.xml - merge unstable
This commit is contained in:
committed by
Liru Færs
parent
9a53824d6d
commit
36b75b2398
@@ -126,9 +126,9 @@ public:
|
||||
virtual Date asDate() const { return LLDate(); }
|
||||
virtual URI asURI() const { return LLURI(); }
|
||||
virtual const Binary& asBinary() const { static const std::vector<U8> empty; return empty; }
|
||||
|
||||
virtual const String& asStringRef() const { static const std::string empty; return empty; }
|
||||
|
||||
virtual const String& asStringRef() const { static const std::string empty; return empty; }
|
||||
|
||||
virtual bool has(const String&) const { return false; }
|
||||
virtual LLSD get(const String&) const { return LLSD(); }
|
||||
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
|
||||
@@ -183,10 +183,11 @@ namespace
|
||||
public:
|
||||
ImplBase(DataRef value) : mValue(value) { }
|
||||
|
||||
virtual LLSD::Type type() const { return T; }
|
||||
LLSD::Type type() const override { return T; }
|
||||
|
||||
using LLSD::Impl::assign; // Unhiding base class virtuals...
|
||||
virtual void assign(LLSD::Impl*& var, DataRef value) {
|
||||
void assign(LLSD::Impl*& var, DataRef value) override
|
||||
{
|
||||
if (shared())
|
||||
{
|
||||
Impl::assign(var, value);
|
||||
@@ -205,10 +206,10 @@ namespace
|
||||
public:
|
||||
ImplBoolean(LLSD::Boolean v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return mValue; }
|
||||
virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; }
|
||||
virtual LLSD::Real asReal() const { return mValue ? 1 : 0; }
|
||||
virtual LLSD::String asString() const;
|
||||
LLSD::Boolean asBoolean() const override { return mValue; }
|
||||
LLSD::Integer asInteger() const override { return mValue ? 1 : 0; }
|
||||
LLSD::Real asReal() const override { return mValue ? 1 : 0; }
|
||||
LLSD::String asString() const override;
|
||||
};
|
||||
|
||||
LLSD::String ImplBoolean::asString() const
|
||||
@@ -226,10 +227,10 @@ namespace
|
||||
public:
|
||||
ImplInteger(LLSD::Integer v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return mValue != 0; }
|
||||
virtual LLSD::Integer asInteger() const { return mValue; }
|
||||
virtual LLSD::Real asReal() const { return mValue; }
|
||||
virtual LLSD::String asString() const;
|
||||
LLSD::Boolean asBoolean() const override { return mValue != 0; }
|
||||
LLSD::Integer asInteger() const override { return mValue; }
|
||||
LLSD::Real asReal() const override { return mValue; }
|
||||
LLSD::String asString() const override;
|
||||
};
|
||||
|
||||
LLSD::String ImplInteger::asString() const
|
||||
@@ -242,10 +243,10 @@ namespace
|
||||
public:
|
||||
ImplReal(LLSD::Real v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const;
|
||||
virtual LLSD::Integer asInteger() const;
|
||||
virtual LLSD::Real asReal() const { return mValue; }
|
||||
virtual LLSD::String asString() const;
|
||||
LLSD::Boolean asBoolean() const override;
|
||||
LLSD::Integer asInteger() const override;
|
||||
LLSD::Real asReal() const override { return mValue; }
|
||||
LLSD::String asString() const override;
|
||||
};
|
||||
|
||||
LLSD::Boolean ImplReal::asBoolean() const
|
||||
@@ -264,15 +265,15 @@ namespace
|
||||
public:
|
||||
ImplString(const LLSD::String& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); }
|
||||
virtual LLSD::Integer asInteger() const;
|
||||
virtual LLSD::Real asReal() const;
|
||||
virtual LLSD::String asString() const { return mValue; }
|
||||
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); }
|
||||
virtual LLSD::Date asDate() const { return LLDate(mValue); }
|
||||
virtual LLSD::URI asURI() const { return LLURI(mValue); }
|
||||
virtual int size() const { return mValue.size(); }
|
||||
virtual const LLSD::String& asStringRef() const { return mValue; }
|
||||
LLSD::Boolean asBoolean() const override { return !mValue.empty(); }
|
||||
LLSD::Integer asInteger() const override;
|
||||
LLSD::Real asReal() const override;
|
||||
LLSD::String asString() const override { return mValue; }
|
||||
LLSD::UUID asUUID() const override { return LLUUID(mValue); }
|
||||
LLSD::Date asDate() const override { return LLDate(mValue); }
|
||||
LLSD::URI asURI() const override { return LLURI(mValue); }
|
||||
int size() const override { return mValue.size(); }
|
||||
const LLSD::String& asStringRef() const override { return mValue; }
|
||||
};
|
||||
|
||||
LLSD::Integer ImplString::asInteger() const
|
||||
@@ -308,8 +309,8 @@ namespace
|
||||
public:
|
||||
ImplUUID(const LLSD::UUID& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::String asString() const{ return mValue.asString(); }
|
||||
virtual LLSD::UUID asUUID() const { return mValue; }
|
||||
LLSD::String asString() const override { return mValue.asString(); }
|
||||
LLSD::UUID asUUID() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -321,16 +322,17 @@ namespace
|
||||
: ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v)
|
||||
{ }
|
||||
|
||||
virtual LLSD::Integer asInteger() const
|
||||
LLSD::Integer asInteger() const override
|
||||
{
|
||||
return (LLSD::Integer)(mValue.secondsSinceEpoch());
|
||||
}
|
||||
virtual LLSD::Real asReal() const
|
||||
LLSD::Real asReal() const override
|
||||
{
|
||||
return mValue.secondsSinceEpoch();
|
||||
}
|
||||
virtual LLSD::String asString() const{ return mValue.asString(); }
|
||||
virtual LLSD::Date asDate() const { return mValue; }
|
||||
|
||||
LLSD::String asString() const override { return mValue.asString(); }
|
||||
LLSD::Date asDate() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -340,8 +342,8 @@ namespace
|
||||
public:
|
||||
ImplURI(const LLSD::URI& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::String asString() const{ return mValue.asString(); }
|
||||
virtual LLSD::URI asURI() const { return mValue; }
|
||||
LLSD::String asString() const override { return mValue.asString(); }
|
||||
LLSD::URI asURI() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -351,7 +353,7 @@ namespace
|
||||
public:
|
||||
ImplBinary(const LLSD::Binary& v) : Base(v) { }
|
||||
|
||||
virtual const LLSD::Binary& asBinary() const{ return mValue; }
|
||||
const LLSD::Binary& asBinary() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -368,33 +370,33 @@ namespace
|
||||
public:
|
||||
ImplMap() { }
|
||||
|
||||
virtual ImplMap& makeMap(LLSD::Impl*&);
|
||||
ImplMap& makeMap(LLSD::Impl*&) override;
|
||||
|
||||
virtual LLSD::Type type() const { return LLSD::TypeMap; }
|
||||
LLSD::Type type() const override { return LLSD::TypeMap; }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
|
||||
LLSD::Boolean asBoolean() const override { return !mData.empty(); }
|
||||
|
||||
virtual bool has(const LLSD::String&) const;
|
||||
bool has(const LLSD::String&) const override;
|
||||
|
||||
using LLSD::Impl::get; // Unhiding get(LLSD::Integer)
|
||||
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
|
||||
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
|
||||
virtual LLSD get(const LLSD::String&) const;
|
||||
virtual LLSD getKeys() const;
|
||||
LLSD get(const LLSD::String&) const override;
|
||||
LLSD getKeys() const override;
|
||||
void insert(const LLSD::String& k, const LLSD& v);
|
||||
virtual void erase(const LLSD::String&);
|
||||
void erase(const LLSD::String&) override;
|
||||
LLSD& ref(const LLSD::String&);
|
||||
virtual const LLSD& ref(const LLSD::String&) const;
|
||||
const LLSD& ref(const LLSD::String&) const override;
|
||||
|
||||
virtual int size() const { return mData.size(); }
|
||||
int size() const override { return mData.size(); }
|
||||
|
||||
LLSD::map_iterator beginMap() { return mData.begin(); }
|
||||
LLSD::map_iterator endMap() { return mData.end(); }
|
||||
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
|
||||
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
|
||||
LLSD::map_const_iterator beginMap() const override { return mData.begin(); }
|
||||
LLSD::map_const_iterator endMap() const override { return mData.end(); }
|
||||
|
||||
virtual void dumpStats() const;
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
void dumpStats() const override;
|
||||
void calcStats(S32 type_counts[], S32 share_counts[]) const override;
|
||||
};
|
||||
|
||||
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
|
||||
@@ -481,7 +483,7 @@ namespace
|
||||
{
|
||||
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
|
||||
Impl::calcStats((*iter).second, type_counts, share_counts);
|
||||
iter++;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// Add in the values for this map
|
||||
@@ -502,32 +504,32 @@ namespace
|
||||
public:
|
||||
ImplArray() { }
|
||||
|
||||
virtual ImplArray& makeArray(Impl*&);
|
||||
ImplArray& makeArray(Impl*&) override;
|
||||
|
||||
virtual LLSD::Type type() const { return LLSD::TypeArray; }
|
||||
LLSD::Type type() const override { return LLSD::TypeArray; }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
|
||||
LLSD::Boolean asBoolean() const override { return !mData.empty(); }
|
||||
|
||||
using LLSD::Impl::get; // Unhiding get(LLSD::String)
|
||||
using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
|
||||
using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
|
||||
virtual int size() const;
|
||||
virtual LLSD get(LLSD::Integer) const;
|
||||
int size() const override;
|
||||
LLSD get(LLSD::Integer) const override;
|
||||
void set(LLSD::Integer, const LLSD&);
|
||||
void insert(LLSD::Integer, const LLSD&);
|
||||
LLSD& append(const LLSD&);
|
||||
virtual void erase(LLSD::Integer);
|
||||
void erase(LLSD::Integer) override;
|
||||
LLSD& ref(LLSD::Integer);
|
||||
virtual const LLSD& ref(LLSD::Integer) const;
|
||||
const LLSD& ref(LLSD::Integer) const override;
|
||||
|
||||
LLSD::array_iterator beginArray() { return mData.begin(); }
|
||||
LLSD::array_iterator endArray() { return mData.end(); }
|
||||
LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
|
||||
LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
|
||||
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
|
||||
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
|
||||
LLSD::array_const_iterator beginArray() const override { return mData.begin(); }
|
||||
LLSD::array_const_iterator endArray() const override { return mData.end(); }
|
||||
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
void calcStats(S32 type_counts[], S32 share_counts[]) const override;
|
||||
};
|
||||
|
||||
ImplArray& ImplArray::makeArray(Impl*& var)
|
||||
@@ -631,7 +633,7 @@ namespace
|
||||
while (iter != endArray())
|
||||
{ // Add values for all items held in the array
|
||||
Impl::calcStats((*iter), type_counts, share_counts);
|
||||
iter++;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// Add in the values for this array
|
||||
@@ -703,7 +705,7 @@ void LLSD::Impl::assign(Impl*& var, const Impl* other)
|
||||
|
||||
void LLSD::Impl::assignUndefined(Impl*& var)
|
||||
{
|
||||
reset(var, 0);
|
||||
reset(var, nullptr);
|
||||
}
|
||||
|
||||
void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v)
|
||||
@@ -779,7 +781,7 @@ void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
S32 tp = S32(type());
|
||||
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
|
||||
{
|
||||
type_counts[tp]++;
|
||||
type_counts[tp]++;
|
||||
if (shared())
|
||||
{
|
||||
share_counts[tp]++;
|
||||
@@ -813,10 +815,10 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
|
||||
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
|
||||
LLSD::LLSD() : impl(nullptr) { ALLOC_LLSD_OBJECT; }
|
||||
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, nullptr); }
|
||||
|
||||
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
|
||||
LLSD::LLSD(const LLSD& other) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(other); }
|
||||
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
|
||||
|
||||
|
||||
@@ -825,17 +827,17 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
|
||||
LLSD::Type LLSD::type() const { return safe(impl).type(); }
|
||||
|
||||
// Scalar Constructors
|
||||
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Boolean v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
|
||||
// Convenience Constructors
|
||||
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
|
||||
LLSD::LLSD(F32 v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign((Real)v); }
|
||||
|
||||
// Scalar Assignment
|
||||
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
|
||||
@@ -860,7 +862,7 @@ const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
|
||||
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
|
||||
|
||||
// const char * helpers
|
||||
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const char* v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
void LLSD::assign(const char* v)
|
||||
{
|
||||
if(v) assign(std::string(v));
|
||||
@@ -927,7 +929,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
|
||||
// sStorage will point to the result of the last call. This will actually
|
||||
// be one leak, but since this is used only when running under the
|
||||
// debugger, it should not be an issue.
|
||||
static char *sStorage = NULL;
|
||||
static char *sStorage = nullptr;
|
||||
delete[] sStorage;
|
||||
std::string out_string;
|
||||
{
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "llsdutil_math.h"
|
||||
#include "message.h"
|
||||
#include "u64.h"
|
||||
#include "llregionflags.h"
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
|
||||
static const F32 SOME_BIG_NUMBER = 1000.0f;
|
||||
static const F32 SOME_BIG_NEG_NUMBER = -1000.0f;
|
||||
@@ -742,8 +744,8 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
|
||||
void LLParcel::packAccessEntries(LLMessageSystem* msg,
|
||||
const std::map<LLUUID,LLAccessEntry>& list)
|
||||
{
|
||||
access_map_const_iterator cit = list.begin();
|
||||
access_map_const_iterator end = list.end();
|
||||
LLAccessEntry::map::const_iterator cit = list.begin();
|
||||
LLAccessEntry::map::const_iterator end = list.end();
|
||||
|
||||
if (cit == end)
|
||||
{
|
||||
@@ -794,9 +796,28 @@ void LLParcel::unpackAccessEntries(LLMessageSystem* msg,
|
||||
}
|
||||
|
||||
|
||||
void LLParcel::unpackExperienceEntries(LLMessageSystem* msg, U32 type)
|
||||
{
|
||||
LLUUID id;
|
||||
|
||||
S32 i;
|
||||
S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
|
||||
|
||||
if (id.notNull())
|
||||
{
|
||||
mExperienceKeys[id] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLParcel::expirePasses(S32 now)
|
||||
{
|
||||
access_map_iterator itor = mAccessList.begin();
|
||||
LLAccessEntry::map::iterator itor = mAccessList.begin();
|
||||
while (itor != mAccessList.end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -886,7 +907,7 @@ BOOL LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
|
||||
// Can't add owner to these lists
|
||||
return FALSE;
|
||||
}
|
||||
access_map_iterator itor = mAccessList.begin();
|
||||
LLAccessEntry::map::iterator itor = mAccessList.begin();
|
||||
while (itor != mAccessList.end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -931,7 +952,7 @@ BOOL LLParcel::addToBanList(const LLUUID& agent_id, S32 time)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
access_map_iterator itor = mBanList.begin();
|
||||
LLAccessEntry::map::iterator itor = mBanList.begin();
|
||||
while (itor != mBanList.end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -970,7 +991,7 @@ BOOL remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list,
|
||||
const LLUUID& agent_id)
|
||||
{
|
||||
BOOL removed = FALSE;
|
||||
access_map_iterator itor = list->begin();
|
||||
LLAccessEntry::map::iterator itor = list->begin();
|
||||
while (itor != list->end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -1091,7 +1112,7 @@ void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group)
|
||||
mSaleTimerExpires.start();
|
||||
mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT));
|
||||
mStatus = OS_LEASE_PENDING;
|
||||
mClaimDate = time(NULL);
|
||||
mClaimDate = time(nullptr);
|
||||
setAuctionID(0);
|
||||
// clear the autoreturn whenever land changes hands
|
||||
setCleanOtherTime(0);
|
||||
@@ -1313,3 +1334,58 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
|
||||
// is a distinct option from "None" and "Other"
|
||||
return LLParcel::C_ANY;
|
||||
}
|
||||
|
||||
LLAccessEntry::map LLParcel::getExperienceKeysByType(U32 type) const
|
||||
{
|
||||
LLAccessEntry::map access;
|
||||
LLAccessEntry entry;
|
||||
xp_type_map_t::const_iterator it = mExperienceKeys.begin();
|
||||
for(/**/; it != mExperienceKeys.end(); ++it)
|
||||
{
|
||||
if(it->second == type)
|
||||
{
|
||||
entry.mID = it->first;
|
||||
access[entry.mID] = entry;
|
||||
}
|
||||
}
|
||||
return access;
|
||||
}
|
||||
|
||||
void LLParcel::clearExperienceKeysByType(U32 type)
|
||||
{
|
||||
xp_type_map_t::iterator it = mExperienceKeys.begin();
|
||||
while(it != mExperienceKeys.end())
|
||||
{
|
||||
if(it->second == type)
|
||||
{
|
||||
mExperienceKeys.erase(it++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLParcel::setExperienceKeyType(const LLUUID& experience_key, U32 type)
|
||||
{
|
||||
if (type == EXPERIENCE_KEY_TYPE_NONE)
|
||||
{
|
||||
mExperienceKeys.erase(experience_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (countExperienceKeyType(type) < PARCEL_MAX_EXPERIENCE_LIST)
|
||||
{
|
||||
mExperienceKeys[experience_key] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLParcel::countExperienceKeyType(U32 type)
|
||||
{
|
||||
return std::count_if(
|
||||
boost::begin(mExperienceKeys | boost::adaptors::map_values),
|
||||
boost::end(mExperienceKeys | boost::adaptors::map_values),
|
||||
std::bind2nd(std::equal_to<U32>(), type));
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ const S32 PARCEL_MAX_ACCESS_LIST = 300;
|
||||
//for access/ban lists.
|
||||
const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
|
||||
|
||||
// Maximum number of experiences
|
||||
const S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
|
||||
|
||||
// Weekly charge for listing a parcel in the directory
|
||||
const S32 PARCEL_DIRECTORY_FEE = 30;
|
||||
|
||||
@@ -141,9 +144,11 @@ class LLSD;
|
||||
class LLAccessEntry
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<LLUUID,LLAccessEntry> map;
|
||||
|
||||
LLAccessEntry()
|
||||
: mID(),
|
||||
mTime(0),
|
||||
: mTime(0),
|
||||
mFlags(0)
|
||||
{}
|
||||
|
||||
@@ -152,8 +157,6 @@ public:
|
||||
U32 mFlags; // Not used - currently should always be zero
|
||||
};
|
||||
|
||||
typedef std::map<LLUUID,LLAccessEntry>::iterator access_map_iterator;
|
||||
typedef std::map<LLUUID,LLAccessEntry>::const_iterator access_map_const_iterator;
|
||||
|
||||
class LLParcel
|
||||
{
|
||||
@@ -331,6 +334,9 @@ public:
|
||||
void unpackAccessEntries(LLMessageSystem* msg,
|
||||
std::map<LLUUID,LLAccessEntry>* list);
|
||||
|
||||
void unpackExperienceEntries(LLMessageSystem* msg, U32 type);
|
||||
|
||||
|
||||
void setAABBMin(const LLVector3& min) { mAABBMin = min; }
|
||||
void setAABBMax(const LLVector3& max) { mAABBMax = max; }
|
||||
|
||||
@@ -707,6 +713,17 @@ public:
|
||||
std::map<LLUUID,LLAccessEntry> mTempBanList;
|
||||
std::map<LLUUID,LLAccessEntry> mTempAccessList;
|
||||
|
||||
typedef std::map<LLUUID, U32> xp_type_map_t;
|
||||
|
||||
void setExperienceKeyType(const LLUUID& experience_key, U32 type);
|
||||
U32 countExperienceKeyType(U32 type);
|
||||
U32 getExperienceKeyType(const LLUUID& experience_key)const;
|
||||
LLAccessEntry::map getExperienceKeysByType(U32 type)const;
|
||||
void clearExperienceKeysByType(U32 type);
|
||||
|
||||
private:
|
||||
xp_type_map_t mExperienceKeys;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
/**
|
||||
* @file llparcelflags.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -97,8 +91,10 @@ const U32 PF_DEFAULT = PF_ALLOW_FLY
|
||||
| PF_USE_ESTATE_VOICE_CHAN;
|
||||
|
||||
// Access list flags
|
||||
const U32 AL_ACCESS = (1 << 0);
|
||||
const U32 AL_BAN = (1 << 1);
|
||||
const U32 AL_ACCESS = (1 << 0);
|
||||
const U32 AL_BAN = (1 << 1);
|
||||
const U32 AL_ALLOW_EXPERIENCE = (1 << 3);
|
||||
const U32 AL_BLOCK_EXPERIENCE = (1 << 4);
|
||||
//const U32 AL_RENTER = (1 << 2);
|
||||
|
||||
// Block access return values. BA_ALLOWED is the only success case
|
||||
|
||||
@@ -45,6 +45,7 @@ set(llmessage_SOURCE_FILES
|
||||
llclassifiedflags.cpp
|
||||
lldatapacker.cpp
|
||||
lldispatcher.cpp
|
||||
llexperiencecache.cpp
|
||||
llfiltersd2xmlrpc.cpp
|
||||
llhost.cpp
|
||||
llhttpclient.cpp
|
||||
@@ -133,10 +134,12 @@ set(llmessage_HEADER_FILES
|
||||
llcipher.h
|
||||
llcircuit.h
|
||||
llclassifiedflags.h
|
||||
llcororesponder.h
|
||||
llcurl.h
|
||||
lldatapacker.h
|
||||
lldbstrings.h
|
||||
lldispatcher.h
|
||||
llexperiencecache.h
|
||||
lleventflags.h
|
||||
llfiltersd2xmlrpc.h
|
||||
llfollowcamparams.h
|
||||
|
||||
43
indra/llmessage/llcororesponder.h
Normal file
43
indra/llmessage/llcororesponder.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file llcororesponder.h
|
||||
* @brief A responder purposed to call coro functions, to ease transition to LLCoro
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
*
|
||||
* Copyright (C) 2020, Liru Færs
|
||||
*
|
||||
* 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 <functional>
|
||||
#include "llhttpclient.h"
|
||||
|
||||
struct LLCoroResponder final : public LLHTTPClient::ResponderWithCompleted
|
||||
{
|
||||
typedef std::function<void(const LLCoroResponder&)> cb_t;
|
||||
LLCoroResponder(const cb_t& cb) : mCB(cb) {}
|
||||
void httpCompleted() override { mCB(*this); }
|
||||
const AIHTTPReceivedHeaders& getHeaders() const { return mReceivedHeaders; }
|
||||
const LLSD& getContent() const { return mContent; }
|
||||
|
||||
char const* getName() const override { return "LLCoroResponder"; }
|
||||
private:
|
||||
const cb_t mCB;
|
||||
};
|
||||
|
||||
928
indra/llmessage/llexperiencecache.cpp
Normal file
928
indra/llmessage/llexperiencecache.cpp
Normal file
@@ -0,0 +1,928 @@
|
||||
/**
|
||||
* @file llexperiencecache.cpp
|
||||
* @brief llexperiencecache and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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 "llexperiencecache.h"
|
||||
|
||||
#include "llavatarname.h"
|
||||
#include "llcororesponder.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "lleventfilter.h"
|
||||
#include "lldir.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
//=========================================================================
|
||||
namespace LLExperienceCacheImpl
|
||||
{
|
||||
void mapKeys(const LLSD& legacyKeys);
|
||||
F64 getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers);
|
||||
bool maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age);
|
||||
|
||||
static const std::string PRIVATE_KEY = "private_id";
|
||||
static const std::string EXPERIENCE_ID = "public_id";
|
||||
|
||||
static const std::string MAX_AGE("max-age");
|
||||
static const boost::char_separator<char> EQUALS_SEPARATOR("=");
|
||||
static const boost::char_separator<char> COMMA_SEPARATOR(",");
|
||||
|
||||
// *TODO$: this seems to be tied to mapKeys which is used by bootstrap.... but I don't think that bootstrap is used.
|
||||
typedef std::map<LLUUID, LLUUID> KeyMap;
|
||||
KeyMap privateToPublicKeyMap;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
const std::string LLExperienceCache::PRIVATE_KEY = "private_id";
|
||||
const std::string LLExperienceCache::MISSING = "DoesNotExist";
|
||||
|
||||
const std::string LLExperienceCache::AGENT_ID = "agent_id";
|
||||
const std::string LLExperienceCache::GROUP_ID = "group_id";
|
||||
const std::string LLExperienceCache::EXPERIENCE_ID = "public_id";
|
||||
const std::string LLExperienceCache::NAME = "name";
|
||||
const std::string LLExperienceCache::PROPERTIES = "properties";
|
||||
const std::string LLExperienceCache::EXPIRES = "expiration";
|
||||
const std::string LLExperienceCache::DESCRIPTION = "description";
|
||||
const std::string LLExperienceCache::QUOTA = "quota";
|
||||
const std::string LLExperienceCache::MATURITY = "maturity";
|
||||
const std::string LLExperienceCache::METADATA = "extended_metadata";
|
||||
const std::string LLExperienceCache::SLURL = "slurl";
|
||||
|
||||
// should be in sync with experience-api/experiences/models.py
|
||||
const int LLExperienceCache::PROPERTY_INVALID = 1 << 0;
|
||||
const int LLExperienceCache::PROPERTY_PRIVILEGED = 1 << 3;
|
||||
const int LLExperienceCache::PROPERTY_GRID = 1 << 4;
|
||||
const int LLExperienceCache::PROPERTY_PRIVATE = 1 << 5;
|
||||
const int LLExperienceCache::PROPERTY_DISABLED = 1 << 6;
|
||||
const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7;
|
||||
|
||||
// default values
|
||||
const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0;
|
||||
const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes
|
||||
const int LLExperienceCache::SEARCH_PAGE_SIZE = 30;
|
||||
|
||||
//=========================================================================
|
||||
LLExperienceCache::LLExperienceCache():
|
||||
mShutdown(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLExperienceCache::~LLExperienceCache()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLExperienceCache::initSingleton()
|
||||
{
|
||||
mCacheFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "experience_cache.xml");
|
||||
|
||||
LL_INFOS("ExperienceCache") << "Loading " << mCacheFileName << LL_ENDL;
|
||||
llifstream cache_stream(mCacheFileName.c_str());
|
||||
|
||||
if (cache_stream.is_open())
|
||||
{
|
||||
cache_stream >> (*this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLExperienceCache::cleanup()
|
||||
{
|
||||
LL_INFOS("ExperienceCache") << "Saving " << mCacheFileName << LL_ENDL;
|
||||
|
||||
llofstream cache_stream(mCacheFileName.c_str());
|
||||
if (cache_stream.is_open())
|
||||
{
|
||||
cache_stream << (*this);
|
||||
}
|
||||
mShutdown = true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::importFile(std::istream& istr)
|
||||
{
|
||||
LLSD data;
|
||||
S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
|
||||
if (parse_count < 1) return;
|
||||
|
||||
LLSD experiences = data["experiences"];
|
||||
|
||||
LLUUID public_key;
|
||||
LLSD::map_const_iterator it = experiences.beginMap();
|
||||
for (; it != experiences.endMap(); ++it)
|
||||
{
|
||||
public_key.set(it->first);
|
||||
mCache[public_key] = it->second;
|
||||
}
|
||||
|
||||
LL_DEBUGS("ExperienceCache") << "importFile() loaded " << mCache.size() << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLExperienceCache::exportFile(std::ostream& ostr) const
|
||||
{
|
||||
LLSD experiences;
|
||||
|
||||
cache_t::const_iterator it = mCache.begin();
|
||||
for (; it != mCache.end(); ++it)
|
||||
{
|
||||
if (!it->second.has(EXPERIENCE_ID) || it->second[EXPERIENCE_ID].asUUID().isNull() ||
|
||||
it->second.has("DoesNotExist") || (it->second.has(PROPERTIES) && it->second[PROPERTIES].asInteger() & PROPERTY_INVALID))
|
||||
continue;
|
||||
|
||||
experiences[it->first.asString()] = it->second;
|
||||
}
|
||||
|
||||
LLSD data;
|
||||
data["experiences"] = experiences;
|
||||
|
||||
LLSDSerialize::toPrettyXML(data, ostr);
|
||||
}
|
||||
|
||||
// *TODO$: Rider: This method does not seem to be used... it may be useful in testing.
|
||||
void LLExperienceCache::bootstrap(const LLSD& legacyKeys, int initialExpiration)
|
||||
{
|
||||
LLExperienceCacheImpl::mapKeys(legacyKeys);
|
||||
LLSD::array_const_iterator it = legacyKeys.beginArray();
|
||||
for (/**/; it != legacyKeys.endArray(); ++it)
|
||||
{
|
||||
LLSD experience = *it;
|
||||
if (experience.has(EXPERIENCE_ID))
|
||||
{
|
||||
if (!experience.has(EXPIRES))
|
||||
{
|
||||
experience[EXPIRES] = initialExpiration;
|
||||
}
|
||||
processExperience(experience[EXPERIENCE_ID].asUUID(), experience);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ExperienceCache")
|
||||
<< "Skipping bootstrap entry which is missing " << EXPERIENCE_ID
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_if_not_found)
|
||||
{
|
||||
if (private_key.isNull())
|
||||
return LLUUID::null;
|
||||
|
||||
LLExperienceCacheImpl::KeyMap::const_iterator it = LLExperienceCacheImpl::privateToPublicKeyMap.find(private_key);
|
||||
if (it == LLExperienceCacheImpl::privateToPublicKeyMap.end())
|
||||
{
|
||||
if (null_if_not_found)
|
||||
{
|
||||
return LLUUID::null;
|
||||
}
|
||||
return private_key;
|
||||
}
|
||||
LL_WARNS("LLExperience") << "converted private key " << private_key << " to experience_id " << it->second << LL_ENDL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void LLExperienceCache::processExperience(const LLUUID& public_key, const LLSD& experience)
|
||||
{
|
||||
LL_INFOS("ExperienceCache") << "Processing experience \"" << experience[NAME] << "\" with key " << public_key.asString() << LL_ENDL;
|
||||
|
||||
mCache[public_key]=experience;
|
||||
LLSD & row = mCache[public_key];
|
||||
|
||||
if(row.has(EXPIRES))
|
||||
{
|
||||
row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds();
|
||||
}
|
||||
|
||||
if(row.has(EXPERIENCE_ID))
|
||||
{
|
||||
mPendingQueue.erase(row[EXPERIENCE_ID].asUUID());
|
||||
}
|
||||
|
||||
//signal
|
||||
signal_map_t::iterator sig_it = mSignalMap.find(public_key);
|
||||
if (sig_it != mSignalMap.end())
|
||||
{
|
||||
signal_ptr signal = sig_it->second;
|
||||
(*signal)(experience);
|
||||
|
||||
mSignalMap.erase(public_key);
|
||||
}
|
||||
}
|
||||
|
||||
const LLExperienceCache::cache_t& LLExperienceCache::getCached()
|
||||
{
|
||||
return mCache;
|
||||
}
|
||||
|
||||
void LLExperienceCache::requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t requests)
|
||||
{
|
||||
//LL_INFOS("requestExperiencesCoro") << "url: " << url << LL_ENDL;
|
||||
|
||||
LLSD result = responder.getContent();
|
||||
auto status = responder.getStatus();
|
||||
|
||||
if (!responder.isGoodStatus(status))
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
auto headers = responder.getHeaders();
|
||||
// build dummy entries for the failed requests
|
||||
for (auto request : requests)
|
||||
{
|
||||
LLSD exp = get(request);
|
||||
//leave the properties alone if we already have a cache entry for this xp
|
||||
if (exp.isUndefined())
|
||||
{
|
||||
exp[PROPERTIES] = PROPERTY_INVALID;
|
||||
}
|
||||
exp[EXPIRES] = now + LLExperienceCacheImpl::getErrorRetryDeltaTime(status, headers);
|
||||
exp[EXPERIENCE_ID] = request;
|
||||
exp["key_type"] = EXPERIENCE_ID;
|
||||
exp["uuid"] = request;
|
||||
exp["error"] = status;
|
||||
exp[QUOTA] = DEFAULT_QUOTA;
|
||||
|
||||
processExperience(request, exp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD experiences = result["experience_keys"];
|
||||
|
||||
for (LLSD::array_const_iterator it = experiences.beginArray();
|
||||
it != experiences.endArray(); ++it)
|
||||
{
|
||||
const LLSD& row = *it;
|
||||
LLUUID public_key = row[EXPERIENCE_ID].asUUID();
|
||||
|
||||
LL_DEBUGS("ExperienceCache") << "Received result for " << public_key
|
||||
<< " display '" << row[LLExperienceCache::NAME].asString() << "'" << LL_ENDL;
|
||||
|
||||
processExperience(public_key, row);
|
||||
}
|
||||
|
||||
LLSD error_ids = result["error_ids"];
|
||||
|
||||
for (LLSD::array_const_iterator errIt = error_ids.beginArray();
|
||||
errIt != error_ids.endArray(); ++errIt)
|
||||
{
|
||||
LLUUID id = errIt->asUUID();
|
||||
LLSD exp;
|
||||
exp[EXPIRES] = DEFAULT_EXPIRATION;
|
||||
exp[EXPERIENCE_ID] = id;
|
||||
exp[PROPERTIES] = PROPERTY_INVALID;
|
||||
exp[MISSING] = true;
|
||||
exp[QUOTA] = DEFAULT_QUOTA;
|
||||
|
||||
processExperience(id, exp);
|
||||
LL_WARNS("ExperienceCache") << "LLExperienceResponder::result() error result for " << id << LL_ENDL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLExperienceCache::requestExperiences()
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string urlBase = mCapability("GetExperienceInfo");
|
||||
if (urlBase.empty())
|
||||
{
|
||||
LL_DEBUGS("ExperienceCache") << "No Experience capability." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*urlBase.rbegin() != '/')
|
||||
{
|
||||
urlBase += "/";
|
||||
}
|
||||
urlBase += "id/";
|
||||
|
||||
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
const U32 EXP_URL_SEND_THRESHOLD = 3000;
|
||||
constexpr U32 EXP_PAGE_SIZE = EXP_URL_SEND_THRESHOLD / UUID_STR_LENGTH;
|
||||
|
||||
std::ostringstream ostr;
|
||||
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
|
||||
RequestQueue_t requests;
|
||||
|
||||
while (!mRequestQueue.empty())
|
||||
{
|
||||
RequestQueue_t::iterator it = mRequestQueue.begin();
|
||||
LLUUID key = (*it);
|
||||
mRequestQueue.erase(it);
|
||||
requests.insert(key);
|
||||
|
||||
ostr << "&" << EXPERIENCE_ID << "=" << key.asString();
|
||||
mPendingQueue[key] = now;
|
||||
|
||||
if (mRequestQueue.empty() || (ostr.tellp() > EXP_URL_SEND_THRESHOLD))
|
||||
{ // request is placed in the coprocedure pool for the ExpCache cache. Throttling is done by the pool itself.
|
||||
LLHTTPClient::get(ostr.str(), new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::requestExperiencesCoro, this, _1, requests) ));
|
||||
|
||||
ostr.str(std::string());
|
||||
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
|
||||
requests.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool LLExperienceCache::isRequestPending(const LLUUID& public_key)
|
||||
{
|
||||
bool isPending = false;
|
||||
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
|
||||
|
||||
PendingQueue_t::const_iterator it = mPendingQueue.find(public_key);
|
||||
|
||||
if(it != mPendingQueue.end())
|
||||
{
|
||||
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
|
||||
isPending = (it->second > expire_time);
|
||||
}
|
||||
|
||||
return isPending;
|
||||
}
|
||||
|
||||
void LLExperienceCache::setCapabilityQuery(LLExperienceCache::CapabilityQuery_t queryfn)
|
||||
{
|
||||
mCapability = queryfn;
|
||||
}
|
||||
|
||||
|
||||
void LLExperienceCache::idleCoro()
|
||||
{
|
||||
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
|
||||
const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
|
||||
|
||||
{
|
||||
static LLFrameTimer sRequestTimer;
|
||||
if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) return;
|
||||
|
||||
if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
|
||||
{
|
||||
eraseExpired();
|
||||
}
|
||||
|
||||
if (!mRequestQueue.empty())
|
||||
{
|
||||
requestExperiences();
|
||||
}
|
||||
}
|
||||
|
||||
// The coroutine system will likely be shut down by the time we get to this point
|
||||
// (or at least no further cycling will occur on it since the user has decided to quit.)
|
||||
}
|
||||
|
||||
void LLExperienceCache::erase(const LLUUID& key)
|
||||
{
|
||||
cache_t::iterator it = mCache.find(key);
|
||||
|
||||
if(it != mCache.end())
|
||||
{
|
||||
mCache.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void LLExperienceCache::eraseExpired()
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
cache_t::iterator it = mCache.begin();
|
||||
while (it != mCache.end())
|
||||
{
|
||||
cache_t::iterator cur = it;
|
||||
LLSD& exp = cur->second;
|
||||
++it;
|
||||
|
||||
//LL_INFOS("ExperienceCache") << "Testing experience \"" << exp[NAME] << "\" with exp time " << exp[EXPIRES].asReal() << "(now = " << now << ")" << LL_ENDL;
|
||||
|
||||
if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
|
||||
{
|
||||
if(!exp.has(EXPERIENCE_ID))
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
|
||||
mCache.erase(cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID id = exp[EXPERIENCE_ID].asUUID();
|
||||
LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
|
||||
if(private_key.notNull() || !exp.has("DoesNotExist"))
|
||||
{
|
||||
fetch(id, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
|
||||
mCache.erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLExperienceCache::fetch(const LLUUID& key, bool refresh/* = true*/)
|
||||
{
|
||||
if(!key.isNull() && !isRequestPending(key) && (refresh || mCache.find(key)==mCache.end()))
|
||||
{
|
||||
LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL;
|
||||
|
||||
mRequestQueue.insert(key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLExperienceCache::insert(const LLSD& experience_data)
|
||||
{
|
||||
if(experience_data.has(EXPERIENCE_ID))
|
||||
{
|
||||
processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
const LLSD& LLExperienceCache::get(const LLUUID& key)
|
||||
{
|
||||
static const LLSD empty;
|
||||
|
||||
if(key.isNull())
|
||||
return empty;
|
||||
cache_t::const_iterator it = mCache.find(key);
|
||||
|
||||
if (it != mCache.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
fetch(key);
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::ExperienceGetFn_t slot)
|
||||
{
|
||||
if(key.isNull())
|
||||
return;
|
||||
|
||||
cache_t::const_iterator it = mCache.find(key);
|
||||
if (it != mCache.end())
|
||||
{
|
||||
// ...name already exists in cache, fire callback now
|
||||
callback_signal_t signal;
|
||||
signal.connect(slot);
|
||||
|
||||
signal(it->second);
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(key);
|
||||
|
||||
signal_ptr signal = boost::make_shared<callback_signal_t>();
|
||||
|
||||
std::pair<signal_map_t::iterator, bool> result = mSignalMap.insert(signal_map_t::value_type(key, signal));
|
||||
if (!result.second)
|
||||
signal = (*result.first).second;
|
||||
signal->connect(slot);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
url = mCapability("GetMetadata");
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LLSD fields;
|
||||
fields.append("experience");
|
||||
LLSD data;
|
||||
data["object-id"] = objectId;
|
||||
data["item-id"] = itemId;
|
||||
data["fields"] = fields;
|
||||
|
||||
LLHTTPClient::post(url, data, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
auto status = responder.getStatus();
|
||||
|
||||
if (!responder.isGoodStatus(status) || !result.has("experience"))
|
||||
{
|
||||
LLSD failure;
|
||||
if (!status)
|
||||
{
|
||||
failure["error"] = status;
|
||||
failure["message"] = responder.getReason();
|
||||
}
|
||||
else
|
||||
{
|
||||
failure["error"] = -1;
|
||||
failure["message"] = "no experience";
|
||||
}
|
||||
if (fn != nullptr)
|
||||
fn(failure);
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID expId = result["experience"].asUUID();
|
||||
get(expId, fn);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream url;
|
||||
|
||||
url << mCapability("FindExperienceByName") << "?page=" << page << "&page_size=" << SEARCH_PAGE_SIZE << "&query=" << LLURI::escape(text);
|
||||
|
||||
LLHTTPClient::get(url.str(), new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::findExperienceByNameCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
fn(LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
const LLSD& experiences = result["experience_keys"];
|
||||
for (LLSD::array_const_iterator it = experiences.beginArray(); it != experiences.endArray(); ++it)
|
||||
{
|
||||
insert(*it);
|
||||
}
|
||||
|
||||
fn(result);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// search for experiences owned by the current group
|
||||
std::string url = mCapability("GroupExperiences");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Group Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
url += "?" + groupId.asString();
|
||||
|
||||
LLHTTPClient::get(url, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::getGroupExperiencesCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
fn(LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
const LLSD& experienceIds = result["experience_ids"];
|
||||
fn(experienceIds);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn)
|
||||
{
|
||||
regionExperiences(regioncaps, LLSD(), false, fn);
|
||||
}
|
||||
|
||||
void LLExperienceCache::setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn)
|
||||
{
|
||||
regionExperiences(regioncaps, experiences, true, fn);
|
||||
}
|
||||
|
||||
void LLExperienceCache::regionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, bool update, ExperienceGetFn_t fn)
|
||||
{
|
||||
// search for experiences owned by the current group
|
||||
std::string url = regioncaps("RegionExperiences");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
auto httpRequest = new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::regionExperiencesCoro, this, _1, fn));
|
||||
|
||||
LLSD result;
|
||||
if (update)
|
||||
LLHTTPClient::post(url, experiences, httpRequest);
|
||||
else
|
||||
LLHTTPClient::get(url, httpRequest);
|
||||
}
|
||||
|
||||
void LLExperienceCache::regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
// fn(LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
fn(result);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
|
||||
|
||||
LLHTTPClient::get(url, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("ExperiencePreferences");
|
||||
if (url.empty())
|
||||
return;
|
||||
LLSD permData;
|
||||
LLSD data;
|
||||
permData["permission"] = permission;
|
||||
data[experienceId.asString()] = permData;
|
||||
|
||||
LLHTTPClient::put(url, data, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
|
||||
LLHTTPClient::del(url, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
// search for experiences owned by the current group
|
||||
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
fn(result);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("IsExperienceAdmin");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
url += "?experience_id=" + experienceId.asString();
|
||||
|
||||
LLHTTPClient::get(url, new LLCoroResponder(
|
||||
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::updateExperience(LLSD updateData, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("UpdateExperience");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
updateData.erase(LLExperienceCache::QUOTA);
|
||||
updateData.erase(LLExperienceCache::EXPIRES);
|
||||
updateData.erase(LLExperienceCache::AGENT_ID);
|
||||
|
||||
LLHTTPClient::post(url, updateData, new LLCoroResponder(
|
||||
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void LLExperienceCacheImpl::mapKeys(const LLSD& legacyKeys)
|
||||
{
|
||||
LLSD::array_const_iterator exp = legacyKeys.beginArray();
|
||||
for (/**/; exp != legacyKeys.endArray(); ++exp)
|
||||
{
|
||||
if (exp->has(LLExperienceCacheImpl::EXPERIENCE_ID) && exp->has(LLExperienceCacheImpl::PRIVATE_KEY))
|
||||
{
|
||||
LLExperienceCacheImpl::privateToPublicKeyMap[(*exp)[LLExperienceCacheImpl::PRIVATE_KEY].asUUID()] =
|
||||
(*exp)[LLExperienceCacheImpl::EXPERIENCE_ID].asUUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return time to retry a request that generated an error, based on
|
||||
// error type and headers. Return value is seconds-since-epoch.
|
||||
F64 LLExperienceCacheImpl::getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers)
|
||||
{
|
||||
// Retry-After takes priority
|
||||
std::string retry_afters;
|
||||
if (headers.getFirstValue("retry-after", retry_afters))
|
||||
{
|
||||
LLSD retry_after(retry_afters);
|
||||
// We only support the delta-seconds type
|
||||
S32 delta_seconds = retry_after.asInteger();
|
||||
if (delta_seconds > 0)
|
||||
{
|
||||
// ...valid delta-seconds
|
||||
return F64(delta_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
// If no Retry-After, look for Cache-Control max-age
|
||||
// Allow the header to override the default
|
||||
std::string cache_control;
|
||||
if (headers.getFirstValue("cache-control", cache_control))
|
||||
{
|
||||
S32 max_age = 0;
|
||||
if (LLExperienceCacheImpl::maxAgeFromCacheControl(cache_control, &max_age))
|
||||
{
|
||||
LL_WARNS("ExperienceCache")
|
||||
<< "got EXPIRES from headers, max_age " << max_age
|
||||
<< LL_ENDL;
|
||||
return (F64)max_age;
|
||||
}
|
||||
}
|
||||
|
||||
// No information in header, make a guess
|
||||
if (status == 503)
|
||||
{
|
||||
// ...service unavailable, retry soon
|
||||
const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
|
||||
return SERVICE_UNAVAILABLE_DELAY;
|
||||
}
|
||||
else if (status == 499)
|
||||
{
|
||||
// ...we were probably too busy, retry quickly
|
||||
const F64 BUSY_DELAY = 10.0; // 10 seconds
|
||||
return BUSY_DELAY;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...other unexpected error
|
||||
const F64 DEFAULT_DELAY = 3600.0; // 1 hour
|
||||
return DEFAULT_DELAY;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLExperienceCacheImpl::maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age)
|
||||
{
|
||||
// Split the string on "," to get a list of directives
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
tokenizer directives(cache_control, COMMA_SEPARATOR);
|
||||
|
||||
tokenizer::iterator token_it = directives.begin();
|
||||
for ( ; token_it != directives.end(); ++token_it)
|
||||
{
|
||||
// Tokens may have leading or trailing whitespace
|
||||
std::string token = *token_it;
|
||||
LLStringUtil::trim(token);
|
||||
|
||||
if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
|
||||
{
|
||||
// ...this token starts with max-age, so let's chop it up by "="
|
||||
tokenizer subtokens(token, EQUALS_SEPARATOR);
|
||||
tokenizer::iterator subtoken_it = subtokens.begin();
|
||||
|
||||
// Must have a token
|
||||
if (subtoken_it == subtokens.end()) return false;
|
||||
std::string subtoken = *subtoken_it;
|
||||
|
||||
// Must exactly equal "max-age"
|
||||
LLStringUtil::trim(subtoken);
|
||||
if (subtoken != MAX_AGE) return false;
|
||||
|
||||
// Must have another token
|
||||
++subtoken_it;
|
||||
if (subtoken_it == subtokens.end()) return false;
|
||||
subtoken = *subtoken_it;
|
||||
|
||||
// Must be a valid integer
|
||||
// *NOTE: atoi() returns 0 for invalid values, so we have to
|
||||
// check the string first.
|
||||
// *TODO: Do servers ever send "0000" for zero? We don't handle it
|
||||
LLStringUtil::trim(subtoken);
|
||||
if (subtoken == "0")
|
||||
{
|
||||
*max_age = 0;
|
||||
return true;
|
||||
}
|
||||
S32 val = atoi( subtoken.c_str() );
|
||||
if (val > 0 && val < S32_MAX)
|
||||
{
|
||||
*max_age = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
181
indra/llmessage/llexperiencecache.h
Normal file
181
indra/llmessage/llexperiencecache.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @file llexperiencecache.h
|
||||
* @brief Caches information relating to experience keys
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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_LLEXPERIENCECACHE_H
|
||||
#define LL_LLEXPERIENCECACHE_H
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llsd.h"
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
struct LLCoroResponder;
|
||||
class LLSD;
|
||||
class LLUUID;
|
||||
|
||||
|
||||
class LLExperienceCache final : public LLSingleton < LLExperienceCache >
|
||||
{
|
||||
friend class LLSingleton<LLExperienceCache>;
|
||||
LLExperienceCache();
|
||||
|
||||
public:
|
||||
typedef std::function<std::string(const std::string &)> CapabilityQuery_t;
|
||||
typedef std::function<void(const LLSD &)> ExperienceGetFn_t;
|
||||
|
||||
void idleCoro();
|
||||
void setCapabilityQuery(CapabilityQuery_t queryfn);
|
||||
void cleanup();
|
||||
|
||||
//-------------------------------------------
|
||||
// Cache methods
|
||||
void erase(const LLUUID& key);
|
||||
bool fetch(const LLUUID& key, bool refresh = false);
|
||||
void insert(const LLSD& experience_data);
|
||||
const LLSD& get(const LLUUID& key);
|
||||
void get(const LLUUID& key, ExperienceGetFn_t slot); // If name information is in cache, callback will be called immediately.
|
||||
|
||||
bool isRequestPending(const LLUUID& public_key);
|
||||
|
||||
//-------------------------------------------
|
||||
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn) { fetchAssociatedExperience(objectId, itemId, LLStringUtil::null, fn); }
|
||||
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
|
||||
void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
|
||||
void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
|
||||
|
||||
// the Get/Set Region Experiences take a CapabilityQuery to get the capability since
|
||||
// the region being queried may not be the region that the agent is standing on.
|
||||
void getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn);
|
||||
void setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn);
|
||||
|
||||
void getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
|
||||
void setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn);
|
||||
void forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
|
||||
|
||||
void getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn);
|
||||
|
||||
void updateExperience(LLSD updateData, ExperienceGetFn_t fn);
|
||||
//-------------------------------------------
|
||||
static const std::string NAME; // "name"
|
||||
static const std::string EXPERIENCE_ID; // "public_id"
|
||||
static const std::string AGENT_ID; // "agent_id"
|
||||
static const std::string GROUP_ID; // "group_id"
|
||||
static const std::string PROPERTIES; // "properties"
|
||||
static const std::string EXPIRES; // "expiration"
|
||||
static const std::string DESCRIPTION; // "description"
|
||||
static const std::string QUOTA; // "quota"
|
||||
static const std::string MATURITY; // "maturity"
|
||||
static const std::string METADATA; // "extended_metadata"
|
||||
static const std::string SLURL; // "slurl"
|
||||
|
||||
static const std::string MISSING; // "DoesNotExist"
|
||||
|
||||
// should be in sync with experience-api/experiences/models.py
|
||||
static const int PROPERTY_INVALID; // 1 << 0
|
||||
static const int PROPERTY_PRIVILEGED; // 1 << 3
|
||||
static const int PROPERTY_GRID; // 1 << 4
|
||||
static const int PROPERTY_PRIVATE; // 1 << 5
|
||||
static const int PROPERTY_DISABLED; // 1 << 6
|
||||
static const int PROPERTY_SUSPENDED; // 1 << 7
|
||||
|
||||
private:
|
||||
virtual ~LLExperienceCache();
|
||||
|
||||
void initSingleton() override;
|
||||
|
||||
// Callback types for get()
|
||||
typedef boost::signals2::signal < void(const LLSD &) > callback_signal_t;
|
||||
typedef boost::shared_ptr<callback_signal_t> signal_ptr;
|
||||
// May have multiple callbacks for a single ID, which are
|
||||
// represented as multiple slots bound to the signal.
|
||||
// Avoid copying signals via pointers.
|
||||
typedef std::map<LLUUID, signal_ptr> signal_map_t;
|
||||
typedef std::map<LLUUID, LLSD> cache_t;
|
||||
|
||||
typedef uuid_set_t RequestQueue_t;
|
||||
typedef std::map<LLUUID, F64> PendingQueue_t;
|
||||
|
||||
//--------------------------------------------
|
||||
static const std::string PRIVATE_KEY; // "private_id"
|
||||
|
||||
// default values
|
||||
static const F64 DEFAULT_EXPIRATION; // 600.0
|
||||
static const S32 DEFAULT_QUOTA; // 128 this is megabytes
|
||||
static const int SEARCH_PAGE_SIZE;
|
||||
|
||||
//--------------------------------------------
|
||||
void processExperience(const LLUUID& public_key, const LLSD& experience);
|
||||
|
||||
//--------------------------------------------
|
||||
cache_t mCache;
|
||||
signal_map_t mSignalMap;
|
||||
RequestQueue_t mRequestQueue;
|
||||
PendingQueue_t mPendingQueue;
|
||||
|
||||
LLFrameTimer mEraseExpiredTimer; // Periodically clean out expired entries from the cache
|
||||
CapabilityQuery_t mCapability;
|
||||
std::string mCacheFileName;
|
||||
bool mShutdown;
|
||||
|
||||
void eraseExpired();
|
||||
void requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t);
|
||||
void requestExperiences();
|
||||
|
||||
void fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
|
||||
void findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
|
||||
void getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
|
||||
void regionExperiences(CapabilityQuery_t regioncaps, const LLSD& experiences, bool update, ExperienceGetFn_t fn);
|
||||
void regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
|
||||
void experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
|
||||
|
||||
void bootstrap(const LLSD& legacyKeys, int initialExpiration);
|
||||
void exportFile(std::ostream& ostr) const;
|
||||
void importFile(std::istream& istr);
|
||||
|
||||
//
|
||||
const cache_t& getCached();
|
||||
|
||||
// maps an experience private key to the experience id
|
||||
LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false);
|
||||
|
||||
//=====================================================================
|
||||
inline friend std::ostream &operator << (std::ostream &os, const LLExperienceCache &cache)
|
||||
{
|
||||
cache.exportFile(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline friend std::istream &operator >> (std::istream &is, LLExperienceCache &cache)
|
||||
{
|
||||
cache.importFile(is);
|
||||
return is;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // LL_LLEXPERIENCECACHE_H
|
||||
@@ -168,19 +168,20 @@ const U32 ESTATE_ACCESS_ALL = ESTATE_ACCESS_ALLOWED_AGENTS
|
||||
| ESTATE_ACCESS_BANNED_AGENTS
|
||||
| ESTATE_ACCESS_MANAGERS;
|
||||
|
||||
// for EstateOwnerRequest, estateaccessdelta message
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1 << 0;
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1 << 1;
|
||||
// for EstateOwnerRequest, estateaccessdelta, estateexperiencedelta messages
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1U << 0;
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1U << 1;
|
||||
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1 << 2;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1 << 3;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1 << 4;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1 << 5;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1 << 6;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1 << 7;
|
||||
const U32 ESTATE_ACCESS_MANAGER_ADD = 1 << 8;
|
||||
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1 << 9;
|
||||
const U32 ESTATE_ACCESS_NO_REPLY = 1 << 10;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1U << 2;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1U << 3;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1U << 4;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1U << 5;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1U << 6;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1U << 7;
|
||||
const U32 ESTATE_ACCESS_MANAGER_ADD = 1U << 8;
|
||||
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9;
|
||||
const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10;
|
||||
const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11;
|
||||
|
||||
const S32 ESTATE_MAX_MANAGERS = 15;
|
||||
const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access, banned
|
||||
@@ -191,6 +192,26 @@ const U32 SWD_OTHERS_LAND_ONLY = (1 << 0);
|
||||
const U32 SWD_ALWAYS_RETURN_OBJECTS = (1 << 1);
|
||||
const U32 SWD_SCRIPTED_ONLY = (1 << 2);
|
||||
|
||||
// Controls experience key validity in the estate
|
||||
const U32 EXPERIENCE_KEY_TYPE_NONE = 0;
|
||||
const U32 EXPERIENCE_KEY_TYPE_BLOCKED = 1;
|
||||
const U32 EXPERIENCE_KEY_TYPE_ALLOWED = 2;
|
||||
const U32 EXPERIENCE_KEY_TYPE_TRUSTED = 3;
|
||||
|
||||
const U32 EXPERIENCE_KEY_TYPE_FIRST = EXPERIENCE_KEY_TYPE_BLOCKED;
|
||||
const U32 EXPERIENCE_KEY_TYPE_LAST = EXPERIENCE_KEY_TYPE_TRUSTED;
|
||||
|
||||
//
|
||||
const U32 ESTATE_EXPERIENCE_TRUSTED_ADD = 1U << 2;
|
||||
const U32 ESTATE_EXPERIENCE_TRUSTED_REMOVE = 1U << 3;
|
||||
const U32 ESTATE_EXPERIENCE_ALLOWED_ADD = 1U << 4;
|
||||
const U32 ESTATE_EXPERIENCE_ALLOWED_REMOVE = 1U << 5;
|
||||
const U32 ESTATE_EXPERIENCE_BLOCKED_ADD = 1U << 6;
|
||||
const U32 ESTATE_EXPERIENCE_BLOCKED_REMOVE = 1U << 7;
|
||||
|
||||
const S32 ESTATE_MAX_EXPERIENCE_IDS = 8;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1393,6 +1393,8 @@ char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance
|
||||
char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
|
||||
char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()->getString("AppearanceHover");
|
||||
char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
|
||||
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
|
||||
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX");
|
||||
|
||||
@@ -1393,6 +1393,8 @@ extern char const* const _PREHASH_AppearanceVersion;
|
||||
extern char const* const _PREHASH_CofVersion;
|
||||
extern char const* const _PREHASH_AppearanceHover;
|
||||
extern char const* const _PREHASH_HoverHeight;
|
||||
extern char const* const _PREHASH_Experience;
|
||||
extern char const* const _PREHASH_ExperienceID;
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
extern char const* const _PREHASH_RegionSizeX;
|
||||
|
||||
@@ -37,6 +37,7 @@ set(llui_SOURCE_FILES
|
||||
lldraghandle.cpp
|
||||
lleditmenuhandler.cpp
|
||||
llfiltereditor.cpp
|
||||
llflatlistview.cpp
|
||||
llfloater.cpp
|
||||
llflyoutbutton.cpp
|
||||
llfocusmgr.cpp
|
||||
@@ -116,6 +117,7 @@ set(llui_HEADER_FILES
|
||||
lldraghandle.h
|
||||
lleditmenuhandler.h
|
||||
llfiltereditor.h
|
||||
llflatlistview.h
|
||||
llfloater.h
|
||||
llflyoutbutton.h
|
||||
llfocusmgr.h
|
||||
|
||||
@@ -27,6 +27,7 @@ const std::array<const std::string, LFIDBearer::COUNT> LFIDBearer::sMenuStrings
|
||||
"menu_avs_list.xml" // 0
|
||||
, "menu_groups_list.xml" // 1
|
||||
, "menu_objects_list.xml" // 2
|
||||
, "menu_experiences.xml" // 3
|
||||
};
|
||||
std::array<LLMenuGL*, LFIDBearer::COUNT> LFIDBearer::sMenus {};
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ struct LFIDBearer
|
||||
AVATAR = 0,
|
||||
GROUP,
|
||||
OBJECT,
|
||||
EXPERIENCE,
|
||||
COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -446,8 +446,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
|
||||
|
||||
if (!mAllowTextEntry)
|
||||
{
|
||||
mButton->setLabelUnselected(name);
|
||||
mButton->setLabelSelected(name);
|
||||
mButton->setLabel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,9 +464,7 @@ void LLComboBox::updateLabel()
|
||||
// the combo button label.
|
||||
if (!mAllowTextEntry)
|
||||
{
|
||||
std::string label = getSelectedItemLabel();
|
||||
mButton->setLabelUnselected(label);
|
||||
mButton->setLabelSelected(label);
|
||||
mButton->setLabel(getSelectedItemLabel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,13 +510,16 @@ void LLComboBox::onFocusLost()
|
||||
|
||||
void LLComboBox::setButtonVisible(BOOL visible)
|
||||
{
|
||||
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
|
||||
|
||||
mButton->setVisible(visible);
|
||||
if (mTextEntry)
|
||||
{
|
||||
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
if (visible)
|
||||
{
|
||||
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
|
||||
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
|
||||
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
|
||||
}
|
||||
//mTextEntry->setRect(text_entry_rect);
|
||||
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
|
||||
@@ -558,18 +558,21 @@ S32 LLComboBox::getCurrentIndex() const
|
||||
|
||||
void LLComboBox::updateLayout()
|
||||
{
|
||||
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
|
||||
LLRect rect = getLocalRect();
|
||||
if (mAllowTextEntry)
|
||||
{
|
||||
S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton");
|
||||
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size,
|
||||
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
|
||||
S32 shadow_size = drop_shadow_button;
|
||||
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,
|
||||
rect.mTop, rect.mRight, rect.mBottom));
|
||||
mButton->setTabStop(FALSE);
|
||||
mButton->setHAlign(LLFontGL::HCENTER);
|
||||
|
||||
if (!mTextEntry)
|
||||
{
|
||||
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * shadow_size;
|
||||
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
|
||||
// clear label on button
|
||||
std::string cur_label = mButton->getLabelSelected();
|
||||
mTextEntry = new LLLineEditor(std::string("combo_text_entry"),
|
||||
@@ -718,6 +721,7 @@ void LLComboBox::showList()
|
||||
mList->setVisible(TRUE);
|
||||
|
||||
setUseBoundingRect(TRUE);
|
||||
// updateBoundingRect();
|
||||
}
|
||||
|
||||
void LLComboBox::hideList()
|
||||
@@ -744,6 +748,7 @@ void LLComboBox::hideList()
|
||||
{
|
||||
gFocusMgr.setTopCtrl(NULL);
|
||||
}
|
||||
// updateBoundingRect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,9 +1034,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
|
||||
|
||||
void LLComboBox::updateSelection()
|
||||
{
|
||||
if(mSuppressAutoComplete) {
|
||||
return;
|
||||
}
|
||||
if(mSuppressAutoComplete) return;
|
||||
|
||||
LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor());
|
||||
// user-entered portion of string, based on assumption that any selected
|
||||
@@ -1242,3 +1245,25 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
|
||||
return mList->selectItemRange(first, last);
|
||||
}
|
||||
|
||||
|
||||
/* Singu Note: This isn't very necessary for now, let's not bother.
|
||||
static LLRegisterWidget<LLIconsComboBox> register_icons_combo_box("icons_combo_box");
|
||||
|
||||
LLIconsComboBox::Params::Params()
|
||||
: icon_column("icon_column", ICON_COLUMN),
|
||||
label_column("label_column", LABEL_COLUMN)
|
||||
{}
|
||||
|
||||
LLIconsComboBox::LLIconsComboBox(const LLIconsComboBox::Params& p)
|
||||
: LLComboBox(p),
|
||||
mIconColumnIndex(p.icon_column),
|
||||
mLabelColumnIndex(p.label_column)
|
||||
{}
|
||||
|
||||
const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const
|
||||
{
|
||||
mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
|
||||
|
||||
return LLComboBox::getSelectedItemLabel(mLabelColumnIndex);
|
||||
}
|
||||
*/
|
||||
|
||||
1464
indra/llui/llflatlistview.cpp
Normal file
1464
indra/llui/llflatlistview.cpp
Normal file
File diff suppressed because it is too large
Load Diff
540
indra/llui/llflatlistview.h
Normal file
540
indra/llui/llflatlistview.h
Normal file
@@ -0,0 +1,540 @@
|
||||
/**
|
||||
* @file llflatlistview.h
|
||||
* @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&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_LLFLATLISTVIEW_H
|
||||
#define LL_LLFLATLISTVIEW_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
|
||||
/**
|
||||
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
|
||||
* LLSD can be associated with each added item, it can keep data from an item in digested form.
|
||||
* Associated LLSD's can be of any type (singular, a map etc.).
|
||||
* Items (LLPanel's subclasses) can be of different height.
|
||||
* The list is LLPanel created in itself and grows in height while new items are added.
|
||||
*
|
||||
* The control can manage selection of its items when the flag "allow_select" is set. Also ability to select
|
||||
* multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag
|
||||
* is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
|
||||
* since any item of the list was selected.
|
||||
*
|
||||
* Examples of using this control are presented in Picks panel (My Profile and Profile View), where this control is used to
|
||||
* manage the list of pick items.
|
||||
*
|
||||
* ASSUMPTIONS AND STUFF
|
||||
* - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise
|
||||
* - Order of returned selected items are not guaranteed
|
||||
* - The control assumes that all items being added are unique.
|
||||
*/
|
||||
class LLFlatListView : public LLScrollContainer, public LLEditMenuHandler
|
||||
{
|
||||
LOG_CLASS(LLFlatListView);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Abstract comparator for comparing flat list items in a form of LLPanel
|
||||
*/
|
||||
class ItemComparator
|
||||
{
|
||||
public:
|
||||
ItemComparator() {};
|
||||
virtual ~ItemComparator() {};
|
||||
|
||||
/** Returns true if item1 < item2, false otherwise */
|
||||
virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents reverse comparator which acts as a decorator for a comparator that need to be reversed
|
||||
*/
|
||||
class ItemReverseComparator : public ItemComparator
|
||||
{
|
||||
public:
|
||||
ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {};
|
||||
virtual ~ItemReverseComparator() {};
|
||||
|
||||
bool compare(const LLPanel* item1, const LLPanel* item2) const override
|
||||
{
|
||||
return mComparator.compare(item2, item1);
|
||||
}
|
||||
|
||||
private:
|
||||
const ItemComparator& mComparator;
|
||||
};
|
||||
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
|
||||
{
|
||||
/** turning on/off selection support */
|
||||
Optional<bool> allow_select;
|
||||
|
||||
/** turning on/off multiple selection (works while clicking and holding CTRL)*/
|
||||
Optional<bool> multi_select;
|
||||
|
||||
/** don't allow to deselect all selected items (for mouse events on items only) */
|
||||
Optional<bool> keep_one_selected;
|
||||
|
||||
/** try to keep selection visible after reshape */
|
||||
Optional<bool> keep_selection_visible_on_reshape;
|
||||
|
||||
/** padding between items */
|
||||
Optional<U32> item_pad;
|
||||
|
||||
/** textbox with info message when list is empty*/
|
||||
Optional<LLTextBox::Params> no_items_text;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
// disable traversal when finding widget to hand focus off to
|
||||
/*virtual*/ BOOL canFocusChildren() const override { return FALSE; }
|
||||
|
||||
/**
|
||||
* Connects callback to signal called when Return key is pressed.
|
||||
*/
|
||||
boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
|
||||
|
||||
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
|
||||
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
|
||||
|
||||
/** Returns full rect of child panel */
|
||||
const LLRect& getItemsRect() const;
|
||||
|
||||
LLRect getRequiredRect() override { return getItemsRect(); }
|
||||
|
||||
/** Returns distance between items */
|
||||
const S32 getItemsPad() const { return mItemPad; }
|
||||
|
||||
/**
|
||||
* Adds and item and LLSD value associated with it to the list at specified position
|
||||
* @return true if the item was added, false otherwise
|
||||
*/
|
||||
virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Insert item_to_add along with associated value to the list right after the after_item.
|
||||
* @return true if the item was successfully added, false otherwise
|
||||
*/
|
||||
virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null);
|
||||
|
||||
/**
|
||||
* Remove specified item
|
||||
* @return true if the item was removed, false otherwise
|
||||
*/
|
||||
virtual bool removeItem(LLPanel* item, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Remove an item specified by value
|
||||
* @return true if the item was removed, false otherwise
|
||||
*/
|
||||
virtual bool removeItemByValue(const LLSD& value, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Remove an item specified by uuid
|
||||
* @return true if the item was removed, false otherwise
|
||||
*/
|
||||
virtual bool removeItemByUUID(const LLUUID& uuid, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Get an item by value
|
||||
* @return the item as LLPanel if associated with value, NULL otherwise
|
||||
*/
|
||||
virtual LLPanel* getItemByValue(const LLSD& value) const;
|
||||
|
||||
/**
|
||||
* Check for item by value in list
|
||||
* @return bool whether item exists by value or not
|
||||
*/
|
||||
virtual bool valueExists(const LLSD& value) const;
|
||||
|
||||
template<class T>
|
||||
T* getTypedItemByValue(const LLSD& value) const
|
||||
{
|
||||
return dynamic_cast<T*>(getItemByValue(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select or deselect specified item based on select
|
||||
* @return true if succeed, false otherwise
|
||||
*/
|
||||
virtual bool selectItem(LLPanel* item, bool select = true);
|
||||
|
||||
/**
|
||||
* Select or deselect an item by associated value based on select
|
||||
* @return true if succeed, false otherwise
|
||||
*/
|
||||
virtual bool selectItemByValue(const LLSD& value, bool select = true);
|
||||
|
||||
/**
|
||||
* Select or deselect an item by associated uuid based on select
|
||||
* @return true if succeed, false otherwise
|
||||
*/
|
||||
virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true);
|
||||
|
||||
/**
|
||||
* Get all panels stored in the list.
|
||||
*/
|
||||
virtual void getItems(std::vector<LLPanel*>& items) const;
|
||||
|
||||
/**
|
||||
* Get all items values.
|
||||
*/
|
||||
virtual void getValues(std::vector<LLSD>& values) const;
|
||||
|
||||
/**
|
||||
* Get LLSD associated with the first selected item
|
||||
*/
|
||||
virtual LLSD getSelectedValue() const;
|
||||
|
||||
/**
|
||||
* Get LLSD's associated with selected items.
|
||||
* @param selected_values std::vector being populated with LLSD associated with selected items
|
||||
*/
|
||||
virtual void getSelectedValues(std::vector<LLSD>& selected_values) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get LLUUID associated with selected item
|
||||
* @return LLUUID if such was associated with selected item
|
||||
*/
|
||||
virtual LLUUID getSelectedUUID() const;
|
||||
|
||||
/**
|
||||
* Get LLUUIDs associated with selected items
|
||||
* @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items
|
||||
*/
|
||||
virtual void getSelectedUUIDs(uuid_vec_t& selected_uuids) const;
|
||||
|
||||
/** Get the top selected item */
|
||||
virtual LLPanel* getSelectedItem() const;
|
||||
|
||||
/**
|
||||
* Get selected items
|
||||
* @param selected_items An std::vector being populated with pointers to selected items
|
||||
*/
|
||||
virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
|
||||
|
||||
|
||||
/**
|
||||
* Resets selection of items.
|
||||
*
|
||||
* It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true"
|
||||
* argument for current Flat List.
|
||||
* @param no_commit_on_deselection - if true onCommit callback will not be called
|
||||
*/
|
||||
virtual void resetSelection(bool no_commit_on_deselection = false);
|
||||
|
||||
/**
|
||||
* Sets comment text which will be shown in the list is it is empty.
|
||||
*
|
||||
* Textbox to hold passed text is created while this method is called at the first time.
|
||||
*
|
||||
* @param comment_text - string to be shown as a comment.
|
||||
*/
|
||||
void setNoItemsCommentText( const std::string& comment_text);
|
||||
|
||||
/** Turn on/off multiple selection support */
|
||||
void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
|
||||
|
||||
/** Turn on/off selection support */
|
||||
void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
|
||||
|
||||
/** Sets flag whether onCommit should be fired if selection was changed */
|
||||
// FIXME: this should really be a separate signal, since "Commit" implies explicit user action, and selection changes can happen more indirectly.
|
||||
void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
|
||||
|
||||
/** Get number of selected items in the list */
|
||||
U32 numSelected() const {return mSelectedItemPairs.size(); }
|
||||
|
||||
/** Get number of (visible) items in the list */
|
||||
U32 size(const bool only_visible_items = true) const;
|
||||
|
||||
/** Removes all items from the list */
|
||||
void clear() override;
|
||||
|
||||
/**
|
||||
* Removes all items that can be detached from the list but doesn't destroy
|
||||
* them, caller responsible to manage items after they are detached.
|
||||
* Detachable item should accept "detach" action via notify() method,
|
||||
* where it disconnect all callbacks, does other valuable routines and
|
||||
* return 1.
|
||||
*/
|
||||
void detachItems(std::vector<LLPanel*>& detached_items);
|
||||
|
||||
/**
|
||||
* Set comparator to use for future sorts.
|
||||
*
|
||||
* This class does NOT manage lifetime of the comparator
|
||||
* but assumes that the comparator is always alive.
|
||||
*/
|
||||
void setComparator(const ItemComparator* comp) { mItemComparator = comp; }
|
||||
void sort();
|
||||
|
||||
bool updateValue(const LLSD& old_value, const LLSD& new_value);
|
||||
|
||||
void scrollToShowFirstSelectedItem();
|
||||
|
||||
void selectFirstItem ();
|
||||
void selectLastItem ();
|
||||
|
||||
S32 notify(const LLSD& info) override;
|
||||
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); // <singu> Old-style
|
||||
|
||||
virtual ~LLFlatListView();
|
||||
protected:
|
||||
|
||||
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
|
||||
typedef std::pair<LLPanel*, LLSD> item_pair_t;
|
||||
|
||||
typedef std::list<item_pair_t*> pairs_list_t;
|
||||
typedef pairs_list_t::iterator pairs_iterator_t;
|
||||
typedef pairs_list_t::const_iterator pairs_const_iterator_t;
|
||||
|
||||
/** An adapter for a ItemComparator */
|
||||
struct ComparatorAdaptor
|
||||
{
|
||||
ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {};
|
||||
|
||||
bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2) const
|
||||
{
|
||||
return mComparator.compare(item_pair1->first, item_pair2->first);
|
||||
}
|
||||
|
||||
const ItemComparator& mComparator;
|
||||
};
|
||||
|
||||
|
||||
friend class LLUICtrlFactory;
|
||||
LLFlatListView(const std::string& name, const LLRect& rect, bool opaque, const LLColor4& color, const S32& item_pad, bool allow_select, bool multi_select, bool keep_one_selected, bool keep_selection_visible_on_reshape, const std::string& no_items_text);
|
||||
|
||||
/** Manage selection on mouse events */
|
||||
void onItemMouseClick(item_pair_t* item_pair, MASK mask);
|
||||
|
||||
void onItemRightMouseClick(item_pair_t* item_pair, MASK mask);
|
||||
|
||||
/**
|
||||
* Updates position of items.
|
||||
* It does not take into account invisible items.
|
||||
*/
|
||||
virtual void rearrangeItems();
|
||||
|
||||
virtual item_pair_t* getItemPair(LLPanel* item) const;
|
||||
|
||||
virtual item_pair_t* getItemPair(const LLSD& value) const;
|
||||
|
||||
virtual bool selectItemPair(item_pair_t* item_pair, bool select);
|
||||
|
||||
virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
|
||||
|
||||
BOOL canSelectAll() const override;
|
||||
void selectAll() override;
|
||||
|
||||
virtual bool isSelected(item_pair_t* item_pair) const;
|
||||
|
||||
virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange);
|
||||
|
||||
bool addItemPairs(pairs_list_t panel_list, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Notify parent about changed size of internal controls with "size_changes" action
|
||||
*
|
||||
* Size includes Items Rect width and either Items Rect height or comment text height.
|
||||
* Comment text height is included if comment text is set and visible.
|
||||
* List border size is also included into notified size.
|
||||
*/
|
||||
void notifyParentItemsRectChanged();
|
||||
|
||||
BOOL handleKeyHere(KEY key, MASK mask) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onFocusReceived() override;
|
||||
|
||||
void onFocusLost() override;
|
||||
|
||||
void draw() override;
|
||||
|
||||
LLRect getLastSelectedItemRect();
|
||||
|
||||
void ensureSelectedVisible();
|
||||
|
||||
private:
|
||||
|
||||
void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
|
||||
|
||||
void setNoItemsCommentVisible(bool visible) const;
|
||||
|
||||
protected:
|
||||
|
||||
/** Comparator to use when sorting the list. */
|
||||
const ItemComparator* mItemComparator;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
LLPanel* mItemsPanel;
|
||||
|
||||
S32 mItemsNoScrollWidth;
|
||||
|
||||
S32 mBorderThickness;
|
||||
|
||||
/** Items padding */
|
||||
S32 mItemPad;
|
||||
|
||||
/** Selection support flag */
|
||||
bool mAllowSelection;
|
||||
|
||||
/** Multiselection support flag, ignored if selection is not supported */
|
||||
bool mMultipleSelection;
|
||||
|
||||
/**
|
||||
* Flag specified whether onCommit be called if selection is changed in the list.
|
||||
*
|
||||
* Can be ignored in the resetSelection() method.
|
||||
* @see resetSelection()
|
||||
*/
|
||||
bool mCommitOnSelectionChange;
|
||||
|
||||
bool mKeepOneItemSelected;
|
||||
|
||||
bool mIsConsecutiveSelection;
|
||||
|
||||
bool mKeepSelectionVisibleOnReshape;
|
||||
|
||||
/** All pairs of the list */
|
||||
pairs_list_t mItemPairs;
|
||||
|
||||
/** Selected pairs for faster access */
|
||||
pairs_list_t mSelectedItemPairs;
|
||||
|
||||
/**
|
||||
* Rectangle contained previous size of items parent notified last time.
|
||||
* Is used to reduce amount of parentNotify() calls if size was not changed.
|
||||
*/
|
||||
LLRect mPrevNotifyParentRect;
|
||||
|
||||
LLTextBox* mNoItemsCommentTextbox;
|
||||
|
||||
LLViewBorder* mSelectedItemsBorder;
|
||||
|
||||
commit_signal_t mOnReturnSignal;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends LLFlatListView functionality to show different messages when there are no items in the
|
||||
* list depend on whether they are filtered or not.
|
||||
*
|
||||
* Class provides one message per case of empty list.
|
||||
* It also provides protected updateNoItemsMessage() method to be called each time when derived list
|
||||
* is changed to update base mNoItemsCommentTextbox value.
|
||||
*
|
||||
* It is implemented to avoid duplication of this functionality in concrete implementations of the
|
||||
* lists. It is intended to be used as a base class for lists which should support two different
|
||||
* messages for empty state. Can be improved to support more than two messages via state-to-message map.
|
||||
*/
|
||||
class LLFlatListViewEx : public LLFlatListView
|
||||
{
|
||||
public:
|
||||
LOG_CLASS(LLFlatListViewEx);
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
|
||||
{
|
||||
/**
|
||||
* Contains a message for empty list when it does not contain any items at all.
|
||||
*/
|
||||
Optional<std::string> no_items_msg;
|
||||
|
||||
/**
|
||||
* Contains a message for empty list when its items are removed by filtering.
|
||||
*/
|
||||
Optional<std::string> no_filtered_items_msg;
|
||||
Params();
|
||||
};
|
||||
|
||||
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
|
||||
// no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931
|
||||
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
|
||||
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
|
||||
|
||||
bool getForceShowingUnmatchedItems();
|
||||
|
||||
void setForceShowingUnmatchedItems(bool show);
|
||||
|
||||
/**
|
||||
* Sets up new filter string and filters the list.
|
||||
*/
|
||||
void setFilterSubString(const std::string& filter_str);
|
||||
std::string getFilterSubString() const { return mFilterSubString; }
|
||||
|
||||
/**
|
||||
* Filters the list, rearranges and notifies parent about shape changes.
|
||||
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
|
||||
*/
|
||||
void filterItems();
|
||||
|
||||
/**
|
||||
* Returns true if last call of filterItems() found at least one matching item
|
||||
*/
|
||||
bool hasMatchedItems();
|
||||
|
||||
protected:
|
||||
LLFlatListViewEx(const Params& p);
|
||||
|
||||
/**
|
||||
* Applies a message for empty list depend on passed argument.
|
||||
*
|
||||
* @param filter_string - if is not empty, message for filtered items will be set, otherwise for
|
||||
* completely empty list. Value of filter string will be passed as search_term in SLURL.
|
||||
*/
|
||||
void updateNoItemsMessage(const std::string& filter_string);
|
||||
|
||||
/**
|
||||
* Applies visibility acording to action and LLFlatListView settings.
|
||||
*
|
||||
* @param item - item we are changing
|
||||
* @param item - action - parameters to determin visibility from
|
||||
*/
|
||||
void updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
|
||||
private:
|
||||
std::string mNoFilteredItemsMsg;
|
||||
std::string mNoItemsMsg;
|
||||
std::string mFilterSubString;
|
||||
/**
|
||||
* Show list items that don't match current filter
|
||||
*/
|
||||
bool mForceShowingUnmatchedItems;
|
||||
/**
|
||||
* True if last call of filterItems() found at least one matching item
|
||||
*/
|
||||
bool mHasMatchedItems;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llscrollbar.cpp
|
||||
* @brief Scrollbar UI widget
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* 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.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -46,6 +40,7 @@
|
||||
#include "llwindow.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llrender.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
LLScrollbar::LLScrollbar(
|
||||
const std::string& name, LLRect rect,
|
||||
@@ -402,7 +397,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
|
||||
}
|
||||
|
||||
getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
|
||||
handled = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -414,7 +409,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
|
||||
if( !handled )
|
||||
{
|
||||
getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
|
||||
handled = TRUE;
|
||||
}
|
||||
|
||||
@@ -468,6 +463,13 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
return handled;
|
||||
}
|
||||
|
||||
BOOL LLScrollbar::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// just treat a double click as a second click
|
||||
return handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
|
||||
void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
if (width == getRect().getWidth() && height == getRect().getHeight()) return;
|
||||
@@ -509,7 +511,6 @@ void LLScrollbar::draw()
|
||||
mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));
|
||||
}
|
||||
|
||||
|
||||
// Draw background and thumb.
|
||||
LLUIImage* rounded_rect_imagep = LLUI::getUIImage("Rounded_Square");
|
||||
|
||||
@@ -525,6 +526,9 @@ void LLScrollbar::draw()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thumb
|
||||
LLRect outline_rect = mThumbRect;
|
||||
outline_rect.stretch(2);
|
||||
// Background
|
||||
rounded_rect_imagep->drawSolid(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
|
||||
mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0,
|
||||
@@ -532,9 +536,6 @@ void LLScrollbar::draw()
|
||||
mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
|
||||
mTrackColor);
|
||||
|
||||
// Thumb
|
||||
LLRect outline_rect = mThumbRect;
|
||||
outline_rect.stretch(2);
|
||||
|
||||
if (gFocusMgr.getKeyboardFocus() == this)
|
||||
{
|
||||
@@ -636,3 +637,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
|
||||
{
|
||||
changeLine( mStepSize, TRUE );
|
||||
}
|
||||
|
||||
void LLScrollbar::setThickness(S32 thickness)
|
||||
{
|
||||
mThickness = thickness < 0 ? SCROLLBAR_SIZE : thickness;
|
||||
}
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llscrollbar.h
|
||||
* @brief Scrollbar UI widget
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -36,6 +30,7 @@
|
||||
#include "stdtypes.h"
|
||||
#include "lluictrl.h"
|
||||
#include "v4color.h"
|
||||
#include "llbutton.h"
|
||||
|
||||
//
|
||||
// Constants
|
||||
@@ -59,6 +54,7 @@ public:
|
||||
callback_t change_callback,
|
||||
S32 step_size = 1);
|
||||
|
||||
public:
|
||||
virtual ~LLScrollbar();
|
||||
|
||||
virtual void setValue(const LLSD& value);
|
||||
@@ -67,6 +63,7 @@ public:
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
@@ -104,6 +101,9 @@ public:
|
||||
void onLineUpBtnPressed(const LLSD& data);
|
||||
void onLineDownBtnPressed(const LLSD& data);
|
||||
|
||||
S32 getThickness() const { return mThickness; }
|
||||
void setThickness(S32 thickness);
|
||||
|
||||
void setTrackColor( const LLColor4& color ) { mTrackColor = color; }
|
||||
void setThumbColor( const LLColor4& color ) { mThumbColor = color; }
|
||||
void setHighlightColor( const LLColor4& color ) { mHighlightColor = color; }
|
||||
@@ -145,5 +145,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // LL_SCROLLBAR_H
|
||||
|
||||
@@ -218,6 +218,15 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLScrollContainer::handleUnicodeCharHere(llwchar uni_char)
|
||||
{
|
||||
if (mScrolledView && mScrolledView->handleUnicodeCharHere(uni_char))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
||||
{
|
||||
// Give event to my child views - they may have scroll bars
|
||||
@@ -262,7 +271,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
//S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
// Scroll folder view if needed. Never accepts a drag or drop.
|
||||
*accept = ACCEPT_NO;
|
||||
BOOL handled = autoScroll(x, y);
|
||||
@@ -413,6 +421,7 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLScrollContainer::draw()
|
||||
{
|
||||
S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
@@ -525,7 +534,7 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
|
||||
|
||||
void LLScrollContainer::updateScroll()
|
||||
{
|
||||
if (!mScrolledView)
|
||||
if (!getVisible() || !mScrolledView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -626,6 +635,7 @@ LLRect LLScrollContainer::getVisibleContentRect()
|
||||
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
|
||||
return visible_rect;
|
||||
}
|
||||
|
||||
LLRect LLScrollContainer::getContentWindowRect()
|
||||
{
|
||||
updateScroll();
|
||||
@@ -729,6 +739,13 @@ S32 LLScrollContainer::getBorderWidth() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LLScrollContainer::setSize(S32 size)
|
||||
{
|
||||
mSize = size;
|
||||
mScrollbar[VERTICAL]->setThickness(size);
|
||||
mScrollbar[HORIZONTAL]->setThickness(size);
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLScrollContainer::getXML(bool save_children) const
|
||||
{
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llscrollcontainer.h
|
||||
* @brief LLScrollContainer class header file.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -78,7 +72,7 @@ public:
|
||||
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
|
||||
LLRect getVisibleContentRect();
|
||||
LLRect getContentWindowRect();
|
||||
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
|
||||
virtual const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
|
||||
void pageUp(S32 overlap = 0);
|
||||
void pageDown(S32 overlap = 0);
|
||||
void goToTop();
|
||||
@@ -90,6 +84,7 @@ public:
|
||||
// LLView functionality
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
@@ -105,9 +100,14 @@ public:
|
||||
virtual LLXMLNodePtr getXML(bool save_children) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
S32 getSize() const { return mSize; }
|
||||
void setSize(S32 thickness);
|
||||
|
||||
protected:
|
||||
LLView* mScrolledView;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
// internal scrollbar handlers
|
||||
virtual void scrollHorizontal( S32 new_pos );
|
||||
virtual void scrollVertical( S32 new_pos );
|
||||
@@ -117,7 +117,6 @@ public:
|
||||
private:
|
||||
|
||||
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
|
||||
LLView* mScrolledView;
|
||||
S32 mSize;
|
||||
BOOL mIsOpaque;
|
||||
LLColor4 mBackgroundColor;
|
||||
|
||||
@@ -1896,3 +1896,8 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y)
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLTabContainer::getTotalTabWidth() const
|
||||
{
|
||||
return mTotalTabWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
S32 getIndexForPanel(LLPanel* panel);
|
||||
S32 getPanelIndexByTitle(const std::string& title);
|
||||
LLPanel* getPanelByName(const std::string& name);
|
||||
S32 getTotalTabWidth() const;
|
||||
void setCurrentTabName(const std::string& name);
|
||||
|
||||
void selectFirstTab();
|
||||
|
||||
@@ -387,6 +387,7 @@ static LFIDBearer::Type get_type_from_url(const std::string& url)
|
||||
auto type = url.substr(pos + 5, 5);
|
||||
return type == "agent" ? LFIDBearer::AVATAR
|
||||
: type == "group" ? LFIDBearer::GROUP
|
||||
: type == "experience" ? LFIDBearer::EXPERIENCE
|
||||
: LFIDBearer::OBJECT;
|
||||
}
|
||||
return LFIDBearer::NONE;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "lltrans.h"
|
||||
//#include "lluicolortable.h"
|
||||
#include "message.h"
|
||||
#include "llexperiencecache.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/format.hpp> // <alchemy/>
|
||||
@@ -1492,6 +1493,58 @@ std::string LLUrlEntryEmail::getUrl(const std::string &string) const
|
||||
return escapeUrl(string);
|
||||
}
|
||||
|
||||
LLUrlEntryExperienceProfile::LLUrlEntryExperienceProfile()
|
||||
{
|
||||
mPattern = boost::regex(APP_HEADER_REGEX "/experience/[\\da-f-]+/\\w+\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mIcon = "Generic_Experience";
|
||||
mMenuName = "menu_url_experience.xml";
|
||||
}
|
||||
|
||||
std::string LLUrlEntryExperienceProfile::getLabel(const std::string& url, const LLUrlLabelCallback& cb)
|
||||
{
|
||||
if (!gCacheName)
|
||||
{
|
||||
// probably at the login screen, use short string for layout
|
||||
return LLTrans::getString("LoadingData");
|
||||
}
|
||||
|
||||
std::string experience_id_string = getIDStringFromUrl(url);
|
||||
if (experience_id_string.empty())
|
||||
{
|
||||
// something went wrong, just give raw url
|
||||
return unescapeUrl(url);
|
||||
}
|
||||
|
||||
LLUUID experience_id(experience_id_string);
|
||||
if (experience_id.isNull())
|
||||
{
|
||||
return LLTrans::getString("ExperienceNameNull");
|
||||
}
|
||||
|
||||
const LLSD& experience_details = LLExperienceCache::instance().get(experience_id);
|
||||
if (!experience_details.isUndefined())
|
||||
{
|
||||
std::string experience_name_string = experience_details[LLExperienceCache::NAME].asString();
|
||||
return experience_name_string.empty() ? LLTrans::getString("ExperienceNameUntitled") : experience_name_string;
|
||||
}
|
||||
|
||||
addObserver(experience_id_string, url, cb);
|
||||
LLExperienceCache::instance().get(experience_id, boost::bind(&LLUrlEntryExperienceProfile::onExperienceDetails, this, _1));
|
||||
return LLTrans::getString("LoadingData");
|
||||
|
||||
}
|
||||
|
||||
void LLUrlEntryExperienceProfile::onExperienceDetails(const LLSD& experience_details)
|
||||
{
|
||||
std::string name = experience_details[LLExperienceCache::NAME].asString();
|
||||
if(name.empty())
|
||||
{
|
||||
name = LLTrans::getString("ExperienceNameUntitled");
|
||||
}
|
||||
callObservers(experience_details[LLExperienceCache::EXPERIENCE_ID].asString(), name, LLStringUtil::null);
|
||||
}
|
||||
|
||||
// <alchemy>
|
||||
//
|
||||
// LLUrlEntryJIRA describes a Jira Issue Tracker entry
|
||||
|
||||
@@ -323,6 +323,20 @@ private:
|
||||
/*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryExperienceProfile Describes a Second Life experience profile Url, e.g.,
|
||||
/// secondlife:///app/experience/0e346d8b-4433-4d66-a6b0-fd37083abc4c/profile
|
||||
/// that displays the experience namethat displays the experience name
|
||||
class LLUrlEntryExperienceProfile : public LLUrlEntryBase
|
||||
{
|
||||
public:
|
||||
LLUrlEntryExperienceProfile();
|
||||
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
|
||||
private:
|
||||
void onExperienceDetails(const LLSD& experience_details);
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
|
||||
/// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
|
||||
|
||||
@@ -73,6 +73,7 @@ LLUrlRegistry::LLUrlRegistry()
|
||||
registerUrl(new LLUrlEntryObjectIM());
|
||||
registerUrl(new LLUrlEntryPlace());
|
||||
registerUrl(new LLUrlEntryInventory());
|
||||
registerUrl(new LLUrlEntryExperienceProfile());
|
||||
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
|
||||
//so it should be registered in the end of list
|
||||
registerUrl(new LLUrlEntrySL());
|
||||
|
||||
@@ -355,6 +355,10 @@ typedef enum e_lscript_state_event_type
|
||||
LSTT_REMOTE_DATA,
|
||||
LSTT_HTTP_RESPONSE,
|
||||
LSTT_HTTP_REQUEST,
|
||||
LSTT_EXPERMISSIONS,
|
||||
LSTT_TRANSACTION_RESULT,
|
||||
LSTT_PATH_UPDATE,
|
||||
LSTT_EXPERMISSIONS_DENIED,
|
||||
LSTT_EOF,
|
||||
|
||||
LSTT_STATE_BEGIN = LSTT_STATE_ENTRY,
|
||||
@@ -397,7 +401,11 @@ const U64 LSCRIPTStateBitField[LSTT_EOF] =
|
||||
0x0000000040000000, // LSTT_OBJECT_REZ
|
||||
0x0000000080000000, // LSTT_REMOTE_DATA
|
||||
0x0000000100000000LL, // LSTT_HTTP_RESPOSE
|
||||
0x0000000200000000LL // LSTT_HTTP_REQUEST
|
||||
0x0000000200000000LL, // LSTT_HTTP_REQUEST
|
||||
0x0000000400000000LL, // LSTT_EXPERMISSIONS
|
||||
0x0000000800000000LL, // LSTT_TRANSACTION_RESULT
|
||||
0x0000001000000000LL, // LSTT_PATH_UPDATE
|
||||
0x0000002000000000LL, //LSTT_EXPERMISSIONS_DENIED
|
||||
};
|
||||
|
||||
inline S32 get_event_handler_jump_position(U64 bit_field, LSCRIPTStateEventType type)
|
||||
@@ -511,6 +519,7 @@ typedef enum e_lscript_runtime_faults
|
||||
LSRF_TOO_MANY_LISTENS,
|
||||
LSRF_NESTING_LISTS,
|
||||
LSRF_CLI,
|
||||
LSRF_INVALID_STATE,
|
||||
LSRF_EOF
|
||||
} LSCRIPTRunTimeFaults;
|
||||
|
||||
@@ -551,10 +560,10 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =
|
||||
(0x1 << 10),// SCRIPT_PERMISSION_TRACK_CAMERA
|
||||
(0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA
|
||||
(0x1 << 12),// SCRIPT_PERMISSION_TELEPORT
|
||||
(0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE,
|
||||
(0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT,
|
||||
(0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS,
|
||||
(0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS,
|
||||
(0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE
|
||||
(0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT
|
||||
(0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS
|
||||
(0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS
|
||||
};
|
||||
|
||||
// http_request string constants
|
||||
|
||||
@@ -685,6 +685,23 @@ void parse_string();
|
||||
"STATUS_INTERNAL_ERROR" { count(); yylval.ival = LSL_STATUS_INTERNAL_ERROR; return(INTEGER_CONSTANT); }
|
||||
"STATUS_WHITELIST_FAILED" { count(); yylval.ival = LSL_STATUS_WHITELIST_FAILED; return(INTEGER_CONSTANT); }
|
||||
|
||||
"XP_ERROR_NONE" { const char* sval= "no error"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_THROTTLED" { const char* sval= "exceeded throttle"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_EXPERIENCES_DISABLED" { const char* sval= "experiences are disabled"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_INVALID_PARAMETERS" { const char* sval= "invalid parameters"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_NOT_PERMITTED" { const char* sval= "operation not permitted"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_NO_EXPERIENCE" { const char* sval= "script not associated with an experience";yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_NOT_FOUND" { const char* sval= "not found"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_INVALID_EXPERIENCE" { const char* sval= "invalid experience"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_EXPERIENCE_DISABLED" { const char* sval= "experience is disabled"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_EXPERIENCE_SUSPENDED" { const char* sval= "experience is suspended"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_UNKNOWN_ERROR" { const char* sval= "unknown error"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_QUOTA_EXCEEDED" { const char* sval= "experience data quota exceeded"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_STORE_DISABLED" { const char* sval= "key-value store is disabled"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_STORAGE_EXCEPTION" { const char* sval= "key-value store communication failed"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_KEY_NOT_FOUND" { const char* sval= "key doesn't exist"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
"XP_ERROR_RETRY_UPDATE" { const char* sval= "retry update"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
|
||||
|
||||
"PROFILE_SCRIPT_NONE" { count(); yylval.ival = LSL_PROFILE_SCRIPT_NONE; return(INTEGER_CONSTANT); }
|
||||
"PROFILE_SCRIPT_MEMORY" { count(); yylval.ival = LSL_PROFILE_SCRIPT_MEMORY; return(INTEGER_CONSTANT); }
|
||||
|
||||
|
||||
@@ -179,6 +179,8 @@
|
||||
%type <event> money
|
||||
%type <event> email
|
||||
%type <event> run_time_permissions
|
||||
%type <event> experience_permissions
|
||||
%type <event> experience_permissions_denied
|
||||
%type <event> inventory
|
||||
%type <event> attach
|
||||
%type <event> dataserver
|
||||
@@ -787,6 +789,16 @@ event
|
||||
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
|
||||
gAllocationManager->addAllocation($$);
|
||||
}
|
||||
| experience_permissions compound_statement
|
||||
{
|
||||
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
|
||||
gAllocationManager->addAllocation($$);
|
||||
}
|
||||
| experience_permissions_denied compound_statement
|
||||
{
|
||||
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
|
||||
gAllocationManager->addAllocation($$);
|
||||
}
|
||||
| inventory compound_statement
|
||||
{
|
||||
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
|
||||
@@ -1039,6 +1051,28 @@ run_time_permissions
|
||||
}
|
||||
;
|
||||
|
||||
experience_permissions
|
||||
: EXPERIENCE_PERMISSIONS '(' LLKEY IDENTIFIER ')'
|
||||
{
|
||||
LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
|
||||
gAllocationManager->addAllocation(id1);
|
||||
$$ = new LLScriptEXPEvent(gLine, gColumn, id1);
|
||||
gAllocationManager->addAllocation($$);
|
||||
}
|
||||
;
|
||||
|
||||
experience_permissions_denied
|
||||
: EXPERIENCE_PERMISSIONS_DENIED '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ')'
|
||||
{
|
||||
LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
|
||||
gAllocationManager->addAllocation(id1);
|
||||
LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
|
||||
gAllocationManager->addAllocation(id2);
|
||||
$$ = new LLScriptEXPDeniedEvent(gLine, gColumn, id1, id2);
|
||||
gAllocationManager->addAllocation($$);
|
||||
}
|
||||
;
|
||||
|
||||
inventory
|
||||
: INVENTORY '(' INTEGER IDENTIFIER ')'
|
||||
{
|
||||
|
||||
@@ -3712,6 +3712,155 @@ S32 LLScriptNoSensorEvent::getSize()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LLScriptEXPEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
|
||||
{
|
||||
if (gErrorToText.getErrors())
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch(pass)
|
||||
{
|
||||
case LSCP_PRETTY_PRINT:
|
||||
case LSCP_EMIT_ASSEMBLY:
|
||||
fdotabs(fp, tabs, tabsize);
|
||||
fprintf(fp, "experience_permissions( key ");
|
||||
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
fprintf(fp, " )\n");
|
||||
break;
|
||||
case LSCP_SCOPE_PASS1:
|
||||
checkForDuplicateHandler(fp, this, scope, "experience_permissions");
|
||||
if (scope->checkEntry(mName->mName))
|
||||
{
|
||||
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
|
||||
}
|
||||
break;
|
||||
case LSCP_RESOURCE:
|
||||
{
|
||||
// we're just tryng to determine how much space the variable needs
|
||||
if (mName->mScopeEntry)
|
||||
{
|
||||
mName->mScopeEntry->mOffset = (S32)count;
|
||||
mName->mScopeEntry->mSize = 4;
|
||||
count += mName->mScopeEntry->mSize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LSCP_EMIT_BYTE_CODE:
|
||||
{
|
||||
#ifdef LSL_INCLUDE_DEBUG_INFO
|
||||
char name[] = "experience_permissions";
|
||||
chunk->addBytes(name, strlen(name) + 1);
|
||||
chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LSCP_EMIT_CIL_ASSEMBLY:
|
||||
fdotabs(fp, tabs, tabsize);
|
||||
fprintf(fp, "experience_permissions( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
|
||||
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
fprintf(fp, " )");
|
||||
break;
|
||||
default:
|
||||
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLScriptEXPEvent::getSize()
|
||||
{
|
||||
// key = 4
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
void LLScriptEXPDeniedEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
|
||||
{
|
||||
if (gErrorToText.getErrors())
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch(pass)
|
||||
{
|
||||
case LSCP_PRETTY_PRINT:
|
||||
case LSCP_EMIT_ASSEMBLY:
|
||||
fdotabs(fp, tabs, tabsize);
|
||||
fprintf(fp, "experience_permissions_denied( key ");
|
||||
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
fprintf(fp, ", integer ");
|
||||
mReason->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
fprintf(fp, " )\n");
|
||||
break;
|
||||
case LSCP_SCOPE_PASS1:
|
||||
checkForDuplicateHandler(fp, this, scope, "experience_permissions_denied");
|
||||
if (scope->checkEntry(mName->mName))
|
||||
{
|
||||
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
|
||||
}
|
||||
if (scope->checkEntry(mReason->mName))
|
||||
{
|
||||
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
mReason->mScopeEntry = scope->addEntry(mReason->mName, LIT_VARIABLE, LST_INTEGER);
|
||||
}
|
||||
break;
|
||||
case LSCP_RESOURCE:
|
||||
{
|
||||
// we're just trying to determine how much space the variable needs
|
||||
if (mName->mScopeEntry)
|
||||
{
|
||||
mName->mScopeEntry->mOffset = (S32)count;
|
||||
mName->mScopeEntry->mSize = 4;
|
||||
count += mName->mScopeEntry->mSize;
|
||||
|
||||
mReason->mScopeEntry->mOffset = (S32)count;
|
||||
mReason->mScopeEntry->mSize = 4;
|
||||
count += mReason->mScopeEntry->mSize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LSCP_EMIT_BYTE_CODE:
|
||||
{
|
||||
#ifdef LSL_INCLUDE_DEBUG_INFO
|
||||
char name[] = "experience_permissions_denied";
|
||||
chunk->addBytes(name, strlen(name) + 1);
|
||||
chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
|
||||
chunk->addBytes(mReason->mName, strlen(mReason->mName) + 1);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LSCP_EMIT_CIL_ASSEMBLY:
|
||||
fdotabs(fp, tabs, tabsize);
|
||||
fprintf(fp, "experience_permissions_denied( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
|
||||
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
fprintf(fp, ", int32 ");
|
||||
mReason->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
fprintf(fp, " )");
|
||||
break;
|
||||
default:
|
||||
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
mReason->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLScriptEXPDeniedEvent::getSize()
|
||||
{
|
||||
// key = 4 + integer
|
||||
return LSCRIPTDataSize[LST_KEY]+LSCRIPTDataSize[LST_INTEGER];
|
||||
}
|
||||
|
||||
void LLScriptAtTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
|
||||
{
|
||||
if (gErrorToText.getErrors())
|
||||
@@ -8577,6 +8726,7 @@ void LLScriptReturn::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
|
||||
}
|
||||
}
|
||||
prunearg = TRUE;
|
||||
break;
|
||||
case LSCP_TYPE:
|
||||
// if there is a return expression, it must be promotable to the return type of the function
|
||||
if (mExpression)
|
||||
@@ -9775,7 +9925,13 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
|
||||
mScopeEntry->mFunctionArgs.addType(LST_STRING);
|
||||
mScopeEntry->mFunctionArgs.addType(LST_STRING);
|
||||
break;
|
||||
|
||||
case LSTT_EXPERMISSIONS:
|
||||
mScopeEntry->mFunctionArgs.addType(LST_KEY);
|
||||
break;
|
||||
case LSTT_EXPERMISSIONS_DENIED:
|
||||
mScopeEntry->mFunctionArgs.addType(LST_KEY);
|
||||
mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -633,6 +633,39 @@ public:
|
||||
LLScriptIdentifier *mRTPermissions;
|
||||
};
|
||||
|
||||
class LLScriptEXPEvent : public LLScriptEvent
|
||||
{
|
||||
public:
|
||||
LLScriptEXPEvent(S32 line, S32 col, LLScriptIdentifier *name)
|
||||
: LLScriptEvent(line, col, LSTT_EXPERMISSIONS), mName(name)
|
||||
{
|
||||
}
|
||||
|
||||
~LLScriptEXPEvent() {}
|
||||
|
||||
void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
|
||||
S32 getSize();
|
||||
|
||||
LLScriptIdentifier *mName;
|
||||
};
|
||||
|
||||
class LLScriptEXPDeniedEvent : public LLScriptEvent
|
||||
{
|
||||
public:
|
||||
LLScriptEXPDeniedEvent(S32 line, S32 col, LLScriptIdentifier *name, LLScriptIdentifier *reason)
|
||||
: LLScriptEvent(line, col, LSTT_EXPERMISSIONS_DENIED), mName(name), mReason(reason)
|
||||
{
|
||||
}
|
||||
|
||||
~LLScriptEXPDeniedEvent() {}
|
||||
|
||||
void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
|
||||
S32 getSize();
|
||||
|
||||
LLScriptIdentifier *mName;
|
||||
LLScriptIdentifier *mReason;
|
||||
};
|
||||
|
||||
class LLScriptChatEvent : public LLScriptEvent
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -181,6 +181,7 @@ set(viewer_SOURCE_FILES
|
||||
lleventinfo.cpp
|
||||
lleventnotifier.cpp
|
||||
lleventpoll.cpp
|
||||
llexperiencelog.cpp
|
||||
llexternaleditor.cpp
|
||||
llface.cpp
|
||||
llfasttimerview.cpp
|
||||
@@ -221,6 +222,9 @@ set(viewer_SOURCE_FILES
|
||||
llfloatereditui.cpp
|
||||
llfloaterenvsettings.cpp
|
||||
llfloaterevent.cpp
|
||||
llfloaterexperiencepicker.cpp
|
||||
llfloaterexperienceprofile.cpp
|
||||
llfloaterexperiences.cpp
|
||||
llfloaterexploreanimations.cpp
|
||||
llfloaterexploresounds.cpp
|
||||
llfloaterfeed.cpp
|
||||
@@ -382,11 +386,16 @@ set(viewer_SOURCE_FILES
|
||||
llpaneldisplay.cpp
|
||||
llpaneleditwearable.cpp
|
||||
llpanelevent.cpp
|
||||
llpanelexperiencelisteditor.cpp
|
||||
llpanelexperiencelog.cpp
|
||||
llpanelexperiencepicker.cpp
|
||||
llpanelexperiences.cpp
|
||||
llpanelface.cpp
|
||||
llpanelgeneral.cpp
|
||||
llpanelgroup.cpp
|
||||
llpanelgroupbulk.cpp
|
||||
llpanelgroupbulkban.cpp
|
||||
llpanelgroupexperiences.cpp
|
||||
llpanelgroupgeneral.cpp
|
||||
llpanelgroupinvite.cpp
|
||||
llpanelgrouplandmoney.cpp
|
||||
@@ -715,6 +724,7 @@ set(viewer_HEADER_FILES
|
||||
lleventinfo.h
|
||||
lleventnotifier.h
|
||||
lleventpoll.h
|
||||
llexperiencelog.h
|
||||
llexternaleditor.h
|
||||
llface.h
|
||||
llfasttimerview.h
|
||||
@@ -755,6 +765,9 @@ set(viewer_HEADER_FILES
|
||||
llfloatereditui.h
|
||||
llfloaterenvsettings.h
|
||||
llfloaterevent.h
|
||||
llfloaterexperiencepicker.h
|
||||
llfloaterexperienceprofile.h
|
||||
llfloaterexperiences.h
|
||||
llfloaterexploreanimations.h
|
||||
llfloaterexploresounds.h
|
||||
llfloaterfeed.h
|
||||
@@ -916,12 +929,17 @@ set(viewer_HEADER_FILES
|
||||
llpaneldisplay.h
|
||||
llpaneleditwearable.h
|
||||
llpanelevent.h
|
||||
llpanelexperiencelisteditor.h
|
||||
llpanelexperiencelog.h
|
||||
llpanelexperiencepicker.h
|
||||
llpanelexperiences.h
|
||||
llpanelface.h
|
||||
llpanelgeneral.h
|
||||
llpanelgroup.h
|
||||
llpanelgroupbulk.h
|
||||
llpanelgroupbulkban.h
|
||||
llpanelgroupbulkimpl.h
|
||||
llpanelgroupexperiences.h
|
||||
llpanelgroupgeneral.h
|
||||
llpanelgroupinvite.h
|
||||
llpanelgrouplandmoney.h
|
||||
|
||||
@@ -1052,5 +1052,28 @@
|
||||
<map/>
|
||||
<key>llGetMaxScaleFactor</key>
|
||||
<map/>
|
||||
<!-- Experience Tools new functions -->
|
||||
<key>llAgentInExperience</key>
|
||||
<map/>
|
||||
<key>llGetExperienceDetails</key>
|
||||
<map/>
|
||||
<key>llRequestExperiencePermissions</key>
|
||||
<map/>
|
||||
<key>llReadKeyValue</key>
|
||||
<map/>
|
||||
<key>llCreateKeyValue</key>
|
||||
<map/>
|
||||
<key>llUpdateKeyValue</key>
|
||||
<map/>
|
||||
<key>llDeleteKeyValue</key>
|
||||
<map/>
|
||||
<key>llDataSizeKeyValue</key>
|
||||
<map/>
|
||||
<key>llKeysKeyValue</key>
|
||||
<map/>
|
||||
<key>llKeyCountKeyValue</key>
|
||||
<map/>
|
||||
<key>llGetExperienceErrorMessage</key>
|
||||
<map/>
|
||||
</map>
|
||||
</llsd>
|
||||
|
||||
@@ -7500,6 +7500,38 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>FloaterExperienceProfileRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rectangle for experience profile floaters</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Rect</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<integer>16</integer>
|
||||
<integer>650</integer>
|
||||
<integer>600</integer>
|
||||
<integer>128</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>FloaterExperiencesRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rectangle for experiences floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Rect</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<integer>16</integer>
|
||||
<integer>650</integer>
|
||||
<integer>600</integer>
|
||||
<integer>128</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>FloaterFindRect2</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -11677,6 +11709,17 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>344</integer>
|
||||
</map>
|
||||
<key>PickerContextOpacity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Controls overall opacity of context frustrum connecting color and texture pickers with their swatches</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.34999999404</real>
|
||||
</map>
|
||||
<key>RevokePermsOnStandUp</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -565,6 +565,17 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AlchemyDisableSimCamConstraint</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Disable the push the simulator applies when camera collides with objects</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentFlyAlwaysEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -1622,6 +1633,28 @@ Changing this setting only affects new text.</string>
|
||||
<key>IsCOA</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>ToolbarVisibleExperiencePicker</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not the button for the experience picker is on the toolbar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<boolean>0</boolean>
|
||||
</map>
|
||||
<key>ToolbarVisibleExperiences</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not the button for the experiences floater is on the toolbar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<boolean>0</boolean>
|
||||
</map>
|
||||
<key>ToolbarVisibleFastTimers</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
// Linden library includes
|
||||
#include "llavatarnamecache.h"
|
||||
#include "lldiriterator.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llmemory.h"
|
||||
#include "llprimitive.h"
|
||||
@@ -4179,6 +4180,7 @@ void LLAppViewer::idle()
|
||||
// floating throughout the various object lists.
|
||||
//
|
||||
idleNameCache();
|
||||
if (gAgent.getRegion()) LLExperienceCache::instance().idleCoro();
|
||||
|
||||
gFrameStats.start(LLFrameStats::IDLE_NETWORK);
|
||||
stop_glerror();
|
||||
@@ -4843,6 +4845,12 @@ void LLAppViewer::disconnectViewer()
|
||||
}
|
||||
|
||||
saveNameCache();
|
||||
if (LLExperienceCache::instanceExists())
|
||||
{
|
||||
// TODO: LLExperienceCache::cleanup() logic should be moved to
|
||||
// cleanupSingleton().
|
||||
LLExperienceCache::instance().cleanup();
|
||||
}
|
||||
|
||||
// close inventory interface, close all windows
|
||||
LLPanelMainInventory::cleanup();
|
||||
|
||||
@@ -171,6 +171,7 @@ void LLAssetUploadQueue::request(LLAssetUploadQueueSupplier** supplier)
|
||||
body["item_id"] = data.mItemId;
|
||||
body["is_script_running"] = data.mIsRunning;
|
||||
body["target"] = data.mIsTargetMono? "mono" : "lsl2";
|
||||
body["experience"] = data.mExperienceId;
|
||||
|
||||
std::string url = "";
|
||||
LLViewerObject* object = gObjectList.findObject(data.mTaskId);
|
||||
@@ -194,7 +195,8 @@ void LLAssetUploadQueue::queue(const std::string& filename,
|
||||
const LLUUID& queue_id,
|
||||
U8* script_data,
|
||||
U32 data_size,
|
||||
std::string script_name)
|
||||
std::string script_name,
|
||||
const LLUUID& experience_id)
|
||||
{
|
||||
UploadData data;
|
||||
data.mTaskId = task_id;
|
||||
@@ -206,6 +208,7 @@ void LLAssetUploadQueue::queue(const std::string& filename,
|
||||
data.mData = script_data;
|
||||
data.mDataSize = data_size;
|
||||
data.mScriptName = script_name;
|
||||
data.mExperienceId = experience_id;
|
||||
|
||||
mQueue.push_back(data);
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ public:
|
||||
const LLUUID& queue_id,
|
||||
U8* data,
|
||||
U32 data_size,
|
||||
std::string script_name);
|
||||
std::string script_name,
|
||||
const LLUUID& experience_id);
|
||||
|
||||
bool isEmpty() const {return mQueue.empty();}
|
||||
|
||||
@@ -75,6 +76,7 @@ private:
|
||||
U8* mData;
|
||||
U32 mDataSize;
|
||||
std::string mScriptName;
|
||||
LLUUID mExperienceId;
|
||||
};
|
||||
|
||||
// Ownership of mSupplier passed to currently waiting responder
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "lltrans.h"
|
||||
|
||||
#include "llselectmgr.h"
|
||||
#include "llexperiencecache.h"
|
||||
|
||||
// *TODO: This should be separated into the script queue, and the floater views of that queue.
|
||||
// There should only be one floater class that can view any queue type
|
||||
@@ -76,12 +77,12 @@
|
||||
struct LLScriptQueueData
|
||||
{
|
||||
LLUUID mQueueID;
|
||||
std::string mScriptName;
|
||||
LLPointer<LLInventoryItem> mItemp;
|
||||
LLUUID mTaskId;
|
||||
LLUUID mItemId;
|
||||
LLScriptQueueData(const LLUUID& q_id, const std::string& name, const LLUUID& task_id, const LLUUID& item_id) :
|
||||
mQueueID(q_id), mScriptName(name), mTaskId(task_id), mItemId(item_id) {}
|
||||
|
||||
LLUUID mExperienceId;
|
||||
LLHost mHost;
|
||||
LLScriptQueueData(const LLUUID& q_id, const LLUUID& task_id, LLInventoryItem* item, const LLHost& host) :
|
||||
mQueueID(q_id), mTaskId(task_id), mItemp(item), mHost(host) {}
|
||||
};
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -220,7 +221,7 @@ BOOL LLFloaterScriptQueue::nextObject()
|
||||
LL_INFOS() << "LLFloaterScriptQueue::nextObject() - " << count
|
||||
<< " objects left to process." << LL_ENDL;
|
||||
mCurrentObjectID.setNull();
|
||||
if(count > 0)
|
||||
if (count > 0)
|
||||
{
|
||||
successful_start = popNext();
|
||||
}
|
||||
@@ -228,7 +229,7 @@ BOOL LLFloaterScriptQueue::nextObject()
|
||||
<< (successful_start ? "successful" : "unsuccessful")
|
||||
<< LL_ENDL;
|
||||
} while((mObjectIDs.size() > 0) && !successful_start);
|
||||
if(isDone() && !mDone)
|
||||
if (isDone() && !mDone)
|
||||
{
|
||||
mDone = true;
|
||||
getChild<LLScrollListCtrl>("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM);
|
||||
@@ -245,14 +246,14 @@ BOOL LLFloaterScriptQueue::popNext()
|
||||
// the inventory.
|
||||
BOOL rv = FALSE;
|
||||
S32 count = mObjectIDs.size();
|
||||
if(mCurrentObjectID.isNull() && (count > 0))
|
||||
if (mCurrentObjectID.isNull() && (count > 0))
|
||||
{
|
||||
mCurrentObjectID = mObjectIDs.at(0);
|
||||
LL_INFOS() << "LLFloaterScriptQueue::popNext() - mCurrentID: "
|
||||
<< mCurrentObjectID << LL_ENDL;
|
||||
mObjectIDs.erase(mObjectIDs.begin());
|
||||
LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
|
||||
if(obj)
|
||||
if (obj)
|
||||
{
|
||||
LL_INFOS() << "LLFloaterScriptQueue::popNext() requesting inv for "
|
||||
<< mCurrentObjectID << LL_ENDL;
|
||||
@@ -270,35 +271,21 @@ BOOL LLFloaterScriptQueue::startQueue()
|
||||
return nextObject();
|
||||
}
|
||||
|
||||
#if 0 // Singu TODO: Experiences
|
||||
class CompileQueueExperienceResponder : public LLHTTPClient::ResponderWithResult
|
||||
class CompileQueueExperienceResponder final : public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
const LLUUID mParent;
|
||||
public:
|
||||
CompileQueueExperienceResponder(const LLUUID& parent):mParent(parent)
|
||||
{
|
||||
}
|
||||
CompileQueueExperienceResponder(const LLUUID& parent): mParent(parent) {}
|
||||
|
||||
LLUUID mParent;
|
||||
|
||||
/*virtual*/ void httpSuccess()
|
||||
{
|
||||
sendResult(getContent());
|
||||
}
|
||||
/*virtual*/ void httpFailure()
|
||||
{
|
||||
sendResult(LLSD());
|
||||
}
|
||||
void httpSuccess() override { sendResult(getContent()); }
|
||||
void httpFailure() override { sendResult(LLSD()); }
|
||||
void sendResult(const LLSD& content)
|
||||
{
|
||||
LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mParent);
|
||||
if(!queue)
|
||||
return;
|
||||
|
||||
queue->experienceIdsReceived(content["experience_ids"]);
|
||||
if (auto queue = static_cast<LLFloaterCompileQueue*>(LLFloaterCompileQueue::findInstance(mParent)))
|
||||
queue->experienceIdsReceived(content["experience_ids"]);
|
||||
}
|
||||
/*virtual*/ char const* getName() const { return "RequiredRubbish"; }
|
||||
char const* getName() const override { return "CompileQueueExperienceResponder"; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -318,7 +305,7 @@ public:
|
||||
virtual LLAssetUploadQueue* get() const
|
||||
{
|
||||
LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
|
||||
if(NULL == queue)
|
||||
if (NULL == queue)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -328,7 +315,7 @@ public:
|
||||
virtual void log(std::string message) const
|
||||
{
|
||||
LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
|
||||
if(NULL == queue)
|
||||
if (NULL == queue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -363,6 +350,21 @@ LLFloaterCompileQueue::~LLFloaterCompileQueue()
|
||||
{
|
||||
}
|
||||
|
||||
void LLFloaterCompileQueue::experienceIdsReceived(const LLSD& content)
|
||||
{
|
||||
for(LLSD::array_const_iterator it = content.beginArray(); it != content.endArray(); ++it)
|
||||
{
|
||||
mExperienceIds.insert(it->asUUID());
|
||||
}
|
||||
nextObject();
|
||||
}
|
||||
|
||||
BOOL LLFloaterCompileQueue::hasExperience(const LLUUID& id) const
|
||||
{
|
||||
return mExperienceIds.find(id) != mExperienceIds.end();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
|
||||
LLInventoryObject::object_list_t* inv)
|
||||
{
|
||||
@@ -376,7 +378,7 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
|
||||
LLInventoryObject::object_list_t::const_iterator end = inv->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
{
|
||||
LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
|
||||
// Check permissions before allowing the user to retrieve data.
|
||||
@@ -397,31 +399,68 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
|
||||
}
|
||||
else
|
||||
{
|
||||
// request all of the assets.
|
||||
uuid_item_map::iterator iter;
|
||||
for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++)
|
||||
LLViewerRegion* region = viewer_object->getRegion();
|
||||
std::string url = std::string();
|
||||
if (region)
|
||||
{
|
||||
LLInventoryItem *itemp = iter->second;
|
||||
LLScriptQueueData* datap = new LLScriptQueueData(getID(),
|
||||
itemp->getName(),
|
||||
viewer_object->getID(),
|
||||
itemp->getUUID());
|
||||
url = region->getCapability("GetMetadata");
|
||||
}
|
||||
|
||||
//LL_INFOS() << "ITEM NAME 2: " << names.get(i) << LL_ENDL;
|
||||
gAssetStorage->getInvItemAsset(viewer_object->getRegion()->getHost(),
|
||||
gAgent.getID(),
|
||||
gAgent.getSessionID(),
|
||||
itemp->getPermissions().getOwner(),
|
||||
viewer_object->getID(),
|
||||
itemp->getUUID(),
|
||||
itemp->getAssetUUID(),
|
||||
itemp->getType(),
|
||||
LLFloaterCompileQueue::scriptArrived,
|
||||
(void*)datap);
|
||||
const auto& host = region->getHost();
|
||||
const auto& obj_id = viewer_object->getID();
|
||||
// request all of the assets.
|
||||
for(const auto& pair : asset_item_map)
|
||||
{
|
||||
LLInventoryItem *itemp = pair.second;
|
||||
LLScriptQueueData* datap = new LLScriptQueueData(getID(),
|
||||
obj_id,
|
||||
itemp,
|
||||
host);
|
||||
|
||||
LLExperienceCache::instance().fetchAssociatedExperience(itemp->getParentUUID(), itemp->getUUID(),
|
||||
boost::bind(LLFloaterCompileQueue::requestAsset, datap, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterCompileQueue::requestAsset(LLScriptQueueData* datap, const LLSD& experience)
|
||||
{
|
||||
LLFloaterCompileQueue* queue = static_cast<LLFloaterCompileQueue*>(findInstance(datap->mQueueID));
|
||||
if (!queue)
|
||||
{
|
||||
delete datap;
|
||||
return;
|
||||
}
|
||||
|
||||
if (experience.has(LLExperienceCache::EXPERIENCE_ID))
|
||||
{
|
||||
datap->mExperienceId = experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
|
||||
if (!queue->hasExperience(datap->mExperienceId))
|
||||
{
|
||||
std::string buffer = LLTrans::getString("CompileNoExperiencePerm", LLSD::emptyMap()
|
||||
.with("SCRIPT", datap->mItemp->getName())
|
||||
.with("EXPERIENCE", experience[LLExperienceCache::NAME].asString()));
|
||||
|
||||
queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
|
||||
queue->removeItemByItemID(datap->mItemp->getUUID());
|
||||
delete datap;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//LL_INFOS() << "ITEM NAME 2: " << names.get(i) << LL_ENDL;
|
||||
gAssetStorage->getInvItemAsset(datap->mHost,
|
||||
gAgent.getID(),
|
||||
gAgent.getSessionID(),
|
||||
datap->mItemp->getPermissions().getOwner(),
|
||||
datap->mTaskId,
|
||||
datap->mItemp->getUUID(),
|
||||
datap->mItemp->getAssetUUID(),
|
||||
datap->mItemp->getType(),
|
||||
LLFloaterCompileQueue::scriptArrived,
|
||||
(void*)datap);
|
||||
}
|
||||
|
||||
|
||||
// This is the callback for when each script arrives
|
||||
// static
|
||||
@@ -438,9 +477,9 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
|
||||
LLFloaterCompileQueue* queue = static_cast<LLFloaterCompileQueue*> (LLFloaterScriptQueue::findInstance(data->mQueueID));
|
||||
|
||||
std::string buffer;
|
||||
if(queue && (0 == status))
|
||||
if (queue && (0 == status))
|
||||
{
|
||||
//LL_INFOS() << "ITEM NAME 3: " << data->mScriptName << LL_ENDL;
|
||||
//LL_INFOS() << "ITEM NAME 3: " << data->mItemp->getName() << LL_ENDL;
|
||||
|
||||
// Dump this into a file on the local disk so we can compile it.
|
||||
std::string filename;
|
||||
@@ -454,7 +493,7 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
|
||||
if (object)
|
||||
{
|
||||
std::string url = object->getRegion()->getCapability("UpdateScriptTask");
|
||||
if(!url.empty())
|
||||
if (!url.empty())
|
||||
{
|
||||
// Read script source in to buffer.
|
||||
U32 script_size = file.getSize();
|
||||
@@ -462,17 +501,17 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
|
||||
file.read(script_data, script_size);
|
||||
|
||||
queue->mUploadQueue->queue(filename, data->mTaskId,
|
||||
data->mItemId, is_running, queue->mMono, queue->getID(),
|
||||
script_data, script_size, data->mScriptName);
|
||||
data->mItemp->getUUID(), is_running, queue->mMono, queue->getID(),
|
||||
script_data, script_size, data->mItemp->getName(), data->mExperienceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string text = LLTrans::getString("CompileQueueProblemUploading");
|
||||
LLChat chat(text);
|
||||
LLFloaterChat::addChat(chat);
|
||||
buffer = text + LLTrans::getString(":") + ' ' + data->mScriptName;
|
||||
buffer = text + LLTrans::getString(":") + ' ' + data->mItemp->getName();
|
||||
LL_WARNS() << "Problem uploading script asset." << LL_ENDL;
|
||||
if(queue) queue->removeItemByItemID(data->mItemId);
|
||||
if(queue) queue->removeItemByItemID(data->mItemp->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -480,29 +519,29 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
|
||||
{
|
||||
LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
|
||||
|
||||
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
|
||||
if ( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
|
||||
{
|
||||
LLChat chat(LLTrans::getString("CompileQueueScriptNotFound"));
|
||||
LLFloaterChat::addChat(chat);
|
||||
|
||||
buffer = LLTrans::getString("CompileQueueProblemDownloading") + LLTrans::getString(":") + ' ' + data->mScriptName;
|
||||
buffer = LLTrans::getString("CompileQueueProblemDownloading") + LLTrans::getString(":") + ' ' + data->mItemp->getName();
|
||||
}
|
||||
else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
|
||||
{
|
||||
LLChat chat(LLTrans::getString("CompileQueueInsufficientPermDownload"));
|
||||
LLFloaterChat::addChat(chat);
|
||||
|
||||
buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + LLTrans::getString(":") + ' ' + data->mScriptName;
|
||||
buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + LLTrans::getString(":") + ' ' + data->mItemp->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = LLTrans::getString("CompileQueueUnknownFailure") + ' ' + data->mScriptName;
|
||||
buffer = LLTrans::getString("CompileQueueUnknownFailure") + ' ' + data->mItemp->getName();
|
||||
}
|
||||
|
||||
LL_WARNS() << "Problem downloading script asset." << LL_ENDL;
|
||||
if(queue) queue->removeItemByItemID(data->mItemId);
|
||||
if(queue) queue->removeItemByItemID(data->mItemp->getUUID());
|
||||
}
|
||||
if(queue && (buffer.size() > 0))
|
||||
if (queue && (buffer.size() > 0))
|
||||
{
|
||||
queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
|
||||
}
|
||||
@@ -528,7 +567,7 @@ void LLFloaterCompileQueue::saveItemByItemID(const LLUUID& asset_id)
|
||||
{
|
||||
LL_INFOS() << "LLFloaterCompileQueue::saveItemByAssetID()" << LL_ENDL;
|
||||
LLViewerObject* viewer_object = gObjectList.findObject(mCurrentObjectID);
|
||||
if(viewer_object)
|
||||
if (viewer_object)
|
||||
{
|
||||
S32 count = mCurrentScripts.size();
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
@@ -582,7 +621,7 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
|
||||
LLInventoryObject::object_list_t::const_iterator end = inv->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
|
||||
|
||||
@@ -641,7 +680,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
|
||||
LLInventoryObject::object_list_t::const_iterator end = inv->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
|
||||
|
||||
@@ -716,17 +755,16 @@ void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id)
|
||||
|
||||
BOOL LLFloaterCompileQueue::startQueue()
|
||||
{
|
||||
/* Singu TODO: Experiences
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
std::string lookup_url=region->getCapability("GetCreatorExperiences");
|
||||
if(!lookup_url.empty())
|
||||
std::string lookup_url = region->getCapability("GetCreatorExperiences");
|
||||
if (!lookup_url.empty())
|
||||
{
|
||||
LLHTTPClient::get(lookup_url, new CompileQueueExperienceResponder(getKey().asUUID()));
|
||||
LLHTTPClient::get(lookup_url, new CompileQueueExperienceResponder(mID));
|
||||
return TRUE;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return nextObject();
|
||||
}
|
||||
|
||||
@@ -741,7 +779,7 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj,
|
||||
LLInventoryObject::object_list_t::const_iterator end = inv->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ protected:
|
||||
|
||||
// Get this instance's ID.
|
||||
const LLUUID& getID() const { return mID; }
|
||||
|
||||
|
||||
protected:
|
||||
// UI
|
||||
LLScrollListCtrl* mMessages;
|
||||
@@ -149,8 +149,8 @@ public:
|
||||
|
||||
LLAssetUploadQueue* getUploadQueue() { return mUploadQueue; }
|
||||
|
||||
void experienceIdsReceived( const LLSD& content );
|
||||
BOOL hasExperience(const LLUUID& id)const;
|
||||
void experienceIdsReceived(const LLSD& content);
|
||||
BOOL hasExperience(const LLUUID& id) const;
|
||||
|
||||
protected:
|
||||
LLFloaterCompileQueue(const std::string& name, const LLRect& rect);
|
||||
@@ -160,6 +160,9 @@ protected:
|
||||
virtual void handleInventory(LLViewerObject* viewer_obj,
|
||||
LLInventoryObject::object_list_t* inv);
|
||||
|
||||
static void requestAsset(struct LLScriptQueueData* datap, const LLSD& experience);
|
||||
|
||||
|
||||
// This is the callback for when each script arrives
|
||||
static void scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
|
||||
LLAssetType::EType type,
|
||||
|
||||
287
indra/newview/llexperiencelog.cpp
Normal file
287
indra/newview/llexperiencelog.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* @file llexperiencelog.cpp
|
||||
* @brief llexperiencelog implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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 "llexperiencelog.h"
|
||||
|
||||
#include "lldispatcher.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llviewergenericmessage.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lltrans.h"
|
||||
#include "llerror.h"
|
||||
#include "lldate.h"
|
||||
|
||||
|
||||
class LLExperienceLogDispatchHandler : public LLDispatchHandler
|
||||
{
|
||||
public:
|
||||
bool operator()(
|
||||
const LLDispatcher* dispatcher,
|
||||
const std::string& key,
|
||||
const LLUUID& invoice,
|
||||
const sparam_t& strings) override
|
||||
{
|
||||
LLSD message;
|
||||
|
||||
sparam_t::const_iterator it = strings.begin();
|
||||
if(it != strings.end()){
|
||||
const std::string& llsdRaw = *it++;
|
||||
std::istringstream llsdData(llsdRaw);
|
||||
if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
|
||||
{
|
||||
LL_WARNS() << "LLExperienceLogDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
|
||||
}
|
||||
}
|
||||
message["public_id"] = invoice;
|
||||
|
||||
// Object Name
|
||||
if(it != strings.end())
|
||||
{
|
||||
message["ObjectName"] = *it++;
|
||||
}
|
||||
|
||||
// parcel Name
|
||||
if(it != strings.end())
|
||||
{
|
||||
message["ParcelName"] = *it++;
|
||||
}
|
||||
message["Count"] = 1;
|
||||
|
||||
LLExperienceLog::instance().handleExperienceMessage(message);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static LLExperienceLogDispatchHandler experience_log_dispatch_handler;
|
||||
|
||||
void LLExperienceLog::handleExperienceMessage(LLSD& message)
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
char daybuf[16];/* Flawfinder: ignore */
|
||||
char time_of_day[16];/* Flawfinder: ignore */
|
||||
strftime(daybuf, 16, "%Y-%m-%d", localtime(&now));
|
||||
strftime(time_of_day, 16, " %H:%M:%S", localtime(&now));
|
||||
message["Time"] = time_of_day;
|
||||
|
||||
std::string day = daybuf;
|
||||
|
||||
if(!mEvents.has(day))
|
||||
{
|
||||
mEvents[day] = LLSD::emptyArray();
|
||||
}
|
||||
LLSD& dayEvents = mEvents[day];
|
||||
if(dayEvents.size() > 0)
|
||||
{
|
||||
LLSD& last = *(dayEvents.rbeginArray());
|
||||
if( last["public_id"].asUUID() == message["public_id"].asUUID()
|
||||
&& last["ObjectName"].asString() == message["ObjectName"].asString()
|
||||
&& last["OwnerID"].asUUID() == message["OwnerID"].asUUID()
|
||||
&& last["ParcelName"].asString() == message["ParcelName"].asString()
|
||||
&& last["Permission"].asInteger() == message["Permission"].asInteger())
|
||||
{
|
||||
last["Count"] = last["Count"].asInteger() + 1;
|
||||
last["Time"] = time_of_day;
|
||||
mSignals(last);
|
||||
return;
|
||||
}
|
||||
}
|
||||
message["Time"] = time_of_day;
|
||||
mEvents[day].append(message);
|
||||
mSignals(message);
|
||||
}
|
||||
|
||||
LLExperienceLog::LLExperienceLog()
|
||||
: mMaxDays(7)
|
||||
, mPageSize(25)
|
||||
, mNotifyNewEvent(false)
|
||||
{
|
||||
}
|
||||
|
||||
void LLExperienceLog::initialize()
|
||||
{
|
||||
loadEvents();
|
||||
if(!gGenericDispatcher.isHandlerPresent("ExperienceEvent"))
|
||||
{
|
||||
gGenericDispatcher.addHandler("ExperienceEvent", &experience_log_dispatch_handler);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLExperienceLog::getFilename()
|
||||
{
|
||||
return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "experience_events.xml");
|
||||
}
|
||||
|
||||
|
||||
std::string LLExperienceLog::getPermissionString( const LLSD& message, const std::string& base )
|
||||
{
|
||||
std::ostringstream buf;
|
||||
if(message.has("Permission"))
|
||||
{
|
||||
buf << base << message["Permission"].asInteger();
|
||||
std::string entry;
|
||||
if(LLTrans::findString(entry, buf.str()))
|
||||
{
|
||||
buf.str(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if(buf.str().empty())
|
||||
{
|
||||
buf << base << "Unknown";
|
||||
|
||||
buf.str(LLTrans::getString(buf.str(), message));
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
void LLExperienceLog::notify( LLSD& message )
|
||||
{
|
||||
message["EventType"] = getPermissionString(message, "ExperiencePermission");
|
||||
if(message.has("IsAttachment") && message["IsAttachment"].asBoolean())
|
||||
{
|
||||
LLNotificationsUtil::add("ExperienceEventAttachment", message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("ExperienceEvent", message);
|
||||
}
|
||||
message.erase("EventType");
|
||||
}
|
||||
|
||||
void LLExperienceLog::saveEvents()
|
||||
{
|
||||
eraseExpired();
|
||||
std::string filename = getFilename();
|
||||
LLSD settings = LLSD::emptyMap().with("Events", mEvents);
|
||||
|
||||
settings["MaxDays"] = (int)mMaxDays;
|
||||
settings["Notify"] = mNotifyNewEvent;
|
||||
settings["PageSize"] = (int)mPageSize;
|
||||
|
||||
llofstream stream(filename.c_str());
|
||||
LLSDSerialize::toPrettyXML(settings, stream);
|
||||
}
|
||||
|
||||
|
||||
void LLExperienceLog::loadEvents()
|
||||
{
|
||||
LLSD settings = LLSD::emptyMap();
|
||||
|
||||
std::string filename = getFilename();
|
||||
llifstream stream(filename.c_str());
|
||||
LLSDSerialize::fromXMLDocument(settings, stream);
|
||||
|
||||
if(settings.has("MaxDays"))
|
||||
{
|
||||
setMaxDays((U32)settings["MaxDays"].asInteger());
|
||||
}
|
||||
if(settings.has("Notify"))
|
||||
{
|
||||
setNotifyNewEvent(settings["Notify"].asBoolean());
|
||||
}
|
||||
if(settings.has("PageSize"))
|
||||
{
|
||||
setPageSize((U32)settings["PageSize"].asInteger());
|
||||
}
|
||||
mEvents.clear();
|
||||
if(mMaxDays > 0 && settings.has("Events"))
|
||||
{
|
||||
mEvents = settings["Events"];
|
||||
}
|
||||
|
||||
eraseExpired();
|
||||
}
|
||||
|
||||
LLExperienceLog::~LLExperienceLog()
|
||||
{
|
||||
saveEvents();
|
||||
}
|
||||
|
||||
void LLExperienceLog::eraseExpired()
|
||||
{
|
||||
std::vector<std::string> expired;
|
||||
std::for_each(mEvents.beginMap(), mEvents.endMap(),
|
||||
[&](const auto& event_pair)
|
||||
{
|
||||
const std::string& date = event_pair.first;
|
||||
if (isExpired(date))
|
||||
{
|
||||
expired.push_back(date);
|
||||
}
|
||||
});
|
||||
|
||||
for (const auto& date : expired)
|
||||
{
|
||||
mEvents.erase(date);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLExperienceLog::isExpired(const std::string& date)
|
||||
{
|
||||
S32 month, day, year = 0;
|
||||
S32 matched = sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day);
|
||||
if (matched != 3) return false;
|
||||
LLDate event_date;
|
||||
event_date.fromYMDHMS(year, month, day);
|
||||
|
||||
return event_date.secondsSinceEpoch() <= (LLDate::now().secondsSinceEpoch() - F64(getMaxDays() * 86400U));
|
||||
}
|
||||
|
||||
const LLSD& LLExperienceLog::getEvents() const
|
||||
{
|
||||
return mEvents;
|
||||
}
|
||||
|
||||
void LLExperienceLog::clear()
|
||||
{
|
||||
mEvents.clear();
|
||||
}
|
||||
|
||||
void LLExperienceLog::setMaxDays( U32 val )
|
||||
{
|
||||
mMaxDays = val;
|
||||
}
|
||||
|
||||
LLExperienceLog::callback_connection_t LLExperienceLog::addUpdateSignal( const callback_slot_t& cb )
|
||||
{
|
||||
return mSignals.connect(cb);
|
||||
}
|
||||
|
||||
void LLExperienceLog::setNotifyNewEvent( bool val )
|
||||
{
|
||||
mNotifyNewEvent = val;
|
||||
if(!val && mNotifyConnection.connected())
|
||||
{
|
||||
mNotifyConnection.disconnect();
|
||||
}
|
||||
else if( val && !mNotifyConnection.connected())
|
||||
{
|
||||
mNotifyConnection = addUpdateSignal(std::function<void(LLSD&)>(LLExperienceLog::notify));
|
||||
}
|
||||
}
|
||||
86
indra/newview/llexperiencelog.h
Normal file
86
indra/newview/llexperiencelog.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file llexperiencelog.h
|
||||
* @brief llexperiencelog and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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_LLEXPERIENCELOG_H
|
||||
#define LL_LLEXPERIENCELOG_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
|
||||
class LLExperienceLog final : public LLSingleton<LLExperienceLog>
|
||||
{
|
||||
friend class LLSingleton<LLExperienceLog>;
|
||||
LLExperienceLog();
|
||||
public:
|
||||
typedef boost::signals2::signal<void(LLSD&)>
|
||||
callback_signal_t;
|
||||
typedef callback_signal_t::slot_type callback_slot_t;
|
||||
typedef boost::signals2::connection callback_connection_t;
|
||||
callback_connection_t addUpdateSignal(const callback_slot_t& cb);
|
||||
|
||||
void initialize();
|
||||
|
||||
U32 getMaxDays() const { return mMaxDays; }
|
||||
void setMaxDays(U32 val);
|
||||
|
||||
bool getNotifyNewEvent() const { return mNotifyNewEvent; }
|
||||
void setNotifyNewEvent(bool val);
|
||||
|
||||
U32 getPageSize() const { return mPageSize; }
|
||||
void setPageSize(U32 val) { mPageSize = val; }
|
||||
|
||||
const LLSD& getEvents()const;
|
||||
void clear();
|
||||
|
||||
virtual ~LLExperienceLog();
|
||||
|
||||
static void notify(LLSD& message);
|
||||
static std::string getFilename();
|
||||
static std::string getPermissionString(const LLSD& message, const std::string& base);
|
||||
bool isExpired(const std::string& date);
|
||||
protected:
|
||||
void handleExperienceMessage(LLSD& message);
|
||||
|
||||
|
||||
void loadEvents();
|
||||
void saveEvents();
|
||||
void eraseExpired();
|
||||
|
||||
LLSD mEvents;
|
||||
callback_signal_t mSignals;
|
||||
callback_connection_t mNotifyConnection;
|
||||
U32 mMaxDays;
|
||||
U32 mPageSize;
|
||||
bool mNotifyNewEvent;
|
||||
|
||||
friend class LLExperienceLogDispatchHandler;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // LL_LLEXPERIENCELOG_H
|
||||
@@ -3,38 +3,31 @@
|
||||
* @author James Cook, Ian Wilkes
|
||||
* @brief Implementation of the auction floater.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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 "llfloaterauction.h"
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llgl.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llimagetga.h"
|
||||
@@ -46,17 +39,21 @@
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llmimetypes.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerdisplay.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llui.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llrender.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdutil_math.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
@@ -74,8 +71,8 @@ void auction_tga_upload_done(const LLUUID& asset_id,
|
||||
LLFloaterAuction* LLFloaterAuction::sInstance = NULL;
|
||||
|
||||
// Default constructor
|
||||
LLFloaterAuction::LLFloaterAuction() :
|
||||
LLFloater(std::string("floater_auction")),
|
||||
LLFloaterAuction::LLFloaterAuction()
|
||||
: LLFloater(std::string("floater_auction")),
|
||||
mParcelID(-1)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml");
|
||||
@@ -86,13 +83,13 @@ LLFloaterAuction::LLFloaterAuction() :
|
||||
onCommitControlSetting(gSavedSettings), (void*)"AuctionShowFence");
|
||||
|
||||
childSetAction("snapshot_btn", onClickSnapshot, this);
|
||||
childSetAction("ok_btn", onClickOK, this);
|
||||
childSetAction("ok_btn", onClickStartAuction, this);
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
LLFloaterAuction::~LLFloaterAuction()
|
||||
{
|
||||
sInstance = NULL;
|
||||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -104,12 +101,23 @@ void LLFloaterAuction::show()
|
||||
sInstance->center();
|
||||
sInstance->setFocus(TRUE);
|
||||
}
|
||||
sInstance->initialize();
|
||||
sInstance->open(); /*Flawfinder: ignore*/
|
||||
}
|
||||
|
||||
BOOL LLFloaterAuction::postBuild()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterAuction::onOpen()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
void LLFloaterAuction::initialize()
|
||||
{
|
||||
mParcelUpdateCapUrl.clear();
|
||||
|
||||
mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection();
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
LLParcel* parcelp = mParcelp->getParcel();
|
||||
@@ -117,28 +125,30 @@ void LLFloaterAuction::initialize()
|
||||
{
|
||||
mParcelHost = region->getHost();
|
||||
mParcelID = parcelp->getLocalID();
|
||||
mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate");
|
||||
|
||||
childSetText("parcel_text", parcelp->getName());
|
||||
childEnable("snapshot_btn");
|
||||
childEnable("ok_btn");
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(parcelp->getName());
|
||||
getChildView("snapshot_btn")->setEnabled(TRUE);
|
||||
getChildView("ok_btn")->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mParcelHost.invalidate();
|
||||
if(parcelp && parcelp->getForSale())
|
||||
{
|
||||
childSetText("parcel_text", getString("already for sale"));
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(getString("already for sale"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetText("parcel_text", LLStringUtil::null);
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(LLStringUtil::null);
|
||||
}
|
||||
mParcelID = -1;
|
||||
childSetEnabled("snapshot_btn", false);
|
||||
childSetEnabled("ok_btn", false);
|
||||
getChildView("snapshot_btn")->setEnabled(false);
|
||||
getChildView("ok_btn")->setEnabled(false);
|
||||
}
|
||||
|
||||
mImageID.setNull();
|
||||
mImage = NULL;
|
||||
mImage = nullptr;
|
||||
}
|
||||
|
||||
void LLFloaterAuction::draw()
|
||||
@@ -147,9 +157,10 @@ void LLFloaterAuction::draw()
|
||||
|
||||
if(!isMinimized() && mImage.notNull())
|
||||
{
|
||||
LLRect rect;
|
||||
if (childGetRect("snapshot_icon", rect))
|
||||
LLView* snapshot_icon = findChild<LLView>("snapshot_icon");
|
||||
if (snapshot_icon)
|
||||
{
|
||||
LLRect rect = snapshot_icon->getRect();
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
|
||||
@@ -176,7 +187,7 @@ void LLFloaterAuction::onClickSnapshot(void* data)
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw;
|
||||
|
||||
gForceRenderLandFence = self->childGetValue("fence_check").asBoolean();
|
||||
gForceRenderLandFence = self->getChild<LLUICtrl>("fence_check")->getValue().asBoolean();
|
||||
BOOL success = gViewerWindow->rawSnapshot(raw,
|
||||
gViewerWindow->getWindowWidth(),
|
||||
gViewerWindow->getWindowHeight(),
|
||||
@@ -218,13 +229,13 @@ void LLFloaterAuction::onClickSnapshot(void* data)
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterAuction::onClickOK(void* data)
|
||||
void LLFloaterAuction::onClickStartAuction(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
|
||||
if(self->mImageID.notNull())
|
||||
{
|
||||
LLSD parcel_name = self->childGetValue("parcel_text");
|
||||
LLSD parcel_name = self->getChild<LLUICtrl>("parcel_text")->getValue();
|
||||
|
||||
// create the asset
|
||||
std::string* name = new std::string(parcel_name.asString());
|
||||
@@ -257,11 +268,243 @@ void LLFloaterAuction::onClickOK(void* data)
|
||||
msg->sendReliable(self->mParcelHost);
|
||||
|
||||
// clean up floater, and get out
|
||||
self->mImageID.setNull();
|
||||
self->mImage = NULL;
|
||||
self->mParcelID = -1;
|
||||
self->mParcelHost.invalidate();
|
||||
self->close();
|
||||
self->cleanupAndClose();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterAuction::cleanupAndClose()
|
||||
{
|
||||
mImageID.setNull();
|
||||
mImage = nullptr;
|
||||
mParcelID = -1;
|
||||
mParcelHost.invalidate();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static glue
|
||||
void LLFloaterAuction::onClickResetParcel(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
if (self)
|
||||
{
|
||||
self->doResetParcel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reset all the values for the parcel in preparation for a sale
|
||||
void LLFloaterAuction::doResetParcel()
|
||||
{
|
||||
LLParcel* parcelp = mParcelp->getParcel();
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
|
||||
if (parcelp
|
||||
&& region
|
||||
&& !mParcelUpdateCapUrl.empty())
|
||||
{
|
||||
LLSD body;
|
||||
std::string empty;
|
||||
|
||||
// request new properties update from simulator
|
||||
U32 message_flags = 0x01;
|
||||
body["flags"] = ll_sd_from_U32(message_flags);
|
||||
|
||||
// Set all the default parcel properties for auction
|
||||
body["local_id"] = parcelp->getLocalID();
|
||||
|
||||
U32 parcel_flags = PF_ALLOW_LANDMARK |
|
||||
PF_ALLOW_FLY |
|
||||
PF_CREATE_GROUP_OBJECTS |
|
||||
PF_ALLOW_ALL_OBJECT_ENTRY |
|
||||
PF_ALLOW_GROUP_OBJECT_ENTRY |
|
||||
PF_ALLOW_GROUP_SCRIPTS |
|
||||
PF_RESTRICT_PUSHOBJECT |
|
||||
PF_SOUND_LOCAL |
|
||||
PF_ALLOW_VOICE_CHAT |
|
||||
PF_USE_ESTATE_VOICE_CHAN;
|
||||
|
||||
body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
|
||||
|
||||
// Build a parcel name like "Ahern (128,128) PG 4032m"
|
||||
std::ostringstream parcel_name;
|
||||
LLVector3 center_point( parcelp->getCenterpoint() );
|
||||
center_point.snap(0); // Get rid of fractions
|
||||
parcel_name << region->getName()
|
||||
<< " ("
|
||||
<< (S32) center_point.mV[VX]
|
||||
<< ","
|
||||
<< (S32) center_point.mV[VY]
|
||||
<< ") "
|
||||
<< region->getSimAccessString()
|
||||
<< " "
|
||||
<< parcelp->getArea()
|
||||
<< "m";
|
||||
|
||||
std::string new_name(parcel_name.str());
|
||||
body["name"] = new_name;
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(new_name); // Set name in dialog as well, since it won't get updated otherwise
|
||||
|
||||
body["sale_price"] = (S32) 0;
|
||||
body["description"] = empty;
|
||||
body["music_url"] = empty;
|
||||
body["media_url"] = empty;
|
||||
body["media_desc"] = empty;
|
||||
body["media_type"] = LLMIMETypes::getDefaultMimeType();
|
||||
body["media_width"] = (S32) 0;
|
||||
body["media_height"] = (S32) 0;
|
||||
body["auto_scale"] = (S32) 0;
|
||||
body["media_loop"] = (S32) 0;
|
||||
body["obscure_media"] = (S32) 0; // OBSOLETE - no longer used
|
||||
body["obscure_music"] = (S32) 0; // OBSOLETE - no longer used
|
||||
body["media_id"] = LLUUID::null;
|
||||
body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group
|
||||
body["pass_price"] = (S32) 10; // Defaults to $10
|
||||
body["pass_hours"] = 0.0f;
|
||||
body["category"] = (U8) LLParcel::C_NONE;
|
||||
body["auth_buyer_id"] = LLUUID::null;
|
||||
body["snapshot_id"] = LLUUID::null;
|
||||
body["user_location"] = ll_sd_from_vector3( LLVector3::zero );
|
||||
body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero );
|
||||
body["landing_type"] = (U8) LLParcel::L_DIRECT;
|
||||
|
||||
LL_INFOS() << "Sending parcel update to reset for auction via capability to: "
|
||||
<< mParcelUpdateCapUrl << LL_ENDL;
|
||||
LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::ResponderIgnore());
|
||||
|
||||
// Send a message to clear the object return time
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_ParcelData);
|
||||
msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID());
|
||||
msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return
|
||||
|
||||
msg->sendReliable(region->getHost());
|
||||
|
||||
// Clear the access lists
|
||||
clearParcelAccessList(parcelp, region, AL_ACCESS);
|
||||
clearParcelAccessList(parcelp, region, AL_BAN);
|
||||
clearParcelAccessList(parcelp, region, AL_ALLOW_EXPERIENCE);
|
||||
clearParcelAccessList(parcelp, region, AL_BLOCK_EXPERIENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLFloaterAuction::clearParcelAccessList(LLParcel* parcel, LLViewerRegion* region, U32 list)
|
||||
{
|
||||
if (!region || !parcel) return;
|
||||
|
||||
LLUUID transactionUUID;
|
||||
transactionUUID.generate();
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addU32Fast(_PREHASH_Flags, list);
|
||||
msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
|
||||
msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id
|
||||
msg->addS32Fast(_PREHASH_Sections, 0); // num_sections
|
||||
|
||||
// pack an empty block since there will be no data
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
|
||||
msg->addS32Fast(_PREHASH_Time, 0 );
|
||||
msg->addU32Fast(_PREHASH_Flags, 0 );
|
||||
|
||||
msg->sendReliable( region->getHost() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static - 'Sell to Anyone' clicked, throw up a confirmation dialog
|
||||
void LLFloaterAuction::onClickSellToAnyone(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
if (self)
|
||||
{
|
||||
LLParcel* parcelp = self->mParcelp->getParcel();
|
||||
|
||||
// Do a confirmation
|
||||
S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter
|
||||
S32 area = parcelp->getArea();
|
||||
|
||||
LLSD args;
|
||||
args["LAND_SIZE"] = llformat("%d", area);
|
||||
args["SALE_PRICE"] = llformat("%d", sale_price);
|
||||
args["NAME"] = LLTrans::getString("Anyone");
|
||||
|
||||
LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog
|
||||
params.substitutions(args)
|
||||
.functor/*.function*/(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2));
|
||||
|
||||
params.name("ConfirmLandSaleToAnyoneChange");
|
||||
|
||||
// ask away
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sell confirmation clicked
|
||||
bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
doSellToAnyone();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reset all the values for the parcel in preparation for a sale
|
||||
void LLFloaterAuction::doSellToAnyone()
|
||||
{
|
||||
LLParcel* parcelp = mParcelp->getParcel();
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
|
||||
if (parcelp
|
||||
&& region
|
||||
&& !mParcelUpdateCapUrl.empty())
|
||||
{
|
||||
LLSD body;
|
||||
|
||||
// request new properties update from simulator
|
||||
U32 message_flags = 0x01;
|
||||
body["flags"] = ll_sd_from_U32(message_flags);
|
||||
|
||||
// Set all the default parcel properties for auction
|
||||
body["local_id"] = parcelp->getLocalID();
|
||||
|
||||
// Set 'for sale' flag
|
||||
U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE;
|
||||
// Ensure objects not included
|
||||
parcel_flags &= ~PF_FOR_SALE_OBJECTS;
|
||||
body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
|
||||
|
||||
body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter
|
||||
body["auth_buyer_id"] = LLUUID::null; // To anyone
|
||||
|
||||
LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
|
||||
<< mParcelUpdateCapUrl << LL_ENDL;
|
||||
|
||||
LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::ResponderIgnore());
|
||||
|
||||
// clean up floater, and get out
|
||||
cleanupAndClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,31 +3,25 @@
|
||||
* @author James Cook, Ian Wilkes
|
||||
* @brief llfloaterauction class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* 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.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -36,7 +30,7 @@
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lluuid.h"
|
||||
#include "llmemory.h"
|
||||
#include "llsafehandle.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -45,34 +39,50 @@
|
||||
// Class which holds the functionality to start auctions.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLParcelSelection;
|
||||
class LLParcel;
|
||||
class LLViewerRegion;
|
||||
|
||||
class LLFloaterAuction : public LLFloater
|
||||
class LLFloaterAuction final : public LLFloater
|
||||
{
|
||||
public:
|
||||
// LLFloater interface
|
||||
/*virtual*/ void onClose(bool app_quitting) { setVisible(FALSE); }
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void onOpen() override;
|
||||
/*virtual*/ void onClose(bool app_quitting) override { setVisible(FALSE); }
|
||||
/*virtual*/ void draw() override;
|
||||
|
||||
// LLFloaterAuction interface
|
||||
static void show();
|
||||
|
||||
private:
|
||||
|
||||
LLFloaterAuction();
|
||||
~LLFloaterAuction();
|
||||
|
||||
void initialize();
|
||||
|
||||
static void onClickSnapshot(void* data);
|
||||
static void onClickOK(void* data);
|
||||
static void onClickResetParcel(void* data);
|
||||
static void onClickSellToAnyone(void* data); // Sell to anyone clicked
|
||||
bool onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response); // Sell confirmation clicked
|
||||
static void onClickStartAuction(void* data);
|
||||
|
||||
static LLFloaterAuction* sInstance;
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
|
||||
void doResetParcel();
|
||||
void doSellToAnyone();
|
||||
void clearParcelAccessList(LLParcel* parcel, LLViewerRegion* region, U32 list);
|
||||
void cleanupAndClose();
|
||||
|
||||
private:
|
||||
|
||||
LLTransactionID mTransactionID;
|
||||
LLAssetID mImageID;
|
||||
LLPointer<LLViewerTexture> mImage;
|
||||
LLSafeHandle<LLParcelSelection> mParcelp;
|
||||
S32 mParcelID;
|
||||
LLHost mParcelHost;
|
||||
|
||||
std::string mParcelUpdateCapUrl; // "ParcelPropertiesUpdate" capability
|
||||
};
|
||||
|
||||
|
||||
|
||||
167
indra/newview/llfloaterexperiencepicker.cpp
Normal file
167
indra/newview/llfloaterexperiencepicker.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @file llfloaterexperiencepicker.cpp
|
||||
* @brief Implementation of llfloaterexperiencepicker
|
||||
* @author dolphin@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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 "llfloaterexperiencepicker.h"
|
||||
|
||||
|
||||
#include "lllineeditor.h"
|
||||
//#include "llfloaterreg.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llagent.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llslurl.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lldraghandle.h"
|
||||
#include "llpanelexperiencepicker.h"
|
||||
|
||||
// <singu>
|
||||
LLFloaterExperiencePicker* show_xp_picker(const LLSD& key)
|
||||
{
|
||||
LLFloaterExperiencePicker* floater =
|
||||
LLFloaterExperiencePicker::getInstance(key);
|
||||
if (!floater)
|
||||
{
|
||||
floater = new LLFloaterExperiencePicker(key);
|
||||
}
|
||||
floater->open();
|
||||
return floater;
|
||||
}
|
||||
// </singu>
|
||||
|
||||
LLFloaterExperiencePicker* LLFloaterExperiencePicker::show( select_callback_t callback, const LLUUID& key, BOOL allow_multiple, BOOL close_on_select, filter_list filters, LLView * frustumOrigin )
|
||||
{
|
||||
LLFloaterExperiencePicker* floater = show_xp_picker(key);
|
||||
|
||||
if (floater->mSearchPanel)
|
||||
{
|
||||
floater->mSearchPanel->mSelectionCallback = callback;
|
||||
floater->mSearchPanel->mCloseOnSelect = close_on_select;
|
||||
floater->mSearchPanel->setAllowMultiple(allow_multiple);
|
||||
floater->mSearchPanel->setDefaultFilters();
|
||||
floater->mSearchPanel->addFilters(filters.begin(), filters.end());
|
||||
floater->mSearchPanel->filterContent();
|
||||
}
|
||||
|
||||
if(frustumOrigin)
|
||||
{
|
||||
floater->mFrustumOrigin = frustumOrigin->getHandle();
|
||||
}
|
||||
|
||||
return floater;
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::drawFrustum()
|
||||
{
|
||||
if(mFrustumOrigin.get())
|
||||
{
|
||||
LLView * frustumOrigin = mFrustumOrigin.get();
|
||||
LLRect origin_rect;
|
||||
frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
|
||||
// draw context cone connecting color picker with color swatch in parent floater
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable<GL_CULL_FACE> cull_face;
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::draw()
|
||||
{
|
||||
drawFrustum();
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
LLFloaterExperiencePicker::LLFloaterExperiencePicker( const LLSD& key )
|
||||
:LLFloater()
|
||||
,LLInstanceTracker<LLFloaterExperiencePicker, LLUUID>(key.asUUID())
|
||||
,mSearchPanel(nullptr)
|
||||
,mContextConeOpacity(0.f)
|
||||
,mContextConeInAlpha(0.f)
|
||||
,mContextConeOutAlpha(0.f)
|
||||
,mContextConeFadeTime(0.f)
|
||||
{
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_experience_search.xml", NULL, false);
|
||||
//buildFromFile("floater_experience_search.xml");
|
||||
}
|
||||
|
||||
LLFloaterExperiencePicker::~LLFloaterExperiencePicker()
|
||||
{
|
||||
gFocusMgr.releaseFocusIfNeeded( this );
|
||||
}
|
||||
|
||||
BOOL LLFloaterExperiencePicker::postBuild()
|
||||
{
|
||||
mSearchPanel = new LLPanelExperiencePicker();
|
||||
addChild(mSearchPanel);
|
||||
mSearchPanel->setOrigin(0, 0);
|
||||
return LLFloater::postBuild();
|
||||
}
|
||||
69
indra/newview/llfloaterexperiencepicker.h
Normal file
69
indra/newview/llfloaterexperiencepicker.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @file llfloaterexperiencepicker.h
|
||||
* @brief Header file for llfloaterexperiencepicker
|
||||
* @author dolphin@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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_LLFLOATEREXPERIENCEPICKER_H
|
||||
#define LL_LLFLOATEREXPERIENCEPICKER_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
class LLScrollListCtrl;
|
||||
class LLLineEditor;
|
||||
class LLPanelExperiencePicker;
|
||||
|
||||
|
||||
class LLFloaterExperiencePicker : public LLFloater
|
||||
, public LLInstanceTracker<LLFloaterExperiencePicker, LLUUID>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::function<void (const uuid_vec_t&)> select_callback_t;
|
||||
// filter function for experiences, return true if the experience should be hidden.
|
||||
typedef std::function<bool (const LLSD&)> filter_function;
|
||||
typedef std::vector<filter_function> filter_list;
|
||||
|
||||
static LLFloaterExperiencePicker* show( select_callback_t callback, const LLUUID& key, BOOL allow_multiple, BOOL close_on_select, filter_list filters, LLView * frustumOrigin);
|
||||
|
||||
LLFloaterExperiencePicker(const LLSD& key);
|
||||
virtual ~LLFloaterExperiencePicker();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void draw() override;
|
||||
private:
|
||||
|
||||
LLPanelExperiencePicker* mSearchPanel;
|
||||
|
||||
void drawFrustum();
|
||||
LLHandle <LLView> mFrustumOrigin;
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATEREXPERIENCEPICKER_H
|
||||
|
||||
962
indra/newview/llfloaterexperienceprofile.cpp
Normal file
962
indra/newview/llfloaterexperienceprofile.cpp
Normal file
@@ -0,0 +1,962 @@
|
||||
/**
|
||||
* @file llfloaterexperienceprofile.cpp
|
||||
* @brief llfloaterexperienceprofile and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, 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 "llfloaterexperienceprofile.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llcommandhandler.h"
|
||||
//#include "llexpandabletextbox.h"
|
||||
#include "llexperiencecache.h"
|
||||
//#include "llfloaterreg.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lllayoutstack.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llevents.h"
|
||||
#include "llfloatergroups.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llfloaterreporter.h"
|
||||
#include "llurlaction.h"
|
||||
|
||||
#define XML_PANEL_EXPERIENCE_PROFILE "floater_experienceprofile.xml"
|
||||
#define TF_NAME "experience_title"
|
||||
#define TF_DESC "experience_description"
|
||||
#define TF_SLURL "LocationTextText"
|
||||
#define TF_MRKT "marketplace"
|
||||
#define TF_MATURITY "ContentRatingText"
|
||||
#define TF_OWNER "OwnerText"
|
||||
#define TF_GROUP "GroupText"
|
||||
#define TF_GRID_WIDE "grid_wide"
|
||||
#define TF_PRIVILEGED "privileged"
|
||||
#define EDIT "edit_"
|
||||
|
||||
#define IMG_LOGO "logo"
|
||||
|
||||
#define PNL_TOP "top panel"
|
||||
#define PNL_IMAGE "image_panel"
|
||||
#define PNL_DESC "description panel"
|
||||
#define PNL_LOC "location panel"
|
||||
#define PNL_MRKT "marketplace panel"
|
||||
#define PNL_GROUP "group_panel"
|
||||
#define PNL_PERMS "perm panel"
|
||||
|
||||
#define BTN_ALLOW "allow_btn"
|
||||
#define BTN_BLOCK "block_btn"
|
||||
#define BTN_CANCEL "cancel_btn"
|
||||
#define BTN_CLEAR_LOCATION "clear_btn"
|
||||
#define BTN_EDIT "edit_btn"
|
||||
#define BTN_ENABLE "enable_btn"
|
||||
#define BTN_FORGET "forget_btn"
|
||||
#define BTN_PRIVATE "private_btn"
|
||||
#define BTN_REPORT "report_btn"
|
||||
#define BTN_SAVE "save_btn"
|
||||
#define BTN_SET_GROUP "Group_btn"
|
||||
#define BTN_SET_LOCATION "location_btn"
|
||||
|
||||
|
||||
class LLExperienceHandler : public LLCommandHandler
|
||||
{
|
||||
public:
|
||||
LLExperienceHandler() : LLCommandHandler("experience", UNTRUSTED_THROTTLE) { }
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map,
|
||||
LLMediaCtrl* web) override
|
||||
{
|
||||
if (params.size() != 2 || params[1].asString() != "profile")
|
||||
return false;
|
||||
|
||||
LLExperienceCache::instance().get(params[0].asUUID(), boost::bind(&LLExperienceHandler::experienceCallback, this, _1));
|
||||
return true;
|
||||
}
|
||||
|
||||
void experienceCallback(const LLSD& experienceDetails)
|
||||
{
|
||||
if (!experienceDetails.has(LLExperienceCache::MISSING))
|
||||
{
|
||||
LLFloaterExperienceProfile::showInstance(experienceDetails[LLExperienceCache::EXPERIENCE_ID].asUUID());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LLExperienceHandler gExperienceHandler;
|
||||
|
||||
void LLFloaterExperienceProfile::showInstance(const LLSD& data)
|
||||
{
|
||||
bool is_map = data.has("experience_id");
|
||||
LLFloaterExperienceProfile* floater = getInstance(is_map ? data["experience_id"].asUUID() : data.asUUID());
|
||||
if (!floater) floater = new LLFloaterExperienceProfile(data);
|
||||
else if (is_map && data.has("edit_experience") && data["edit_experience"].asBoolean())
|
||||
floater->changeToEdit();
|
||||
floater->open();
|
||||
}
|
||||
|
||||
LLFloaterExperienceProfile::LLFloaterExperienceProfile(const LLSD& data)
|
||||
: LLFloater(), LLInstanceTracker<LLFloaterExperienceProfile, LLUUID>(data.asUUID())
|
||||
, mSaveCompleteAction(NOTHING)
|
||||
, mDirty(false)
|
||||
, mForceClose(false)
|
||||
{
|
||||
if (data.has("experience_id"))
|
||||
{
|
||||
mExperienceId = data["experience_id"].asUUID();
|
||||
mPostEdit = data.has("edit_experience") && data["edit_experience"].asBoolean();
|
||||
}
|
||||
else
|
||||
{
|
||||
mExperienceId = data.asUUID();
|
||||
mPostEdit = false;
|
||||
}
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, XML_PANEL_EXPERIENCE_PROFILE, NULL, false);
|
||||
//buildFromFile(XML_PANEL_EXPERIENCE_PROFILE);
|
||||
}
|
||||
|
||||
|
||||
LLFloaterExperienceProfile::~LLFloaterExperienceProfile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL LLFloaterExperienceProfile::postBuild()
|
||||
{
|
||||
|
||||
if (mExperienceId.notNull())
|
||||
{
|
||||
LLExperienceCache::instance().fetch(mExperienceId, true);
|
||||
LLExperienceCache::instance().get(mExperienceId, boost::bind(&LLFloaterExperienceProfile::experienceCallback,
|
||||
getDerivedHandle<LLFloaterExperienceProfile>(), _1));
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
LLExperienceCache::instance().getExperienceAdmin(mExperienceId, boost::bind(
|
||||
&LLFloaterExperienceProfile::experienceIsAdmin, getDerivedHandle<LLFloaterExperienceProfile>(), _1));
|
||||
}
|
||||
}
|
||||
|
||||
childSetAction(BTN_EDIT, boost::bind(&LLFloaterExperienceProfile::onClickEdit, this));
|
||||
childSetAction(BTN_ALLOW, boost::bind(&LLFloaterExperienceProfile::onClickPermission, this, "Allow"));
|
||||
childSetAction(BTN_FORGET, boost::bind(&LLFloaterExperienceProfile::onClickForget, this));
|
||||
childSetAction(BTN_BLOCK, boost::bind(&LLFloaterExperienceProfile::onClickPermission, this, "Block"));
|
||||
childSetAction(BTN_CANCEL, boost::bind(&LLFloaterExperienceProfile::onClickCancel, this));
|
||||
childSetAction(BTN_SAVE, boost::bind(&LLFloaterExperienceProfile::onClickSave, this));
|
||||
childSetAction(BTN_SET_LOCATION, boost::bind(&LLFloaterExperienceProfile::onClickLocation, this));
|
||||
childSetAction(BTN_CLEAR_LOCATION, boost::bind(&LLFloaterExperienceProfile::onClickClear, this));
|
||||
childSetAction(BTN_SET_GROUP, boost::bind(&LLFloaterExperienceProfile::onPickGroup, this));
|
||||
childSetAction(BTN_REPORT, boost::bind(&LLFloaterExperienceProfile::onReportExperience, this));
|
||||
|
||||
getChild<LLTextEditor>(EDIT TF_DESC)->setKeystrokeCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
|
||||
getChild<LLUICtrl>(EDIT TF_MATURITY)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
|
||||
getChild<LLLineEditor>(EDIT TF_MRKT)->setKeystrokeCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
|
||||
getChild<LLLineEditor>(EDIT TF_NAME)->setKeystrokeCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
|
||||
|
||||
childSetCommitCallback(EDIT BTN_ENABLE, boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this), nullptr);
|
||||
childSetCommitCallback(EDIT BTN_PRIVATE, boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this), nullptr);
|
||||
|
||||
childSetCommitCallback(EDIT IMG_LOGO, boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this), nullptr);
|
||||
|
||||
const LLColor4& link_color = gSavedSettings.getColor4("HTMLLinkColor");
|
||||
if (auto market = getChild<LLTextBox>(TF_MRKT))
|
||||
{
|
||||
market->setClickedCallback([market] { LLUrlAction::clickAction(market->getValue().asStringRef(), true); });
|
||||
market->setColor(link_color);
|
||||
market->setFontStyle(LLFontGL::UNDERLINE);
|
||||
}
|
||||
|
||||
if (auto location = getChild<LLTextBox>(TF_SLURL))
|
||||
{
|
||||
location->setClickedCallback([=] { LLUrlAction::clickAction(mLocationSLURL, true); });
|
||||
location->setColor(link_color);
|
||||
location->setFontStyle(LLFontGL::UNDERLINE);
|
||||
}
|
||||
|
||||
if (auto logo = findChild<LLTexturePicker>(IMG_LOGO))
|
||||
{
|
||||
void show_picture(const LLUUID& id, const std::string& name);
|
||||
logo->setCommitCallback(boost::bind(show_picture, boost::bind(&LLTexturePicker::getImageAssetID, logo), "Experience Picture"));
|
||||
}
|
||||
|
||||
getChild<LLTextEditor>(EDIT TF_DESC)->setCommitOnFocusLost(TRUE);
|
||||
|
||||
LLEventPumps::instance().obtain("experience_permission").listen(mExperienceId.asString()+"-profile",
|
||||
boost::bind(&LLFloaterExperienceProfile::experiencePermission, getDerivedHandle<LLFloaterExperienceProfile>(this), _1));
|
||||
|
||||
if (mPostEdit && mExperienceId.notNull())
|
||||
{
|
||||
mPostEdit = false;
|
||||
changeToEdit();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::experienceCallback(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& experience )
|
||||
{
|
||||
LLFloaterExperienceProfile* pllpep = handle.get();
|
||||
if (pllpep)
|
||||
{
|
||||
pllpep->refreshExperience(experience);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLFloaterExperienceProfile::experiencePermission( LLHandle<LLFloaterExperienceProfile> handle, const LLSD& permission )
|
||||
{
|
||||
LLFloaterExperienceProfile* pllpep = handle.get();
|
||||
if (pllpep)
|
||||
{
|
||||
pllpep->updatePermission(permission);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperienceProfile::onClickEdit()
|
||||
{
|
||||
changeToEdit();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperienceProfile::onClickCancel()
|
||||
{
|
||||
changeToView();
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onClickSave()
|
||||
{
|
||||
doSave(NOTHING);
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onClickPermission(const char* perm)
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
return;
|
||||
LLExperienceCache::instance().setExperiencePermission(mExperienceId, perm, boost::bind(
|
||||
&LLFloaterExperienceProfile::experiencePermissionResults, mExperienceId, _1));
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperienceProfile::onClickForget()
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
LLExperienceCache::instance().forgetExperiencePermission(mExperienceId, boost::bind(
|
||||
&LLFloaterExperienceProfile::experiencePermissionResults, mExperienceId, _1));
|
||||
}
|
||||
|
||||
bool LLFloaterExperienceProfile::setMaturityString( U8 maturity, LLTextBox* child, LLComboBox* combo )
|
||||
{
|
||||
/* Singu Note: Nope.
|
||||
LLStyle::Params style;
|
||||
std::string access;
|
||||
*/
|
||||
if (maturity <= SIM_ACCESS_PG)
|
||||
{
|
||||
/* Singu Note: Nope.
|
||||
style.image(LLUI::getUIImage(getString("maturity_icon_general")));
|
||||
access = LLTrans::getString("SIM_ACCESS_PG");
|
||||
*/
|
||||
combo->setCurrentByIndex(2);
|
||||
}
|
||||
else if (maturity <= SIM_ACCESS_MATURE)
|
||||
{
|
||||
/* Singu Note: Nope.
|
||||
style.image(LLUI::getUIImage(getString("maturity_icon_moderate")));
|
||||
access = LLTrans::getString("SIM_ACCESS_MATURE");
|
||||
*/
|
||||
combo->setCurrentByIndex(1);
|
||||
}
|
||||
else if (maturity <= SIM_ACCESS_ADULT)
|
||||
{
|
||||
/* Singu Note: Nope.
|
||||
style.image(LLUI::getUIImage(getString("maturity_icon_adult")));
|
||||
access = LLTrans::getString("SIM_ACCESS_ADULT");
|
||||
*/
|
||||
combo->setCurrentByIndex(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Singu Note: Nope.
|
||||
child->setText(LLStringUtil::null);
|
||||
|
||||
child->appendImageSegment(style);
|
||||
|
||||
child->appendText(access, false);
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperienceProfile::refreshExperience( const LLSD& experience )
|
||||
{
|
||||
mExperienceDetails = experience;
|
||||
mPackage = experience;
|
||||
|
||||
|
||||
LLLayoutPanel* imagePanel = getChild<LLLayoutPanel>(PNL_IMAGE);
|
||||
LLLayoutPanel* descriptionPanel = getChild<LLLayoutPanel>(PNL_DESC);
|
||||
LLLayoutPanel* locationPanel = getChild<LLLayoutPanel>(PNL_LOC);
|
||||
LLLayoutPanel* marketplacePanel = getChild<LLLayoutPanel>(PNL_MRKT);
|
||||
LLLayoutPanel* topPanel = getChild<LLLayoutPanel>(PNL_TOP);
|
||||
|
||||
|
||||
imagePanel->setVisible(FALSE);
|
||||
descriptionPanel->setVisible(FALSE);
|
||||
locationPanel->setVisible(FALSE);
|
||||
marketplacePanel->setVisible(FALSE);
|
||||
topPanel->setVisible(FALSE);
|
||||
|
||||
|
||||
LLTextBox* child = getChild<LLTextBox>(TF_NAME);
|
||||
//child->setText(experience[LLExperienceCache::NAME].asString());
|
||||
child->setValue(experience[LLExperienceCache::EXPERIENCE_ID].asUUID());
|
||||
|
||||
LLLineEditor* linechild = getChild<LLLineEditor>(EDIT TF_NAME);
|
||||
linechild->setText(experience[LLExperienceCache::NAME].asString());
|
||||
|
||||
std::string value = experience[LLExperienceCache::DESCRIPTION].asString();
|
||||
LLTextEditor* exchild = getChild<LLTextEditor>(TF_DESC);
|
||||
exchild->setText(value);
|
||||
descriptionPanel->setVisible(value.length()>0);
|
||||
|
||||
LLTextEditor* edit_child = getChild<LLTextEditor>(EDIT TF_DESC);
|
||||
edit_child->setText(value);
|
||||
|
||||
mLocationSLURL = experience[LLExperienceCache::SLURL].asString();
|
||||
child = getChild<LLTextBox>(TF_SLURL);
|
||||
bool has_slurl = !mLocationSLURL.empty() && mLocationSLURL != "last";
|
||||
locationPanel->setVisible(has_slurl);
|
||||
if (has_slurl) mLocationSLURL = LLSLURL(mLocationSLURL).getSLURLString();
|
||||
child->setText(mLocationSLURL);
|
||||
|
||||
|
||||
child = getChild<LLTextBox>(EDIT TF_SLURL);
|
||||
if (has_slurl)
|
||||
{
|
||||
child->setText(mLocationSLURL);
|
||||
}
|
||||
else
|
||||
{
|
||||
child->setText(getString("empty_slurl"));
|
||||
}
|
||||
|
||||
setMaturityString((U8)(experience[LLExperienceCache::MATURITY].asInteger()), getChild<LLTextBox>(TF_MATURITY), getChild<LLComboBox>(EDIT TF_MATURITY));
|
||||
|
||||
LLUUID agent_id = experience[LLExperienceCache::AGENT_ID].asUUID();
|
||||
getChild<LLTextBox>(TF_OWNER)->setValue(agent_id);
|
||||
|
||||
LLUUID id = experience[LLExperienceCache::GROUP_ID].asUUID();
|
||||
bool id_null = id.isNull();
|
||||
if (!id_null)
|
||||
{
|
||||
getChild<LLTextBox>(TF_GROUP)->setValue(id);
|
||||
}
|
||||
getChild<LLLayoutPanel>(PNL_GROUP)->setVisible(!id_null);
|
||||
|
||||
setEditGroup(id);
|
||||
|
||||
getChild<LLButton>(BTN_SET_GROUP)->setEnabled(agent_id == gAgentID);
|
||||
|
||||
LLCheckBoxCtrl* enable = getChild<LLCheckBoxCtrl>(EDIT BTN_ENABLE);
|
||||
S32 properties = mExperienceDetails[LLExperienceCache::PROPERTIES].asInteger();
|
||||
enable->set(!(properties & LLExperienceCache::PROPERTY_DISABLED));
|
||||
|
||||
enable = getChild<LLCheckBoxCtrl>(EDIT BTN_PRIVATE);
|
||||
enable->set(properties & LLExperienceCache::PROPERTY_PRIVATE);
|
||||
|
||||
topPanel->setVisible(TRUE);
|
||||
child=getChild<LLTextBox>(TF_GRID_WIDE);
|
||||
child->setVisible(TRUE);
|
||||
|
||||
if(properties & LLExperienceCache::PROPERTY_GRID)
|
||||
{
|
||||
child->setText(LLTrans::getString("Grid-Scope"));
|
||||
}
|
||||
else
|
||||
{
|
||||
child->setText(LLTrans::getString("Land-Scope"));
|
||||
}
|
||||
|
||||
if (getChild<LLButton>(BTN_EDIT)->getVisible())
|
||||
{
|
||||
topPanel->setVisible(TRUE);
|
||||
}
|
||||
|
||||
if (properties & LLExperienceCache::PROPERTY_PRIVILEGED)
|
||||
{
|
||||
child = getChild<LLTextBox>(TF_PRIVILEGED);
|
||||
child->setVisible(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
LLExperienceCache::instance().getExperiencePermission(mExperienceId, boost::bind(
|
||||
&LLFloaterExperienceProfile::experiencePermissionResults, mExperienceId, _1));
|
||||
}
|
||||
}
|
||||
|
||||
value=experience[LLExperienceCache::METADATA].asString();
|
||||
if (value.empty())
|
||||
return;
|
||||
|
||||
LLPointer<LLSDParser> parser = new LLSDXMLParser();
|
||||
|
||||
LLSD data;
|
||||
|
||||
std::istringstream is(value);
|
||||
if (LLSDParser::PARSE_FAILURE != parser->parse(is, data, value.size()))
|
||||
{
|
||||
value.clear();
|
||||
if (data.has(TF_MRKT))
|
||||
{
|
||||
value=data[TF_MRKT].asString();
|
||||
|
||||
child = getChild<LLTextBox>(TF_MRKT);
|
||||
child->setText(value);
|
||||
if(!value.empty())
|
||||
{
|
||||
marketplacePanel->setVisible(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
marketplacePanel->setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
marketplacePanel->setVisible(FALSE);
|
||||
}
|
||||
|
||||
linechild = getChild<LLLineEditor>(EDIT TF_MRKT);
|
||||
linechild->setText(value);
|
||||
|
||||
if (data.has(IMG_LOGO))
|
||||
{
|
||||
LLTextureCtrl* logo = getChild<LLTextureCtrl>(IMG_LOGO);
|
||||
|
||||
LLUUID id = data[IMG_LOGO].asUUID();
|
||||
logo->setImageAssetID(id);
|
||||
imagePanel->setVisible(TRUE);
|
||||
|
||||
logo = getChild<LLTextureCtrl>(EDIT IMG_LOGO);
|
||||
logo->setImageAssetID(data[IMG_LOGO].asUUID());
|
||||
|
||||
imagePanel->setVisible(id.notNull());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
marketplacePanel->setVisible(FALSE);
|
||||
imagePanel->setVisible(FALSE);
|
||||
}
|
||||
|
||||
mDirty=false;
|
||||
mForceClose = false;
|
||||
getChild<LLButton>(BTN_SAVE)->setEnabled(mDirty);
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::setPreferences( const LLSD& content )
|
||||
{
|
||||
S32 properties = mExperienceDetails[LLExperienceCache::PROPERTIES].asInteger();
|
||||
if (properties & LLExperienceCache::PROPERTY_PRIVILEGED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const LLSD& experiences = content["experiences"];
|
||||
const LLSD& blocked = content["blocked"];
|
||||
|
||||
|
||||
for(LLSD::array_const_iterator it = experiences.beginArray(); it != experiences.endArray() ; ++it)
|
||||
{
|
||||
if (it->asUUID()==mExperienceId)
|
||||
{
|
||||
experienceAllowed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(LLSD::array_const_iterator it = blocked.beginArray(); it != blocked.endArray() ; ++it)
|
||||
{
|
||||
if (it->asUUID()==mExperienceId)
|
||||
{
|
||||
experienceBlocked();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
experienceForgotten();
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onFieldChanged()
|
||||
{
|
||||
updatePackage();
|
||||
|
||||
if (!getChild<LLButton>(BTN_EDIT)->getVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLSD::map_const_iterator st = mExperienceDetails.beginMap();
|
||||
LLSD::map_const_iterator dt = mPackage.beginMap();
|
||||
|
||||
mDirty = false;
|
||||
while(!mDirty && st != mExperienceDetails.endMap() && dt != mPackage.endMap())
|
||||
{
|
||||
mDirty = st->first != dt->first || st->second.asString() != dt->second.asString();
|
||||
++st;++dt;
|
||||
}
|
||||
|
||||
if (!mDirty && (st != mExperienceDetails.endMap() || dt != mPackage.endMap()))
|
||||
{
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
getChild<LLButton>(BTN_SAVE)->setEnabled(mDirty);
|
||||
}
|
||||
|
||||
|
||||
BOOL LLFloaterExperienceProfile::canClose()
|
||||
{
|
||||
if (mForceClose || !mDirty)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bring up view-modal dialog: Save changes? Yes, No, Cancel
|
||||
LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLFloaterExperienceProfile::handleSaveChangesDialog, this, _1, _2, CLOSE));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterExperienceProfile::handleSaveChangesDialog( const LLSD& notification, const LLSD& response, PostSaveAction action )
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
switch( option )
|
||||
{
|
||||
case 0: // "Yes"
|
||||
// close after saving
|
||||
doSave( action );
|
||||
break;
|
||||
|
||||
case 1: // "No"
|
||||
if (action != NOTHING)
|
||||
{
|
||||
mForceClose = TRUE;
|
||||
if (action==CLOSE)
|
||||
{
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
changeToView();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // "Cancel"
|
||||
default:
|
||||
// If we were quitting, we didn't really mean it.
|
||||
LLAppViewer::instance()->abortQuit();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::doSave( int success_action )
|
||||
{
|
||||
mSaveCompleteAction=success_action;
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
LLExperienceCache::instance().updateExperience(mPackage, boost::bind(
|
||||
&LLFloaterExperienceProfile::experienceUpdateResult,
|
||||
getDerivedHandle<LLFloaterExperienceProfile>(), _1));
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onSaveComplete( const LLSD& content )
|
||||
{
|
||||
LLUUID id = getExperienceId();
|
||||
|
||||
if (content.has("removed"))
|
||||
{
|
||||
const LLSD& removed = content["removed"];
|
||||
LLSD::map_const_iterator it = removed.beginMap();
|
||||
for(/**/; it != removed.endMap(); ++it)
|
||||
{
|
||||
const std::string& field = it->first;
|
||||
if (field == LLExperienceCache::EXPERIENCE_ID)
|
||||
{
|
||||
//this message should be removed by the experience api
|
||||
continue;
|
||||
}
|
||||
const LLSD& data = it->second;
|
||||
std::string error_tag = data["error_tag"].asString()+ "ExperienceProfileMessage";
|
||||
LLSD fields;
|
||||
if (LLNotificationTemplates::instance().templateExists(error_tag))
|
||||
{
|
||||
fields["field"] = field;
|
||||
fields["extra_info"] = data["extra_info"];
|
||||
LLNotificationsUtil::add(error_tag, fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
fields["MESSAGE"] = data["en"];
|
||||
LLNotificationsUtil::add("GenericAlert", fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!content.has("experience_keys"))
|
||||
{
|
||||
LL_WARNS() << "LLFloaterExperienceProfile::onSaveComplete called with bad content" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
const LLSD& experiences = content["experience_keys"];
|
||||
|
||||
LLSD::array_const_iterator it = experiences.beginArray();
|
||||
if (it == experiences.endArray())
|
||||
{
|
||||
LL_WARNS() << "LLFloaterExperienceProfile::onSaveComplete called with empty content" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!it->has(LLExperienceCache::EXPERIENCE_ID) || ((*it)[LLExperienceCache::EXPERIENCE_ID].asUUID() != id))
|
||||
{
|
||||
LL_WARNS() << "LLFloaterExperienceProfile::onSaveComplete called with unexpected experience id" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
refreshExperience(*it);
|
||||
LLExperienceCache::instance().insert(*it);
|
||||
LLExperienceCache::instance().fetch(id, true);
|
||||
|
||||
if (mSaveCompleteAction == VIEW)
|
||||
{
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("tab_container");
|
||||
tabs->selectTabByName("panel_experience_info");
|
||||
}
|
||||
else if (mSaveCompleteAction == CLOSE)
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::changeToView()
|
||||
{
|
||||
if (mForceClose || !mDirty)
|
||||
{
|
||||
refreshExperience(mExperienceDetails);
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("tab_container");
|
||||
|
||||
tabs->selectTabByName("panel_experience_info");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bring up view-modal dialog: Save changes? Yes, No, Cancel
|
||||
LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLFloaterExperienceProfile::handleSaveChangesDialog, this, _1, _2, VIEW));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::changeToEdit()
|
||||
{
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("tab_container");
|
||||
|
||||
tabs->selectTabByName("edit_panel_experience_info");
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onClickLocation()
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
LLTextBox* child = getChild<LLTextBox>(EDIT TF_SLURL);
|
||||
mLocationSLURL = LLSLURL(region->getName(), gAgent.getPositionGlobal()).getSLURLString();
|
||||
child->setText(mLocationSLURL);
|
||||
onFieldChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onClickClear()
|
||||
{
|
||||
LLTextBox* child = getChild<LLTextBox>(EDIT TF_SLURL);
|
||||
mLocationSLURL.clear();
|
||||
child->setText(getString("empty_slurl"));
|
||||
onFieldChanged();
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::updatePermission(const LLSD& permission)
|
||||
{
|
||||
if (permission.has("experience"))
|
||||
{
|
||||
if (permission["experience"].asUUID() != mExperienceId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str = permission[mExperienceId.asString()]["permission"].asString();
|
||||
if (str == "Allow")
|
||||
{
|
||||
experienceAllowed();
|
||||
}
|
||||
else if (str == "Block")
|
||||
{
|
||||
experienceBlocked();
|
||||
}
|
||||
else if (str == "Forget")
|
||||
{
|
||||
experienceForgotten();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setPreferences(permission);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::experienceAllowed()
|
||||
{
|
||||
LLButton* button=getChild<LLButton>(BTN_ALLOW);
|
||||
button->setEnabled(FALSE);
|
||||
|
||||
button=getChild<LLButton>(BTN_FORGET);
|
||||
button->setEnabled(TRUE);
|
||||
|
||||
button=getChild<LLButton>(BTN_BLOCK);
|
||||
button->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::experienceForgotten()
|
||||
{
|
||||
LLButton* button=getChild<LLButton>(BTN_ALLOW);
|
||||
button->setEnabled(TRUE);
|
||||
|
||||
button=getChild<LLButton>(BTN_FORGET);
|
||||
button->setEnabled(FALSE);
|
||||
|
||||
button=getChild<LLButton>(BTN_BLOCK);
|
||||
button->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::experienceBlocked()
|
||||
{
|
||||
LLButton* button=getChild<LLButton>(BTN_ALLOW);
|
||||
button->setEnabled(TRUE);
|
||||
|
||||
button=getChild<LLButton>(BTN_FORGET);
|
||||
button->setEnabled(TRUE);
|
||||
|
||||
button=getChild<LLButton>(BTN_BLOCK);
|
||||
button->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onClose( bool app_quitting )
|
||||
{
|
||||
LLEventPumps::instance().obtain("experience_permission").stopListening(mExperienceId.asString()+"-profile");
|
||||
LLFloater::onClose(app_quitting);
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::updatePackage()
|
||||
{
|
||||
mPackage[LLExperienceCache::NAME] = getChild<LLLineEditor>(EDIT TF_NAME)->getText();
|
||||
mPackage[LLExperienceCache::DESCRIPTION] = getChild<LLTextEditor>(EDIT TF_DESC)->getText();
|
||||
if (mLocationSLURL.empty())
|
||||
{
|
||||
mPackage[LLExperienceCache::SLURL] = LLStringUtil::null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPackage[LLExperienceCache::SLURL] = mLocationSLURL;
|
||||
}
|
||||
|
||||
mPackage[LLExperienceCache::MATURITY] = getChild<LLComboBox>(EDIT TF_MATURITY)->getSelectedValue().asInteger();
|
||||
|
||||
LLSD metadata;
|
||||
|
||||
metadata[TF_MRKT] = getChild<LLLineEditor>(EDIT TF_MRKT)->getText();
|
||||
metadata[IMG_LOGO] = getChild<LLTextureCtrl>(EDIT IMG_LOGO)->getImageAssetID();
|
||||
|
||||
LLPointer<LLSDXMLFormatter> formatter = new LLSDXMLFormatter();
|
||||
|
||||
std::ostringstream os;
|
||||
if (formatter->format(metadata, os))
|
||||
{
|
||||
mPackage[LLExperienceCache::METADATA] = os.str();
|
||||
}
|
||||
|
||||
int properties = mPackage[LLExperienceCache::PROPERTIES].asInteger();
|
||||
LLCheckBoxCtrl* enable = getChild<LLCheckBoxCtrl>(EDIT BTN_ENABLE);
|
||||
if (enable->get())
|
||||
{
|
||||
properties &= ~LLExperienceCache::PROPERTY_DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
properties |= LLExperienceCache::PROPERTY_DISABLED;
|
||||
}
|
||||
|
||||
enable = getChild<LLCheckBoxCtrl>(EDIT BTN_PRIVATE);
|
||||
if (enable->get())
|
||||
{
|
||||
properties |= LLExperienceCache::PROPERTY_PRIVATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
properties &= ~LLExperienceCache::PROPERTY_PRIVATE;
|
||||
}
|
||||
|
||||
mPackage[LLExperienceCache::PROPERTIES] = properties;
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onPickGroup()
|
||||
{
|
||||
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
|
||||
|
||||
LLFloaterGroupPicker* widget = LLFloaterGroupPicker::showInstance(gAgent.getID());
|
||||
if (widget)
|
||||
{
|
||||
widget->setSelectGroupCallback(boost::bind(&LLFloaterExperienceProfile::setEditGroup, this, _1));
|
||||
if (parent_floater)
|
||||
{
|
||||
LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
|
||||
widget->setOrigin(new_rect.mLeft, new_rect.mBottom);
|
||||
parent_floater->addDependentFloater(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::setEditGroup( LLUUID group_id )
|
||||
{
|
||||
LLTextBox* child = getChild<LLTextBox>(EDIT TF_GROUP);
|
||||
std::string value = LLSLURL("group", group_id, "inspect").getSLURLString();
|
||||
child->setText(value);
|
||||
mPackage[LLExperienceCache::GROUP_ID] = group_id;
|
||||
onFieldChanged();
|
||||
}
|
||||
|
||||
void LLFloaterExperienceProfile::onReportExperience()
|
||||
{
|
||||
LLFloaterReporter::showFromExperience(mExperienceId);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool LLFloaterExperienceProfile::hasPermission(const LLSD& content, const std::string &name, const LLUUID &test)
|
||||
{
|
||||
if (!content.has(name))
|
||||
return false;
|
||||
|
||||
const LLSD& list = content[name];
|
||||
LLSD::array_const_iterator it = list.beginArray();
|
||||
while (it != list.endArray())
|
||||
{
|
||||
if (it->asUUID() == test)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLFloaterExperienceProfile::experiencePermissionResults(const LLUUID& exprienceId, const LLSD& result)
|
||||
{
|
||||
std::string permission("Forget");
|
||||
if (hasPermission(result, "experiences", exprienceId))
|
||||
permission = "Allow";
|
||||
else if (hasPermission(result, "blocked", exprienceId))
|
||||
permission = "Block";
|
||||
|
||||
LLSD experience;
|
||||
LLSD message;
|
||||
experience["permission"] = permission;
|
||||
message["experience"] = exprienceId;
|
||||
message[exprienceId.asString()] = experience;
|
||||
|
||||
LLEventPumps::instance().obtain("experience_permission").post(message);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLFloaterExperienceProfile::experienceIsAdmin(LLHandle<LLFloaterExperienceProfile> handle, const LLSD &result)
|
||||
{
|
||||
LLFloaterExperienceProfile* parent = handle.get();
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
bool enabled = true;
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string url = region->getCapability("UpdateExperience");
|
||||
if (url.empty())
|
||||
enabled = false;
|
||||
}
|
||||
if (enabled && result["status"].asBoolean())
|
||||
{
|
||||
parent->getChild<LLLayoutPanel>(PNL_TOP)->setVisible(TRUE);
|
||||
parent->getChild<LLButton>(BTN_EDIT)->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLFloaterExperienceProfile::experienceUpdateResult(LLHandle<LLFloaterExperienceProfile> handle, const LLSD &result)
|
||||
{
|
||||
LLFloaterExperienceProfile* parent = handle.get();
|
||||
if (parent)
|
||||
{
|
||||
parent->onSaveComplete(result);
|
||||
}
|
||||
}
|
||||
113
indra/newview/llfloaterexperienceprofile.h
Normal file
113
indra/newview/llfloaterexperienceprofile.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @file llfloaterexperienceprofile.h
|
||||
* @brief llfloaterexperienceprofile and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, 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_LLFLOATEREXPERIENCEPROFILE_H
|
||||
#define LL_LLFLOATEREXPERIENCEPROFILE_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lluuid.h"
|
||||
#include "llsd.h"
|
||||
|
||||
class LLLayoutPanel;
|
||||
class LLTextBox;
|
||||
class LLComboBox;
|
||||
|
||||
class LLFloaterExperienceProfile final : public LLFloater
|
||||
, public LLInstanceTracker<LLFloaterExperienceProfile, LLUUID>
|
||||
{
|
||||
LOG_CLASS(LLFloaterExperienceProfile);
|
||||
public:
|
||||
enum PostSaveAction
|
||||
{
|
||||
NOTHING,
|
||||
CLOSE,
|
||||
VIEW,
|
||||
};
|
||||
|
||||
static void experiencePermissionResults(const LLUUID& exprienceId, const LLSD& result);
|
||||
|
||||
static void showInstance(const LLSD& data);
|
||||
LLFloaterExperienceProfile(const LLSD& data);
|
||||
virtual ~LLFloaterExperienceProfile();
|
||||
|
||||
LLUUID getExperienceId() const { return mExperienceId; }
|
||||
void setPreferences( const LLSD& content );
|
||||
|
||||
|
||||
void refreshExperience(const LLSD& experience);
|
||||
void onSaveComplete( const LLSD& content );
|
||||
BOOL canClose() override;
|
||||
|
||||
void onClose(bool app_quitting) override;
|
||||
protected:
|
||||
void onClickEdit();
|
||||
void onClickPermission(const char* permission);
|
||||
void onClickForget();
|
||||
void onClickCancel();
|
||||
void onClickSave();
|
||||
void onClickLocation();
|
||||
void onClickClear();
|
||||
void onPickGroup();
|
||||
void onFieldChanged();
|
||||
void onReportExperience();
|
||||
|
||||
void setEditGroup(LLUUID group_id);
|
||||
|
||||
void changeToView();
|
||||
void changeToEdit();
|
||||
|
||||
void experienceForgotten();
|
||||
void experienceBlocked();
|
||||
void experienceAllowed();
|
||||
|
||||
static void experienceCallback(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& experience);
|
||||
static bool experiencePermission(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& permission);
|
||||
|
||||
BOOL postBuild() override;
|
||||
bool setMaturityString(U8 maturity, LLTextBox* child, LLComboBox* combo);
|
||||
bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response, PostSaveAction action);
|
||||
void doSave( int success_action );
|
||||
|
||||
void updatePackage();
|
||||
|
||||
void updatePermission( const LLSD& permission );
|
||||
LLUUID mExperienceId;
|
||||
LLSD mExperienceDetails;
|
||||
LLSD mPackage;
|
||||
std::string mLocationSLURL;
|
||||
int mSaveCompleteAction;
|
||||
bool mDirty;
|
||||
bool mForceClose;
|
||||
bool mPostEdit; // edit experience after opening and updating it
|
||||
private:
|
||||
static bool hasPermission(const LLSD& content, const std::string &name, const LLUUID &test);
|
||||
static void experienceIsAdmin(LLHandle<LLFloaterExperienceProfile> handle, const LLSD &result);
|
||||
static void experienceUpdateResult(LLHandle<LLFloaterExperienceProfile> handle, const LLSD &result);
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATEREXPERIENCEPROFILE_H
|
||||
377
indra/newview/llfloaterexperiences.cpp
Normal file
377
indra/newview/llfloaterexperiences.cpp
Normal file
@@ -0,0 +1,377 @@
|
||||
/**
|
||||
* @file llfloaterexperiences.cpp
|
||||
* @brief LLFloaterExperiences class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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 "llfloaterexperiences.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llcororesponder.h"
|
||||
#include "llevents.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llfloaterregioninfo.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelexperiencelog.h"
|
||||
#include "llpanelexperiencepicker.h"
|
||||
#include "llpanelexperiences.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "lltrans.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
|
||||
#define SHOW_RECENT_TAB (0)
|
||||
LLFloaterExperiences::LLFloaterExperiences(const LLSD& data)
|
||||
:LLFloater(data)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_experiences.xml", NULL, false);
|
||||
//buildFromFile("floater_experiences.xml");
|
||||
}
|
||||
|
||||
LLPanelExperiences* LLFloaterExperiences::addTab(const std::string& name, bool select)
|
||||
{
|
||||
LLPanelExperiences* newPanel = LLPanelExperiences::create(name);
|
||||
getChild<LLTabContainer>("xp_tabs")->addTabPanel(
|
||||
newPanel,
|
||||
LLTrans::getString(name),
|
||||
select);
|
||||
|
||||
return newPanel;
|
||||
}
|
||||
|
||||
BOOL LLFloaterExperiences::postBuild()
|
||||
{
|
||||
LLPanel* panel = new LLPanelExperiencePicker();
|
||||
getChild<LLTabContainer>("xp_tabs")->addTabPanel(panel, panel->getLabel());
|
||||
addTab("Allowed_Experiences_Tab", true);
|
||||
addTab("Blocked_Experiences_Tab", false);
|
||||
addTab("Admin_Experiences_Tab", false);
|
||||
addTab("Contrib_Experiences_Tab", false);
|
||||
LLPanelExperiences* owned = addTab("Owned_Experiences_Tab", false);
|
||||
owned->setButtonAction("acquire", boost::bind(&LLFloaterExperiences::sendPurchaseRequest, this));
|
||||
owned->enableButton(false);
|
||||
#if SHOW_RECENT_TAB
|
||||
addTab("Recent_Experiences_Tab", false);
|
||||
#endif //SHOW_RECENT_TAB
|
||||
panel = new LLPanelExperienceLog();
|
||||
getChild<LLTabContainer>("xp_tabs")->addTabPanel(panel, panel->getLabel());
|
||||
resizeToTabs();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperiences::clearFromRecent(const LLSD& ids)
|
||||
{
|
||||
#if SHOW_RECENT_TAB
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("xp_tabs");
|
||||
|
||||
LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName("Recent_Experiences_Tab");
|
||||
if(!tab)
|
||||
return;
|
||||
|
||||
tab->removeExperiences(ids);
|
||||
#endif // SHOW_RECENT_TAB
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::setupRecentTabs()
|
||||
{
|
||||
#if SHOW_RECENT_TAB
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("xp_tabs");
|
||||
|
||||
LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName("Recent_Experiences_Tab");
|
||||
if(!tab)
|
||||
return;
|
||||
|
||||
LLSD recent;
|
||||
|
||||
const LLExperienceCache::cache_t& experiences = LLExperienceCache::getCached();
|
||||
|
||||
LLExperienceCache::cache_t::const_iterator it = experiences.begin();
|
||||
while( it != experiences.end() )
|
||||
{
|
||||
if(!it->second.has(LLExperienceCache::MISSING))
|
||||
{
|
||||
recent.append(it->first);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
tab->setExperienceList(recent);
|
||||
#endif // SHOW_RECENT_TAB
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperiences::resizeToTabs()
|
||||
{
|
||||
const S32 TAB_WIDTH_PADDING = 16;
|
||||
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("xp_tabs");
|
||||
LLRect rect = getRect();
|
||||
if(rect.getWidth() < tabs->getTotalTabWidth() + TAB_WIDTH_PADDING)
|
||||
{
|
||||
rect.mRight = rect.mLeft + tabs->getTotalTabWidth() + TAB_WIDTH_PADDING;
|
||||
}
|
||||
reshape(rect.getWidth(), rect.getHeight(), FALSE);
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::refreshContents()
|
||||
{
|
||||
setupRecentTabs();
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
|
||||
if (region)
|
||||
{
|
||||
NameMap_t tabMap;
|
||||
LLHandle<LLFloaterExperiences> handle = getDerivedHandle<LLFloaterExperiences>();
|
||||
|
||||
tabMap["experiences"]="Allowed_Experiences_Tab";
|
||||
tabMap["blocked"]="Blocked_Experiences_Tab";
|
||||
tabMap["experience_ids"]="Owned_Experiences_Tab";
|
||||
|
||||
retrieveExperienceList(region->getCapability("GetExperiences"), handle, tabMap);
|
||||
|
||||
updateInfo("GetAdminExperiences","Admin_Experiences_Tab");
|
||||
updateInfo("GetCreatorExperiences","Contrib_Experiences_Tab");
|
||||
|
||||
retrieveExperienceList(region->getCapability("AgentExperiences"), handle, tabMap,
|
||||
"ExperienceAcquireFailed", boost::bind(&LLFloaterExperiences::checkPurchaseInfo, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::onOpen()
|
||||
{
|
||||
LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences");
|
||||
LLEventPumps::instance().obtain("experience_permission").listen("LLFloaterExperiences",
|
||||
boost::bind(&LLFloaterExperiences::updatePermissions, this, _1));
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if(region)
|
||||
{
|
||||
if(region->capabilitiesReceived())
|
||||
{
|
||||
refreshContents();
|
||||
return;
|
||||
}
|
||||
region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterExperiences::refreshContents, this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterExperiences::updatePermissions( const LLSD& permission )
|
||||
{
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("xp_tabs");
|
||||
LLUUID experience;
|
||||
std::string permission_string;
|
||||
if(permission.has("experience"))
|
||||
{
|
||||
experience = permission["experience"].asUUID();
|
||||
permission_string = permission[experience.asString()]["permission"].asString();
|
||||
|
||||
}
|
||||
LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName("Allowed_Experiences_Tab");
|
||||
if(tab)
|
||||
{
|
||||
if(permission.has("experiences"))
|
||||
{
|
||||
tab->setExperienceList(permission["experiences"]);
|
||||
}
|
||||
else if(experience.notNull())
|
||||
{
|
||||
if(permission_string != "Allow")
|
||||
{
|
||||
tab->removeExperience(experience);
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->addExperience(experience);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tab = (LLPanelExperiences*)tabs->getPanelByName("Blocked_Experiences_Tab");
|
||||
if(tab)
|
||||
{
|
||||
if(permission.has("blocked"))
|
||||
{
|
||||
tab->setExperienceList(permission["blocked"]);
|
||||
}
|
||||
else if(experience.notNull())
|
||||
{
|
||||
if(permission_string != "Block")
|
||||
{
|
||||
tab->removeExperience(experience);
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->addExperience(experience);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::onClose( bool app_quitting )
|
||||
{
|
||||
LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences");
|
||||
LLFloater::onClose(app_quitting);
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::checkPurchaseInfo(LLPanelExperiences* panel, const LLSD& content) const
|
||||
{
|
||||
panel->enableButton(content.has("purchase"));
|
||||
|
||||
LLFloaterExperiences::findInstance()->updateInfo("GetAdminExperiences","Admin_Experiences_Tab");
|
||||
LLFloaterExperiences::findInstance()->updateInfo("GetCreatorExperiences","Contrib_Experiences_Tab");
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::checkAndOpen(LLPanelExperiences* panel, const LLSD& content) const
|
||||
{
|
||||
checkPurchaseInfo(panel, content);
|
||||
|
||||
// determine new item
|
||||
const LLSD& response_ids = content["experience_ids"];
|
||||
|
||||
if (mPrepurchaseIds.size() + 1 == response_ids.size())
|
||||
{
|
||||
// we have a new element
|
||||
for (LLSD::array_const_iterator it = response_ids.beginArray(); it != response_ids.endArray(); ++it)
|
||||
{
|
||||
LLUUID experience_id = it->asUUID();
|
||||
if (std::find(mPrepurchaseIds.begin(), mPrepurchaseIds.end(), experience_id) == mPrepurchaseIds.end())
|
||||
{
|
||||
// new element found, open it
|
||||
LLSD args;
|
||||
args["experience_id"] = experience_id;
|
||||
args["edit_experience"] = true;
|
||||
LLFloaterExperienceProfile::showInstance(args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::updateInfo(std::string experienceCap, std::string tab)
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
NameMap_t tabMap;
|
||||
LLHandle<LLFloaterExperiences> handle = getDerivedHandle<LLFloaterExperiences>();
|
||||
|
||||
tabMap["experience_ids"] = tab;
|
||||
|
||||
retrieveExperienceList(region->getCapability(experienceCap), handle, tabMap);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::sendPurchaseRequest()
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
|
||||
if (region)
|
||||
{
|
||||
NameMap_t tabMap;
|
||||
const std::string tab_owned_name = "Owned_Experiences_Tab";
|
||||
LLHandle<LLFloaterExperiences> handle = getDerivedHandle<LLFloaterExperiences>();
|
||||
|
||||
tabMap["experience_ids"] = tab_owned_name;
|
||||
|
||||
// extract ids for experiences that we already have
|
||||
LLTabContainer* tabs = getChild<LLTabContainer>("xp_tabs");
|
||||
LLPanelExperiences* tab_owned = (LLPanelExperiences*)tabs->getPanelByName(tab_owned_name);
|
||||
mPrepurchaseIds.clear();
|
||||
if (tab_owned)
|
||||
{
|
||||
tab_owned->getExperienceIdsList(mPrepurchaseIds);
|
||||
}
|
||||
|
||||
requestNewExperience(region->getCapability("AgentExperiences"), handle, tabMap, "ExperienceAcquireFailed",
|
||||
boost::bind(&LLFloaterExperiences::checkAndOpen, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperiences::retrieveExperienceList(const std::string &url,
|
||||
const LLHandle<LLFloaterExperiences> &hparent, const NameMap_t &tabMapping,
|
||||
const std::string &errorNotify, Callback_t cback, bool post)
|
||||
{
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS() << "retrieveExperienceListCoro called with empty capability!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
auto responder = new LLCoroResponder(
|
||||
boost::bind(LLFloaterExperiences::retrieveExperienceListCoro, _1,
|
||||
hparent, tabMapping, errorNotify, cback));
|
||||
|
||||
if (post)
|
||||
LLHTTPClient::post(url, LLSD(), responder);
|
||||
else
|
||||
LLHTTPClient::get(url, responder);
|
||||
}
|
||||
|
||||
void LLFloaterExperiences::retrieveExperienceListCoro(const LLCoroResponder& responder,
|
||||
LLHandle<LLFloaterExperiences> hparent, NameMap_t tabMapping,
|
||||
std::string errorNotify, Callback_t cback)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
LLSD subs;
|
||||
subs["ERROR_MESSAGE"] = responder.getReason();
|
||||
LLNotificationsUtil::add(errorNotify, subs);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (hparent.isDead())
|
||||
return;
|
||||
|
||||
LLFloaterExperiences* parent = hparent.get();
|
||||
LLTabContainer* tabs = parent->getChild<LLTabContainer>("xp_tabs");
|
||||
|
||||
for (auto& it : tabMapping)
|
||||
{
|
||||
if (result.has(it.first))
|
||||
{
|
||||
LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName(it.second);
|
||||
if (tab)
|
||||
{
|
||||
const LLSD& ids = result[it.first];
|
||||
tab->setExperienceList(ids);
|
||||
if (cback != nullptr)
|
||||
{
|
||||
cback(tab, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
78
indra/newview/llfloaterexperiences.h
Normal file
78
indra/newview/llfloaterexperiences.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file llfloaterexperiences.h
|
||||
* @brief LLFloaterExperiences class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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_LLFLOATEREXPERIENCES_H
|
||||
#define LL_LLFLOATEREXPERIENCES_H
|
||||
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLPanelExperiences;
|
||||
|
||||
class LLFloaterExperiences final :
|
||||
public LLFloater
|
||||
, public LLFloaterSingleton<LLFloaterExperiences>
|
||||
{
|
||||
friend class LLUISingleton<LLFloaterExperiences, VisibilityPolicy<LLFloater> >;
|
||||
public:
|
||||
LLFloaterExperiences(const LLSD& data);
|
||||
void onClose(bool app_quitting) override;
|
||||
|
||||
void onOpen(/*const LLSD& key*/) override;
|
||||
|
||||
protected:
|
||||
typedef std::map<std::string, std::string> NameMap_t;
|
||||
typedef std::function<void(LLPanelExperiences*, const LLSD&)> Callback_t;
|
||||
|
||||
void clearFromRecent(const LLSD& ids);
|
||||
void resizeToTabs();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
void refreshContents();
|
||||
void setupRecentTabs();
|
||||
LLPanelExperiences* addTab(const std::string& name, bool select);
|
||||
|
||||
bool updatePermissions(const LLSD& permission);
|
||||
void sendPurchaseRequest();
|
||||
void checkPurchaseInfo(LLPanelExperiences* panel, const LLSD& content)const;
|
||||
void checkAndOpen(LLPanelExperiences* panel, const LLSD& content) const;
|
||||
void updateInfo(std::string experiences, std::string tab);
|
||||
|
||||
void retrieveExperienceList(const std::string &url, const LLHandle<LLFloaterExperiences> &hparent, const NameMap_t &tabMapping,
|
||||
const std::string &errorNotify = std::string("ErrorMessage"), Callback_t cback = Callback_t(), bool post = false);
|
||||
|
||||
void requestNewExperience(const std::string &url, const LLHandle<LLFloaterExperiences> &hparent, const NameMap_t &tabMapping,
|
||||
const std::string &errorNotify, Callback_t cback)
|
||||
{
|
||||
retrieveExperienceList(url, hparent, tabMapping, errorNotify, cback, true);
|
||||
}
|
||||
|
||||
private:
|
||||
static void retrieveExperienceListCoro(const struct LLCoroResponder& responder, LLHandle<LLFloaterExperiences> hparent,
|
||||
NameMap_t tabMapping, std::string errorNotify, Callback_t cback);
|
||||
uuid_vec_t mPrepurchaseIds;
|
||||
};
|
||||
|
||||
#endif //LL_LLFLOATEREXPERIENCES_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,43 +3,33 @@
|
||||
* @author James Cook
|
||||
* @brief "About Land" floater, allowing display and editing of land parcel properties.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERLAND_H
|
||||
#define LL_LLFLOATERLAND_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llpointer.h" // LLPointer<>
|
||||
//#include "llviewertexturelist.h"
|
||||
#include "llsafehandle.h"
|
||||
|
||||
const F32 CACHE_REFRESH_TIME = 2.5f;
|
||||
@@ -49,6 +39,7 @@ class LLCheckBoxCtrl;
|
||||
class LLRadioGroup;
|
||||
class LLComboBox;
|
||||
class LLLineEditor;
|
||||
class LLMessageSystem;
|
||||
class LLNameListCtrl;
|
||||
class LLRadioGroup;
|
||||
class LLParcelSelectionObserver;
|
||||
@@ -58,7 +49,6 @@ class LLTextBox;
|
||||
class LLTextEditor;
|
||||
class LLTextureCtrl;
|
||||
class LLUIImage;
|
||||
class LLViewerTextEditor;
|
||||
class LLParcelSelection;
|
||||
|
||||
class LLPanelLandGeneral;
|
||||
@@ -71,9 +61,11 @@ class LLPanelLandBan;
|
||||
class LLPanelLandRenters;
|
||||
class LLPanelLandCovenant;
|
||||
class LLParcel;
|
||||
class LLPanelLandExperiences;
|
||||
|
||||
class LLFloaterLand
|
||||
: public LLFloater, public LLFloaterSingleton<LLFloaterLand>
|
||||
class LLFloaterLand final
|
||||
: public LLFloater
|
||||
, public LLFloaterSingleton<LLFloaterLand>
|
||||
{
|
||||
friend class LLUISingleton<LLFloaterLand, VisibilityPolicy<LLFloater> >;
|
||||
public:
|
||||
@@ -85,24 +77,23 @@ public:
|
||||
LLParcel* getCurrentSelectedParcel();
|
||||
|
||||
// Destroys itself on close.
|
||||
virtual void onClose(bool app_quitting);
|
||||
virtual void onOpen();
|
||||
virtual BOOL postBuild();
|
||||
void onClose(bool app_quitting) override;
|
||||
void onOpen() override;
|
||||
BOOL postBuild() override;
|
||||
|
||||
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
|
||||
virtual void open();
|
||||
void open() override;
|
||||
// [/RLVa:KB]
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Does its own instance management, so clients not allowed
|
||||
// to allocate or destroy.
|
||||
LLFloaterLand(const LLSD& seed);
|
||||
virtual ~LLFloaterLand();
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
protected:
|
||||
|
||||
/*virtual*/ void refresh() override;
|
||||
|
||||
static void* createPanelLandGeneral(void* data);
|
||||
static void* createPanelLandCovenant(void* data);
|
||||
@@ -111,12 +102,15 @@ protected:
|
||||
static void* createPanelLandAudio(void* data);
|
||||
static void* createPanelLandMedia(void* data);
|
||||
static void* createPanelLandAccess(void* data);
|
||||
static void* createPanelLandExperiences(void* data);
|
||||
static void* createPanelLandBan(void* data);
|
||||
|
||||
|
||||
protected:
|
||||
static LLParcelSelectionObserver* sObserver;
|
||||
static S32 sLastTab;
|
||||
|
||||
friend class LLPanelLandObjects;
|
||||
LLTabContainer* mTabLand;
|
||||
LLPanelLandGeneral* mPanelGeneral;
|
||||
LLPanelLandObjects* mPanelObjects;
|
||||
@@ -125,6 +119,7 @@ protected:
|
||||
LLPanelLandMedia* mPanelMedia;
|
||||
LLPanelLandAccess* mPanelAccess;
|
||||
LLPanelLandCovenant* mPanelCovenant;
|
||||
LLPanelLandExperiences* mPanelExperiences;
|
||||
|
||||
LLSafeHandle<LLParcelSelection> mParcel;
|
||||
|
||||
@@ -137,25 +132,25 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class LLPanelLandGeneral
|
||||
class LLPanelLandGeneral final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelLandGeneral(LLSafeHandle<LLParcelSelection>& parcelp);
|
||||
virtual ~LLPanelLandGeneral();
|
||||
/*virtual*/ void refresh();
|
||||
/*virtual*/ void refresh() override;
|
||||
void refreshNames();
|
||||
|
||||
void setGroup(const LLUUID& group_id);
|
||||
void onClickSetGroup();
|
||||
static void onClickDeed(void*);
|
||||
static void onClickBuyLand(void* data);
|
||||
static void onClickScriptLimits(void* data);
|
||||
static void onClickRelease(void*);
|
||||
static void onClickReclaim(void*);
|
||||
static void onClickBuyPass(void* deselect_when_done);
|
||||
void onClickDeed();
|
||||
void onClickScriptLimits();
|
||||
void onClickRelease();
|
||||
void onClickReclaim();
|
||||
static BOOL enableBuyPass(void*);
|
||||
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
|
||||
void onCommitAny();
|
||||
static void finalizeCommit(void * userdata);
|
||||
static void onForSaleChange(LLUICtrl *ctrl, void * userdata);
|
||||
static void finalizeSetSellChange(void * userdata);
|
||||
@@ -163,20 +158,20 @@ public:
|
||||
|
||||
static bool cbBuyPass(const LLSD& notification, const LLSD& response);
|
||||
|
||||
static void onClickSellLand(void* data);
|
||||
static void onClickStopSellLand(void* data);
|
||||
static void onClickSet(void* data);
|
||||
static void onClickClear(void* data);
|
||||
static void onClickShow(void* data);
|
||||
void onClickSellLand();
|
||||
void onClickStopSellLand();
|
||||
void onClickSet();
|
||||
void onClickClear();
|
||||
void onClickShow();
|
||||
static void callbackAvatarPick(const std::vector<std::string>& names, const uuid_vec_t& ids, void* data);
|
||||
static void finalizeAvatarPick(void* data);
|
||||
static void callbackHighlightTransferable(S32 option, void* userdata);
|
||||
static void onClickStartAuction(void*);
|
||||
void onClickStartAuction();
|
||||
// sale change confirmed when "is for sale", "sale price", "sell to whom" fields are changed
|
||||
static void confirmSaleChange(S32 landSize, S32 salePrice, std::string authorizedName, void(*callback)(void*), void* userdata);
|
||||
static void callbackConfirmSaleChange(S32 option, void* userdata);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
BOOL postBuild() override;
|
||||
|
||||
protected:
|
||||
LLLineEditor* mEditName;
|
||||
@@ -235,36 +230,36 @@ protected:
|
||||
static LLHandle<LLFloater> sBuyPassDialogHandle;
|
||||
};
|
||||
|
||||
class LLPanelLandObjects
|
||||
class LLPanelLandObjects final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelLandObjects(LLSafeHandle<LLParcelSelection>& parcelp);
|
||||
virtual ~LLPanelLandObjects();
|
||||
/*virtual*/ void refresh();
|
||||
/*virtual*/ void refresh() override;
|
||||
|
||||
bool callbackReturnOwnerObjects(const LLSD& notification, const LLSD& response);
|
||||
bool callbackReturnGroupObjects(const LLSD& notification, const LLSD& response);
|
||||
bool callbackReturnOtherObjects(const LLSD& notification, const LLSD& response);
|
||||
bool callbackReturnOwnerList(const LLSD& notification, const LLSD& response);
|
||||
|
||||
static void clickShowCore(LLPanelLandObjects* panelp, S32 return_type, uuid_list_t* list = 0);
|
||||
static void onClickShowOwnerObjects(void*);
|
||||
static void onClickShowGroupObjects(void*);
|
||||
static void onClickShowOtherObjects(void*);
|
||||
static void clickShowCore(LLPanelLandObjects* panelp, S32 return_type, uuid_list_t* list = nullptr);
|
||||
void onClickShowOwnerObjects();
|
||||
void onClickShowGroupObjects();
|
||||
void onClickShowOtherObjects();
|
||||
|
||||
static void onClickReturnOwnerObjects(void*);
|
||||
static void onClickReturnGroupObjects(void*);
|
||||
static void onClickReturnOtherObjects(void*);
|
||||
static void onClickReturnOwnerList(void*);
|
||||
static void onClickRefresh(void*);
|
||||
void onClickReturnOwnerObjects();
|
||||
void onClickReturnGroupObjects();
|
||||
void onClickReturnOtherObjects();
|
||||
void onClickReturnOwnerList();
|
||||
void onClickRefresh();
|
||||
|
||||
void onCommitList();
|
||||
static void onLostFocus(LLFocusableElement* caller, void* user_data);
|
||||
static void onCommitClean(LLUICtrl* caller, void* user_data);
|
||||
void onCommitClean();
|
||||
static void processParcelObjectOwnersReply(LLMessageSystem *msg, void **);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
BOOL postBuild() override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -304,23 +299,23 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class LLPanelLandOptions
|
||||
class LLPanelLandOptions final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelLandOptions(LLSafeHandle<LLParcelSelection>& parcelp);
|
||||
virtual ~LLPanelLandOptions();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void refresh();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
/*virtual*/ void draw() override;
|
||||
/*virtual*/ void refresh() override;
|
||||
|
||||
private:
|
||||
// Refresh the "show in search" checkbox and category selector.
|
||||
void refreshSearch();
|
||||
|
||||
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
|
||||
static void onClickSet(void* userdata);
|
||||
static void onClickClear(void* userdata);
|
||||
void onCommitAny();
|
||||
void onClickSet();
|
||||
void onClickClear();
|
||||
static void onClickPublishHelp(void*);
|
||||
|
||||
private:
|
||||
@@ -355,24 +350,24 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class LLPanelLandAccess
|
||||
class LLPanelLandAccess final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelLandAccess(LLSafeHandle<LLParcelSelection>& parcelp);
|
||||
virtual ~LLPanelLandAccess();
|
||||
void refresh();
|
||||
void refresh() override;
|
||||
void refresh_ui();
|
||||
void refreshNames();
|
||||
virtual void draw();
|
||||
void draw() override;
|
||||
|
||||
static void onCommitPublicAccess(LLUICtrl* ctrl, void *userdata);
|
||||
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
|
||||
static void onCommitGroupCheck(LLUICtrl* ctrl, void *userdata);
|
||||
static void onClickRemoveAccess(void*);
|
||||
static void onClickRemoveBanned(void*);
|
||||
void onCommitPublicAccess(LLUICtrl* ctrl);
|
||||
void onCommitAny();
|
||||
void onCommitGroupCheck(LLUICtrl* ctrl);
|
||||
void onClickRemoveAccess();
|
||||
void onClickRemoveBanned();
|
||||
|
||||
virtual BOOL postBuild();
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onClickAddAccess();
|
||||
void onClickAddBanned();
|
||||
@@ -387,15 +382,14 @@ protected:
|
||||
LLSafeHandle<LLParcelSelection>& mParcel;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelLandCovenant
|
||||
class LLPanelLandCovenant final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelLandCovenant(LLSafeHandle<LLParcelSelection>& parcelp);
|
||||
virtual ~LLPanelLandCovenant();
|
||||
virtual BOOL postBuild();
|
||||
void refresh();
|
||||
BOOL postBuild() override;
|
||||
void refresh() override;
|
||||
static void updateCovenantText(const std::string& string);
|
||||
static void updateEstateName(const std::string& name);
|
||||
static void updateLastModified(const std::string& text);
|
||||
@@ -403,6 +397,10 @@ public:
|
||||
|
||||
protected:
|
||||
LLSafeHandle<LLParcelSelection>& mParcel;
|
||||
|
||||
private:
|
||||
LLUUID mLastRegionID;
|
||||
F64 mNextUpdateTime; //seconds since client start
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "llavataractions.h"
|
||||
#include "llbutton.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcororesponder.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventoryobserver.h"
|
||||
@@ -51,8 +53,8 @@
|
||||
#include "llradiogroup.h"
|
||||
#include "llresmgr.h"
|
||||
#include "roles_constants.h"
|
||||
#include "llnamebox.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
@@ -64,11 +66,6 @@
|
||||
#include "lfsimfeaturehandler.h"
|
||||
#include "hippogridmanager.h"
|
||||
|
||||
|
||||
// [RLVa:KB]
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
bool can_set_export(const U32& base, const U32& own, const U32& next);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -81,7 +78,7 @@ bool can_set_export(const U32& base, const U32& own, const U32& next);
|
||||
// from the inventory observer list when destroyed, which could
|
||||
// happen after gInventory has already been destroyed if a singleton.
|
||||
// Instead, do our own ref counting and create / destroy it as needed
|
||||
class LLPropertiesObserver : public LLInventoryObserver
|
||||
class LLPropertiesObserver final : public LLInventoryObserver
|
||||
{
|
||||
public:
|
||||
LLPropertiesObserver(LLFloaterProperties* floater)
|
||||
@@ -93,9 +90,10 @@ public:
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
void changed(U32 mask) override;
|
||||
private:
|
||||
LLFloaterProperties* mFloater;
|
||||
LLFloaterProperties* mFloater; // Not a handle because LLFloaterProperties is managing LLPropertiesObserver
|
||||
};
|
||||
|
||||
void LLPropertiesObserver::changed(U32 mask)
|
||||
@@ -154,7 +152,7 @@ LLFloaterProperties::LLFloaterProperties(const std::string& name, const LLRect&
|
||||
LLFloaterProperties::~LLFloaterProperties()
|
||||
{
|
||||
delete mPropertiesObserver;
|
||||
mPropertiesObserver = NULL;
|
||||
mPropertiesObserver = nullptr;
|
||||
}
|
||||
|
||||
// virtual
|
||||
@@ -216,7 +214,7 @@ void LLFloaterProperties::refresh()
|
||||
|
||||
mDirty = TRUE;
|
||||
|
||||
const char* enableNames[]={
|
||||
static constexpr std::array<const char*, 21> enableNames{{
|
||||
"LabelItemName",
|
||||
"LabelItemDesc",
|
||||
"LabelCreatorName",
|
||||
@@ -238,21 +236,21 @@ void LLFloaterProperties::refresh()
|
||||
"CheckPurchase",
|
||||
"RadioSaleType",
|
||||
"Edit Cost"
|
||||
};
|
||||
for(size_t t=0; t<LL_ARRAY_SIZE(enableNames); ++t)
|
||||
}};
|
||||
for(const char* name : enableNames)
|
||||
{
|
||||
getChildView(enableNames[t])->setEnabled(false);
|
||||
getChildView(name)->setEnabled(false);
|
||||
}
|
||||
const char* hideNames[]={
|
||||
static constexpr std::array<const char*,5> hideNames{{
|
||||
"BaseMaskDebug",
|
||||
"OwnerMaskDebug",
|
||||
"GroupMaskDebug",
|
||||
"EveryoneMaskDebug",
|
||||
"NextMaskDebug"
|
||||
};
|
||||
for(size_t t=0; t<LL_ARRAY_SIZE(hideNames); ++t)
|
||||
}};
|
||||
for(const char* name : hideNames)
|
||||
{
|
||||
getChildView(hideNames[t])->setVisible(false);
|
||||
getChildView(name)->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +288,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
||||
|
||||
// You need permission to modify the object to modify an inventory
|
||||
// item in it.
|
||||
LLViewerObject* object = NULL;
|
||||
LLViewerObject* object = nullptr;
|
||||
if(!mObjectID.isNull()) object = gObjectList.findObject(mObjectID);
|
||||
BOOL is_obj_modify = TRUE;
|
||||
if(object)
|
||||
@@ -298,6 +296,21 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
||||
is_obj_modify = object->permOwnerModify();
|
||||
}
|
||||
|
||||
if (item->getInventoryType() == LLInventoryType::IT_LSL)
|
||||
{
|
||||
getChildView("LabelItemExperienceTitle")->setVisible(TRUE);
|
||||
LLTextBox* tb = getChild<LLTextBox>("LabelItemExperience");
|
||||
tb->setText(getString("loading_experience"));
|
||||
tb->setVisible(TRUE);
|
||||
std::string url = std::string();
|
||||
if(object && object->getRegion())
|
||||
{
|
||||
url = object->getRegion()->getCapability("GetMetadata");
|
||||
}
|
||||
LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), url,
|
||||
boost::bind(&LLFloaterProperties::setAssociatedExperience, getDerivedHandle<LLFloaterProperties>(), _1));
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// ITEM NAME & DESC //
|
||||
//////////////////////
|
||||
@@ -403,11 +416,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
||||
getChild<LLUICtrl>("CheckOwnerCopy")->setValue(LLSD((BOOL)(owner_mask & PERM_COPY)));
|
||||
getChildView("CheckOwnerTransfer")->setEnabled(FALSE);
|
||||
getChild<LLUICtrl>("CheckOwnerTransfer")->setValue(LLSD((BOOL)(owner_mask & PERM_TRANSFER)));
|
||||
getChildView("CheckOwnerExport")->setEnabled(FALSE);
|
||||
getChild<LLUICtrl>("CheckOwnerExport")->setValue(LLSD((BOOL)(owner_mask & PERM_EXPORT)));
|
||||
|
||||
bool supports_export = LFSimFeatureHandler::instance().simSupportsExport();
|
||||
getChildView("CheckOwnerExport")->setEnabled(false);
|
||||
getChild<LLUICtrl>("CheckOwnerExport")->setValue(LLSD((BOOL)(supports_export && owner_mask & PERM_EXPORT)));
|
||||
if (!gHippoGridManager->getCurrentGrid()->isSecondLife())
|
||||
if (!supports_export)
|
||||
getChildView("CheckOwnerExport")->setVisible(false);
|
||||
|
||||
///////////////////////
|
||||
@@ -520,6 +533,9 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
||||
|
||||
const LLSaleInfo& sale_info = item->getSaleInfo();
|
||||
BOOL is_for_sale = sale_info.isForSale();
|
||||
LLRadioGroup* radioSaleType = getChild<LLRadioGroup>("RadioSaleType");
|
||||
LLUICtrl* edit_cost = getChild<LLUICtrl>("Edit Cost");
|
||||
|
||||
// Check for ability to change values.
|
||||
if (is_obj_modify && can_agent_sell
|
||||
&& gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
|
||||
@@ -533,9 +549,9 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
||||
getChildView("CheckNextOwnerCopy")->setEnabled(no_export && (base_mask & PERM_COPY) && !cannot_restrict_permissions);
|
||||
getChildView("CheckNextOwnerTransfer")->setEnabled(no_export && (next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
|
||||
|
||||
getChildView("RadioSaleType")->setEnabled(is_complete && is_for_sale);
|
||||
radioSaleType->setEnabled(is_complete && is_for_sale);
|
||||
getChildView("TextPrice")->setEnabled(is_complete && is_for_sale);
|
||||
getChildView("Edit Cost")->setEnabled(is_complete && is_for_sale);
|
||||
edit_cost->setEnabled(is_complete && is_for_sale);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -547,30 +563,55 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
||||
getChildView("CheckNextOwnerCopy")->setEnabled(FALSE);
|
||||
getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE);
|
||||
|
||||
getChildView("RadioSaleType")->setEnabled(FALSE);
|
||||
radioSaleType->setEnabled(FALSE);
|
||||
getChildView("TextPrice")->setEnabled(FALSE);
|
||||
getChildView("Edit Cost")->setEnabled(FALSE);
|
||||
edit_cost->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// Set values.
|
||||
getChild<LLUICtrl>("CheckPurchase")->setValue(is_for_sale);
|
||||
getChildView("Edit Cost")->setEnabled(is_for_sale);
|
||||
edit_cost->setEnabled(is_for_sale);
|
||||
getChild<LLUICtrl>("CheckNextOwnerModify")->setValue(LLSD(BOOL(next_owner_mask & PERM_MODIFY)));
|
||||
getChild<LLUICtrl>("CheckNextOwnerCopy")->setValue(LLSD(BOOL(next_owner_mask & PERM_COPY)));
|
||||
getChild<LLUICtrl>("CheckNextOwnerTransfer")->setValue(LLSD(BOOL(next_owner_mask & PERM_TRANSFER)));
|
||||
|
||||
LLRadioGroup* radioSaleType = getChild<LLRadioGroup>("RadioSaleType");
|
||||
if (is_for_sale)
|
||||
{
|
||||
radioSaleType->setSelectedIndex((S32)sale_info.getSaleType() - 1);
|
||||
S32 numerical_price;
|
||||
numerical_price = sale_info.getSalePrice();
|
||||
getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",numerical_price));
|
||||
edit_cost->setValue(llformat("%d",numerical_price));
|
||||
radioSaleType->setSelectedIndex((S32)sale_info.getSaleType() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
edit_cost->setValue("0");
|
||||
radioSaleType->setSelectedIndex(-1);
|
||||
getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterProperties::setAssociatedExperience(LLHandle<LLFloaterProperties> hInfo, const LLSD& experience)
|
||||
{
|
||||
LLFloaterProperties* info = hInfo.get();
|
||||
if(info)
|
||||
{
|
||||
LLUUID id;
|
||||
if (experience.has(LLExperienceCache::EXPERIENCE_ID))
|
||||
{
|
||||
id = experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
|
||||
}
|
||||
if (id.notNull())
|
||||
{
|
||||
//info->getChild<LLTextBox>("LabelItemExperience")->setText(LLSLURL("experience", id, "profile").getSLURLString();
|
||||
if (LLNameBox* tb = info->getChild<LLNameBox>("LabelItemExperience"))
|
||||
{
|
||||
tb->setValue(id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info->getChild<LLTextBox>("LabelItemExperience")->setText(LLTrans::getString("ExperienceNameNull"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,11 +728,6 @@ void LLFloaterProperties::onCommitPermissions()
|
||||
perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(),
|
||||
CheckEveryoneCopy->get(), PERM_COPY);
|
||||
}
|
||||
LLCheckBoxCtrl* CheckExport = getChild<LLCheckBoxCtrl>("CheckExport");
|
||||
if(CheckExport)
|
||||
{
|
||||
perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(), CheckExport->get(), PERM_EXPORT);
|
||||
}
|
||||
|
||||
LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
|
||||
if(CheckNextOwnerModify)
|
||||
@@ -711,6 +747,13 @@ void LLFloaterProperties::onCommitPermissions()
|
||||
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
|
||||
CheckNextOwnerTransfer->get(), PERM_TRANSFER);
|
||||
}
|
||||
|
||||
LLCheckBoxCtrl* CheckExport = getChild<LLCheckBoxCtrl>("CheckExport");
|
||||
if(CheckExport && CheckExport->getVisible())
|
||||
{
|
||||
perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(), CheckExport->get(), PERM_EXPORT);
|
||||
}
|
||||
|
||||
if(perm != item->getPermissions()
|
||||
&& item->isFinished())
|
||||
{
|
||||
@@ -884,7 +927,7 @@ void LLFloaterProperties::updateSaleInfo()
|
||||
|
||||
LLInventoryItem* LLFloaterProperties::findItem() const
|
||||
{
|
||||
LLInventoryItem* item = NULL;
|
||||
LLInventoryItem* item = nullptr;
|
||||
if(mObjectID.isNull())
|
||||
{
|
||||
// it is in agent inventory
|
||||
|
||||
@@ -86,6 +86,8 @@ protected:
|
||||
void refreshFromItem(LLInventoryItem* item);
|
||||
virtual void draw();
|
||||
|
||||
static void setAssociatedExperience(LLHandle<LLFloaterProperties> hInfo, const LLSD& experience);
|
||||
|
||||
protected:
|
||||
// The item id of the inventory item in question.
|
||||
LLUUID mItemID;
|
||||
|
||||
@@ -3,31 +3,25 @@
|
||||
* @author Aaron Brashears
|
||||
* @brief Implementation of the region info and controls floater and panels.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -65,6 +59,7 @@
|
||||
#include "llfloaterregiondebugconsole.h"
|
||||
#include "llfloatertelehub.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lllayoutstack.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llnamelistctrl.h"
|
||||
#include "llnotifications.h"
|
||||
@@ -88,6 +83,11 @@
|
||||
#include "llvlcomposition.h"
|
||||
#include "llwaterparammanager.h"
|
||||
#include "llagentui.h"
|
||||
#include "llpanelexperiencelisteditor.h"
|
||||
#include <boost/function.hpp>
|
||||
#include "llpanelexperiencepicker.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llpanelexperiences.h"
|
||||
#include "hippogridmanager.h"
|
||||
// [RLVa:KB]
|
||||
#include "rlvhandler.h"
|
||||
@@ -126,6 +126,18 @@ public:
|
||||
const sparam_t& strings);
|
||||
};
|
||||
|
||||
class LLDispatchSetEstateExperience : public LLDispatchHandler
|
||||
{
|
||||
public:
|
||||
virtual bool operator()(
|
||||
const LLDispatcher* dispatcher,
|
||||
const std::string& key,
|
||||
const LLUUID& invoice,
|
||||
const sparam_t& strings);
|
||||
|
||||
LLSD getIDs(sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
void unpack_request_params(
|
||||
@@ -256,6 +268,13 @@ BOOL LLFloaterRegionInfo::postBuild()
|
||||
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml");
|
||||
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
|
||||
|
||||
if (!gAgent.getRegion()->getCapability("RegionExperiences").empty())
|
||||
{
|
||||
panel = new LLPanelRegionExperiences;
|
||||
mInfoPanels.push_back(panel);
|
||||
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
|
||||
}
|
||||
|
||||
gMessageSystem->setHandlerFunc(
|
||||
"EstateOwnerMessage",
|
||||
&processEstateOwnerRequest);
|
||||
@@ -531,6 +550,16 @@ LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain()
|
||||
return panel;
|
||||
}
|
||||
|
||||
LLPanelRegionExperiences* LLFloaterRegionInfo::getPanelExperiences()
|
||||
{
|
||||
LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
|
||||
if (!floater) return NULL;
|
||||
LLTabContainer* tab_container = floater->getChild<LLTabContainer>("region_panels");
|
||||
return (LLPanelRegionExperiences*)tab_container->getChild<LLPanel>("Experiences");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLFloaterRegionInfo::onTabSelected(const LLSD& param)
|
||||
{
|
||||
LLPanelRegionInfo* active_panel = getChild<LLPanelRegionInfo>(param.asString());
|
||||
@@ -1538,6 +1567,11 @@ void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch)
|
||||
static LLDispatchSetEstateAccess set_access;
|
||||
dispatch.addHandler(name, &set_access);
|
||||
|
||||
|
||||
name.assign("setexperience");
|
||||
static LLDispatchSetEstateAccess set_experience;
|
||||
dispatch.addHandler(name, &set_experience);
|
||||
|
||||
estate_dispatch_initialized = true;
|
||||
}
|
||||
|
||||
@@ -3043,7 +3077,6 @@ void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // Singu TODO: Experiences
|
||||
LLPanelRegionExperiences::LLPanelRegionExperiences()
|
||||
: mTrusted(nullptr)
|
||||
, mAllowed(nullptr)
|
||||
@@ -3314,7 +3347,6 @@ void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id )
|
||||
onChangeAnything();
|
||||
}
|
||||
|
||||
#endif // Singu TODO: Experiences
|
||||
|
||||
LLPanelEstateAccess::LLPanelEstateAccess()
|
||||
: LLPanelRegionInfo(), mPendingUpdate(false)
|
||||
@@ -4358,10 +4390,11 @@ void LLFloaterRegionInfo::open()
|
||||
{
|
||||
const LLViewerRegion* region(gAgent.getRegion());
|
||||
// Should be able to call LLRegion::canManageEstate() but then we can fake god like
|
||||
if (!(region && region->isEstateManager() && region->getOwner() == gAgentID))
|
||||
if (!region || !region->isEstateManager() || region->getOwner() != gAgentID)
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloater::open();
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
|
||||
@@ -3,31 +3,25 @@
|
||||
* @author Aaron Brashears
|
||||
* @brief Declaration of the region info and controls floater and panels.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -42,6 +36,7 @@
|
||||
#include "llenvmanager.h" // for LLEnvironmentSettings
|
||||
|
||||
class LLAvatarName;
|
||||
class LLDispatcher;
|
||||
struct LLEstateAccessChangeInfo;
|
||||
class LLLineEditor;
|
||||
class LLMessageSystem;
|
||||
@@ -57,6 +52,7 @@ class LLRadioGroup;
|
||||
class LLSliderCtrl;
|
||||
class LLSpinCtrl;
|
||||
class LLTextBox;
|
||||
class LLVFS;
|
||||
class AIFilePicker;
|
||||
|
||||
class LLPanelRegionGeneralInfo;
|
||||
@@ -64,8 +60,17 @@ class LLPanelRegionDebugInfo;
|
||||
class LLPanelRegionTerrainInfo;
|
||||
class LLPanelEstateInfo;
|
||||
class LLPanelEstateCovenant;
|
||||
class LLPanelExperienceListEditor;
|
||||
class LLPanelExperiences;
|
||||
class LLPanelRegionExperiences;
|
||||
class LLPanelEstateAccess;
|
||||
|
||||
class LLEventTimer;
|
||||
class LLEnvironmentSettings;
|
||||
class LLWLParamManager;
|
||||
class LLWaterParamManager;
|
||||
class LLWLParamSet;
|
||||
class LLWaterParamSet;
|
||||
|
||||
class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton<LLFloaterRegionInfo>
|
||||
{
|
||||
@@ -73,11 +78,11 @@ class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton<LLFloate
|
||||
public:
|
||||
|
||||
|
||||
/*virtual*/ void onOpen();
|
||||
/*virtual*/ void onClose(bool app_quitting);
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(/*const LLSD& key*/) override;
|
||||
/*virtual*/ void onClose(bool app_quitting) override;
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
|
||||
/*virtual*/ void open();
|
||||
/*virtual*/ void open() override;
|
||||
// [/RLVa:KB]
|
||||
|
||||
static void processEstateOwnerRequest(LLMessageSystem* msg, void**);
|
||||
@@ -94,9 +99,10 @@ public:
|
||||
static LLPanelEstateAccess* getPanelAccess();
|
||||
static LLPanelEstateCovenant* getPanelCovenant();
|
||||
static LLPanelRegionTerrainInfo* getPanelRegionTerrain();
|
||||
static LLPanelRegionExperiences* getPanelExperiences();
|
||||
|
||||
// from LLPanel
|
||||
virtual void refresh();
|
||||
void refresh() override;
|
||||
|
||||
void requestRegionInfo();
|
||||
void requestMeshRezInfo();
|
||||
@@ -139,7 +145,7 @@ public:
|
||||
virtual bool refreshFromRegion(LLViewerRegion* region);
|
||||
virtual bool estateUpdate(LLMessageSystem* msg) { return true; }
|
||||
|
||||
virtual BOOL postBuild();
|
||||
BOOL postBuild() override;
|
||||
virtual void updateChild(LLUICtrl* child_ctrl);
|
||||
virtual void onOpen(const LLSD& key) {}
|
||||
|
||||
@@ -183,13 +189,14 @@ public:
|
||||
: LLPanelRegionInfo() {}
|
||||
~LLPanelRegionGeneralInfo() {}
|
||||
|
||||
virtual bool refreshFromRegion(LLViewerRegion* region);
|
||||
bool refreshFromRegion(LLViewerRegion* region) override;
|
||||
|
||||
// LLPanel
|
||||
virtual BOOL postBuild();
|
||||
BOOL postBuild() override;
|
||||
|
||||
|
||||
protected:
|
||||
virtual BOOL sendUpdate();
|
||||
BOOL sendUpdate() override;
|
||||
void onClickKick();
|
||||
void onKickCommit(const uuid_vec_t& ids);
|
||||
static void onClickKickAll(void* userdata);
|
||||
@@ -208,12 +215,12 @@ public:
|
||||
: LLPanelRegionInfo(), mTargetAvatar() {}
|
||||
~LLPanelRegionDebugInfo() {}
|
||||
// LLPanel
|
||||
virtual BOOL postBuild();
|
||||
BOOL postBuild() override;
|
||||
|
||||
virtual bool refreshFromRegion(LLViewerRegion* region);
|
||||
bool refreshFromRegion(LLViewerRegion* region) override;
|
||||
|
||||
protected:
|
||||
virtual BOOL sendUpdate();
|
||||
BOOL sendUpdate() override;
|
||||
|
||||
void onClickChooseAvatar();
|
||||
void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName>& names);
|
||||
@@ -240,9 +247,9 @@ public:
|
||||
LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {}
|
||||
~LLPanelRegionTerrainInfo() {}
|
||||
|
||||
virtual BOOL postBuild(); // LLPanel
|
||||
BOOL postBuild() override; // LLPanel
|
||||
|
||||
virtual bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator
|
||||
bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator
|
||||
void setEnvControls(bool available); // Whether environment settings are available for this region
|
||||
|
||||
BOOL validateTextureSizes();
|
||||
@@ -251,7 +258,7 @@ protected:
|
||||
|
||||
//static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button
|
||||
|
||||
virtual BOOL sendUpdate();
|
||||
BOOL sendUpdate() override;
|
||||
|
||||
static void onClickDownloadRaw(void*);
|
||||
void onClickDownloadRaw_continued(AIFilePicker* filepicker);
|
||||
@@ -294,13 +301,13 @@ public:
|
||||
static void updateEstateName(const std::string& name);
|
||||
static void updateEstateOwnerID(const LLUUID& id);
|
||||
|
||||
virtual bool refreshFromRegion(LLViewerRegion* region);
|
||||
virtual bool estateUpdate(LLMessageSystem* msg);
|
||||
bool refreshFromRegion(LLViewerRegion* region) override;
|
||||
bool estateUpdate(LLMessageSystem* msg) override;
|
||||
|
||||
// LLPanel
|
||||
virtual BOOL postBuild();
|
||||
virtual void updateChild(LLUICtrl* child_ctrl);
|
||||
virtual void refresh();
|
||||
BOOL postBuild() override;
|
||||
void updateChild(LLUICtrl* child_ctrl) override;
|
||||
void refresh() override;
|
||||
|
||||
void refreshFromEstate();
|
||||
|
||||
@@ -309,7 +316,7 @@ public:
|
||||
const std::string getOwnerName() const;
|
||||
|
||||
protected:
|
||||
virtual BOOL sendUpdate();
|
||||
BOOL sendUpdate() override;
|
||||
// confirmation dialog callback
|
||||
bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response);
|
||||
|
||||
@@ -330,16 +337,16 @@ public:
|
||||
~LLPanelEstateCovenant() {}
|
||||
|
||||
// LLPanel
|
||||
virtual BOOL postBuild();
|
||||
virtual void updateChild(LLUICtrl* child_ctrl);
|
||||
virtual bool refreshFromRegion(LLViewerRegion* region);
|
||||
virtual bool estateUpdate(LLMessageSystem* msg);
|
||||
BOOL postBuild() override;
|
||||
void updateChild(LLUICtrl* child_ctrl) override;
|
||||
bool refreshFromRegion(LLViewerRegion* region) override;
|
||||
bool estateUpdate(LLMessageSystem* msg) override;
|
||||
|
||||
// LLView overrides
|
||||
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop, EDragAndDropType cargo_type,
|
||||
void *cargo_data, EAcceptance *accept,
|
||||
std::string& tooltip_msg);
|
||||
std::string& tooltip_msg) override;
|
||||
static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response);
|
||||
static void resetCovenantID(void* userdata);
|
||||
static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response);
|
||||
@@ -372,7 +379,7 @@ public:
|
||||
} EAssetStatus;
|
||||
|
||||
protected:
|
||||
virtual BOOL sendUpdate();
|
||||
BOOL sendUpdate() override;
|
||||
LLTextBox* mEstateNameText;
|
||||
LLTextBox* mEstateOwnerText;
|
||||
LLTextBox* mLastModifiedText;
|
||||
@@ -392,17 +399,17 @@ public:
|
||||
LLPanelEnvironmentInfo();
|
||||
|
||||
// LLPanel
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
/*virtual*/ void onOpen(const LLSD& key) override;
|
||||
|
||||
// LLView
|
||||
/*virtual*/ void handleVisibilityChange(BOOL new_visibility);
|
||||
/*virtual*/ void handleVisibilityChange(BOOL new_visibility) override;
|
||||
|
||||
// LLPanelRegionInfo
|
||||
/*virtual*/ bool refreshFromRegion(LLViewerRegion* region);
|
||||
/*virtual*/ bool refreshFromRegion(LLViewerRegion* region) override;
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
void refresh() override;
|
||||
void setControlsEnabled(bool enabled);
|
||||
void setApplyProgress(bool started);
|
||||
void setDirty(bool dirty);
|
||||
@@ -444,7 +451,6 @@ private:
|
||||
LLComboBox* mDayCyclePresetCombo;
|
||||
};
|
||||
|
||||
#if 0 // Singu TODO: Experiences
|
||||
class LLPanelRegionExperiences : public LLPanelRegionInfo
|
||||
{
|
||||
LOG_CLASS(LLPanelEnvironmentInfo);
|
||||
@@ -477,7 +483,6 @@ private:
|
||||
LLUUID mDefaultExperience;
|
||||
};
|
||||
|
||||
#endif // Singu TODO: Experiences
|
||||
|
||||
class LLPanelEstateAccess : public LLPanelRegionInfo
|
||||
{
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
#include "llagentui.h"
|
||||
|
||||
#include "lltrans.h"
|
||||
#include "llexperiencecache.h"
|
||||
|
||||
#include "llcororesponder.h"
|
||||
|
||||
#include "rlvhandler.h"
|
||||
|
||||
@@ -137,7 +140,7 @@ BOOL LLFloaterReporter::postBuild()
|
||||
|
||||
// Default text to be blank
|
||||
getChild<LLUICtrl>("object_name")->setValue(LLStringUtil::null);
|
||||
getChild<LLUICtrl>("owner_name")->setValue(LLStringUtil::null);
|
||||
getChild<LLUICtrl>("owner_name")->setValue(LLUUID::null);
|
||||
mOwnerName = LLStringUtil::null;
|
||||
|
||||
getChild<LLUICtrl>("summary_edit")->setFocus(TRUE);
|
||||
@@ -171,15 +174,34 @@ BOOL LLFloaterReporter::postBuild()
|
||||
|
||||
childSetAction("send_btn", onClickSend, this);
|
||||
childSetAction("cancel_btn", onClickCancel, this);
|
||||
|
||||
// grab the user's name
|
||||
std::string reporter;
|
||||
LLAgentUI::buildFullname(reporter);
|
||||
getChild<LLUICtrl>("reporter_field")->setValue(reporter);
|
||||
getChild<LLUICtrl>("reporter_field")->setValue(gAgent.getID());
|
||||
|
||||
// request categories
|
||||
if (gAgent.getRegion()
|
||||
&& gAgent.getRegion()->capabilitiesReceived())
|
||||
{
|
||||
std::string cap_url = gAgent.getRegionCapability("AbuseCategories");
|
||||
|
||||
if (!cap_url.empty())
|
||||
{
|
||||
std::string lang = gSavedSettings.getString("Language");
|
||||
if (lang != "default" && !lang.empty())
|
||||
{
|
||||
cap_url += "?lc=";
|
||||
cap_url += lang;
|
||||
}
|
||||
LLHTTPClient::get(cap_url, new LLCoroResponder(
|
||||
boost::bind(LLFloaterReporter::requestAbuseCategoriesCoro, _1, cap_url, this->getHandle())));
|
||||
}
|
||||
}
|
||||
|
||||
center();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLFloaterReporter::~LLFloaterReporter()
|
||||
{
|
||||
@@ -204,16 +226,10 @@ LLFloaterReporter::~LLFloaterReporter()
|
||||
delete mResourceDatap;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLFloaterReporter::draw()
|
||||
{
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLFloaterReporter::enableControls(BOOL enable)
|
||||
{
|
||||
getChildView("category_combo")->setEnabled(enable);
|
||||
getChildView("screenshot")->setEnabled(false);
|
||||
getChildView("screenshot")->setEnabled(FALSE);
|
||||
getChildView("pick_btn")->setEnabled(enable);
|
||||
getChildView("summary_edit")->setEnabled(enable);
|
||||
getChildView("details_edit")->setEnabled(enable);
|
||||
@@ -221,6 +237,30 @@ void LLFloaterReporter::enableControls(BOOL enable)
|
||||
getChildView("cancel_btn")->setEnabled(enable);
|
||||
}
|
||||
|
||||
void LLFloaterReporter::getExperienceInfo(const LLUUID& experience_id)
|
||||
{
|
||||
mExperienceID = experience_id;
|
||||
|
||||
if (LLUUID::null != mExperienceID)
|
||||
{
|
||||
const LLSD& experience = LLExperienceCache::instance().get(mExperienceID);
|
||||
std::stringstream desc;
|
||||
|
||||
if (experience.isDefined())
|
||||
{
|
||||
setFromAvatarID(experience[LLExperienceCache::AGENT_ID]);
|
||||
desc << "Experience id: " << mExperienceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc << "Unable to retrieve details for id: "<< mExperienceID;
|
||||
}
|
||||
|
||||
LLUICtrl* details = getChild<LLUICtrl>("details_edit");
|
||||
details->setValue(desc.str());
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
|
||||
{
|
||||
// TODO --
|
||||
@@ -249,6 +289,14 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
|
||||
if (regionp)
|
||||
{
|
||||
getChild<LLUICtrl>("sim_field")->setValue(regionp->getName());
|
||||
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
|
||||
/*
|
||||
if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
|
||||
{
|
||||
childSetText("sim_field", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
|
||||
}
|
||||
*/
|
||||
// [/RLVa:KB]
|
||||
LLVector3d global_pos;
|
||||
global_pos.setVec(objectp->getPositionRegion());
|
||||
setPosBox(global_pos);
|
||||
@@ -305,6 +353,7 @@ void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vecto
|
||||
void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id)
|
||||
{
|
||||
mAbuserID = mObjectID = avatar_id;
|
||||
getChild<LLUICtrl>("owner_name")->setValue(mObjectID);
|
||||
|
||||
if (mAvatarNameCacheConnection.connected())
|
||||
{
|
||||
@@ -321,12 +370,74 @@ void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvata
|
||||
{
|
||||
mOwnerName = av_name.getNSName();
|
||||
const std::string& name(((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) || gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMETAGS)) && RlvUtil::isNearbyAgent(avatar_id)) ? RlvStrings::getString(RLV_STRING_HIDDEN) : mOwnerName);
|
||||
getChild<LLUICtrl>("owner_name")->setValue(name);
|
||||
getChild<LLUICtrl>("owner_name")->setValue(avatar_id);
|
||||
getChild<LLUICtrl>("object_name")->setValue(name);
|
||||
getChild<LLUICtrl>("abuser_name_edit")->setValue(name);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterReporter::requestAbuseCategoriesCoro(const LLCoroResponder& responder, std::string url, LLHandle<LLFloater> handle)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()) || !result.has("categories")) // success = httpResults["success"].asBoolean();
|
||||
{
|
||||
LL_WARNS() << "Error requesting Abuse Categories from capability: " << url << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle.isDead())
|
||||
{
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloater* floater = handle.get();
|
||||
LLComboBox* combo = floater->getChild<LLComboBox>("category_combo");
|
||||
if (!combo)
|
||||
{
|
||||
LL_WARNS() << "categories category_combo not found!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
//get selection (in case capability took a while)
|
||||
S32 selection = combo->getCurrentIndex();
|
||||
|
||||
// Combobox should have a "Select category" element;
|
||||
// This is a bit of workaround since there is no proper and simple way to save array of
|
||||
// localizable strings in xml along with data (value). For now combobox is initialized along
|
||||
// with placeholders, and first element is "Select category" which we want to keep, so remove
|
||||
// everything but first element.
|
||||
// Todo: once sim with capability fully releases, just remove this string and all unnecessary
|
||||
// items from combobox since they will be obsolete (or depending on situation remake this to
|
||||
// something better, for example move "Select category" to separate string)
|
||||
while (combo->remove(1));
|
||||
|
||||
LLSD contents = result["categories"];
|
||||
|
||||
LLSD::array_iterator i = contents.beginArray();
|
||||
LLSD::array_iterator iEnd = contents.endArray();
|
||||
for (; i != iEnd; ++i)
|
||||
{
|
||||
const LLSD &message_data(*i);
|
||||
std::string label = message_data["description_localized"];
|
||||
const auto& cat = message_data["category"];
|
||||
combo->add(label, cat);
|
||||
switch(cat.asInteger())
|
||||
{
|
||||
// Fraud
|
||||
case 47: combo->add(floater->getString("Ridiculous3"), 1000); break;
|
||||
// Harassment
|
||||
case 51: combo->add(floater->getString("Ridiculous1"), 1000); break;
|
||||
// Land > Encroachment
|
||||
case 63: combo->add(floater->getString("Ridiculous2"), 1000); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
//restore selection
|
||||
combo->selectNthItem(selection);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::onClickSend(void *userdata)
|
||||
@@ -413,7 +524,7 @@ void LLFloaterReporter::onClickObjPicker(void *userdata)
|
||||
LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance());
|
||||
self->mPicking = TRUE;
|
||||
self->getChild<LLUICtrl>("object_name")->setValue(LLStringUtil::null);
|
||||
self->getChild<LLUICtrl>("owner_name")->setValue(LLStringUtil::null);
|
||||
self->getChild<LLUICtrl>("owner_name")->setValue(LLUUID::null);
|
||||
self->mOwnerName = LLStringUtil::null;
|
||||
LLButton* pick_btn = self->getChild<LLButton>("pick_btn");
|
||||
if (pick_btn) pick_btn->setToggleState(TRUE);
|
||||
@@ -454,7 +565,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name)
|
||||
void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name, const LLUUID& experience_id)
|
||||
{
|
||||
LLFloaterReporter* f = getInstance();
|
||||
|
||||
@@ -467,6 +578,23 @@ void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_
|
||||
{
|
||||
f->setFromAvatarID(object_id);
|
||||
}
|
||||
if (experience_id.notNull())
|
||||
{
|
||||
f->getExperienceInfo(experience_id);
|
||||
}
|
||||
|
||||
// Need to deselect on close
|
||||
f->mDeselectOnClose = TRUE;
|
||||
|
||||
f->open(); /* Flawfinder: ignore */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLFloaterReporter::showFromExperience(const LLUUID& experience_id)
|
||||
{
|
||||
LLFloaterReporter* f = getInstance();
|
||||
f->getExperienceInfo(experience_id);
|
||||
|
||||
// Need to deselect on close
|
||||
f->mDeselectOnClose = TRUE;
|
||||
@@ -476,9 +604,9 @@ void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::showFromObject(const LLUUID& object_id)
|
||||
void LLFloaterReporter::showFromObject(const LLUUID& object_id, const LLUUID& experience_id)
|
||||
{
|
||||
show(object_id);
|
||||
show(object_id, LLStringUtil::null, experience_id);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -500,7 +628,7 @@ void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("owner_name")->setValue(owner_name);
|
||||
getChild<LLUICtrl>("owner_name")->setValue(owner_id);
|
||||
getChild<LLUICtrl>("abuser_name_edit")->setValue(owner_name);
|
||||
}
|
||||
mAbuserID = owner_id;
|
||||
@@ -513,7 +641,7 @@ bool LLFloaterReporter::validateReport()
|
||||
// Ensure user selected a category from the list
|
||||
LLSD category_sd = getChild<LLUICtrl>("category_combo")->getValue();
|
||||
U8 category = (U8)category_sd.asInteger();
|
||||
if(category >= 100) //This is here for reasons (like shenanigans)
|
||||
if(category == 1000) //This is here for reasons (like shenanigans)
|
||||
{
|
||||
LLNotificationsUtil::add("HelpReportNope");
|
||||
return false;
|
||||
@@ -604,7 +732,7 @@ LLSD LLFloaterReporter::gatherReport()
|
||||
|
||||
std::ostringstream details;
|
||||
|
||||
details << "V" << LLVersionInfo::getVersion() << std::endl; // client version moved to body of email for abuse reports
|
||||
details << 'V' << LLVersionInfo::getVersion() << "\n\n"; // client version moved to body of email for abuse reports
|
||||
|
||||
std::string object_name = getChild<LLUICtrl>("object_name")->getValue().asString();
|
||||
if (!object_name.empty() && !mOwnerName.empty())
|
||||
@@ -628,12 +756,16 @@ LLSD LLFloaterReporter::gatherReport()
|
||||
gGLManager.mGLRenderer.c_str(),
|
||||
gGLManager.mDriverVersionVendorString.c_str());
|
||||
|
||||
// only send a screenshot ID if we're asked to and the email is
|
||||
// going to LL - Estate Owners cannot see the screenshot asset
|
||||
LLUUID screenshot_id = getChild<LLUICtrl>("screenshot")->getValue().asUUID();
|
||||
|
||||
LLSD report = LLSD::emptyMap();
|
||||
report["report-type"] = (U8) mReportType;
|
||||
report["category"] = getChild<LLUICtrl>("category_combo")->getValue();
|
||||
report["position"] = mPosition.getValue();
|
||||
report["check-flags"] = (U8)0; // this is not used
|
||||
report["screenshot-id"] = getChild<LLUICtrl>("screenshot")->getValue();
|
||||
report["screenshot-id"] = screenshot_id;
|
||||
report["object-id"] = mObjectID;
|
||||
report["abuser-id"] = mAbuserID;
|
||||
report["abuse-region-name"] = "";
|
||||
@@ -672,7 +804,7 @@ void LLFloaterReporter::sendReportViaLegacy(const LLSD & report)
|
||||
msg->sendReliable(regionp->getHost());
|
||||
}
|
||||
|
||||
class LLUserReportScreenshotResponder : public LLAssetUploadResponder
|
||||
class LLUserReportScreenshotResponder final : public LLAssetUploadResponder
|
||||
{
|
||||
public:
|
||||
LLUserReportScreenshotResponder(const LLSD & post_data,
|
||||
@@ -692,17 +824,17 @@ public:
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
}
|
||||
|
||||
/*virtual*/ char const* getName(void) const { return "LLUserReportScreenshotResponder"; }
|
||||
char const* getName() const override { return "LLUserReportScreenshotResponder"; }
|
||||
};
|
||||
|
||||
class LLUserReportResponder : public LLHTTPClient::ResponderWithCompleted
|
||||
class LLUserReportResponder final : public LLHTTPClient::ResponderWithCompleted
|
||||
{
|
||||
LOG_CLASS(LLUserReportResponder);
|
||||
public:
|
||||
LLUserReportResponder() { }
|
||||
|
||||
private:
|
||||
void httpCompleted()
|
||||
void httpCompleted() override
|
||||
{
|
||||
if (!isGoodStatus(mStatus))
|
||||
{
|
||||
@@ -712,7 +844,7 @@ private:
|
||||
// we don't care about what the server returns
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
}
|
||||
char const* getName() const { return "LLUserReportResponder"; }
|
||||
char const* getName() const override { return "LLUserReportResponder"; }
|
||||
};
|
||||
|
||||
void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report)
|
||||
@@ -778,7 +910,7 @@ void LLFloaterReporter::takeScreenshot()
|
||||
image_in_list->createGLTexture(0, raw, nullptr, TRUE, LLViewerTexture::OTHER);
|
||||
|
||||
// the texture picker then uses that texture
|
||||
LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot");
|
||||
LLTextureCtrl* texture = getChild<LLTextureCtrl>("screenshot");
|
||||
if (texture)
|
||||
{
|
||||
texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid);
|
||||
@@ -853,6 +985,7 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos)
|
||||
getChild<LLUICtrl>("pos_field")->setValue(pos_string);
|
||||
}
|
||||
|
||||
|
||||
//void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
|
||||
//{
|
||||
// LLFloaterReporter *self = getInstance();
|
||||
|
||||
@@ -77,22 +77,22 @@ enum EReportType
|
||||
CS_REQUEST_REPORT = 4
|
||||
};
|
||||
|
||||
class LLFloaterReporter
|
||||
class LLFloaterReporter final
|
||||
: public LLFloater, public LLSingleton<LLFloaterReporter>
|
||||
{
|
||||
public:
|
||||
LLFloaterReporter();
|
||||
/*virtual*/ ~LLFloaterReporter();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
virtual void draw();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
|
||||
void setReportType(EReportType type) { mReportType = type; }
|
||||
|
||||
// Enables all buttons
|
||||
static void showFromMenu(EReportType report_type);
|
||||
|
||||
static void showFromObject(const LLUUID& object_id);
|
||||
static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null);
|
||||
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
|
||||
static void showFromExperience(const LLUUID& experience_id);
|
||||
|
||||
static void onClickSend (void *userdata);
|
||||
static void onClickCancel (void *userdata);
|
||||
@@ -100,13 +100,13 @@ public:
|
||||
void onClickSelectAbuser ();
|
||||
static void closePickTool (void *userdata);
|
||||
static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);
|
||||
static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
|
||||
static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
|
||||
static void addDescription(const std::string& description, LLMeanCollisionData *mcd = nullptr);
|
||||
static void setDescription(const std::string& description, LLMeanCollisionData *mcd = nullptr);
|
||||
|
||||
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
|
||||
|
||||
private:
|
||||
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null);
|
||||
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null);
|
||||
|
||||
void takeScreenshot();
|
||||
void sendReportViaCaps(std::string url);
|
||||
@@ -118,16 +118,20 @@ private:
|
||||
void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
|
||||
void setPosBox(const LLVector3d &pos);
|
||||
void enableControls(BOOL own_avatar);
|
||||
void getExperienceInfo(const LLUUID& object_id);
|
||||
void getObjectInfo(const LLUUID& object_id);
|
||||
void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName>& names);
|
||||
void setFromAvatarID(const LLUUID& avatar_id);
|
||||
void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name);
|
||||
|
||||
static void requestAbuseCategoriesCoro(const struct LLCoroResponder& responder, std::string url, LLHandle<LLFloater> handle);
|
||||
|
||||
private:
|
||||
EReportType mReportType;
|
||||
LLUUID mObjectID;
|
||||
LLUUID mScreenID;
|
||||
LLUUID mAbuserID;
|
||||
LLUUID mExperienceID;
|
||||
// Store the real name, not the link, for upstream reporting
|
||||
std::string mOwnerName;
|
||||
BOOL mDeselectOnClose;
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include "llfloaterdisplayname.h"
|
||||
#include "llfloatereditui.h"
|
||||
#include "llfloaterenvsettings.h"
|
||||
#include "llfloaterexperiences.h"
|
||||
#include "llfloaterexploreanimations.h"
|
||||
#include "llfloaterexploresounds.h"
|
||||
#include "llfloaterfonttest.h"
|
||||
@@ -119,6 +120,7 @@
|
||||
void handle_debug_avatar_textures(void*);
|
||||
template<typename T> void handle_singleton_toggle(void*);
|
||||
void show_outfit_dialog() { new LLMakeOutfitDialog(false); }
|
||||
class LLFloaterExperiencePicker* show_xp_picker(const LLSD& key);
|
||||
void toggle_build() { LLToolMgr::getInstance()->toggleBuildMode(); }
|
||||
void toggle_control(const std::string& name) { if (LLControlVariable* control = gSavedSettings.getControl(name)) control->set(!control->get()); }
|
||||
void toggle_search_floater();
|
||||
@@ -126,7 +128,7 @@ void toggle_always_run() { gAgent.getAlwaysRun() ? gAgent.clearAlwaysRun() : gAg
|
||||
void toggle_sit();
|
||||
void toggle_mouselook() { gAgentCamera.cameraMouselook() ? gAgentCamera.changeCameraToDefault() : gAgentCamera.changeCameraToMouselook(); }
|
||||
|
||||
bool is_visible_view(boost::function<LLView* ()> get)
|
||||
bool is_visible_view(std::function<LLView* ()> get)
|
||||
{
|
||||
if (LLView* v = get())
|
||||
return v->getVisible();
|
||||
@@ -146,7 +148,7 @@ struct CommWrapper
|
||||
|
||||
struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
|
||||
{
|
||||
typedef std::map<const std::string, std::pair<boost::function<void ()>, boost::function<bool ()> > > menu_floater_map_t;
|
||||
typedef std::map<const std::string, std::pair<std::function<void ()>, std::function<bool ()> > > menu_floater_map_t;
|
||||
menu_floater_map_t mEntries;
|
||||
|
||||
MenuFloaterDict()
|
||||
@@ -162,7 +164,7 @@ struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
|
||||
registerConsole("texture size console", gTextureSizeView);
|
||||
}
|
||||
registerConsole("velocity", gVelocityBar);
|
||||
registerFloater("about", boost::bind(&LLFloaterAbout::show,(void*)NULL));
|
||||
registerFloater("about", boost::bind(&LLFloaterAbout::show,nullptr));
|
||||
registerFloater("always run", boost::bind(toggle_always_run), boost::bind(&LLAgent::getAlwaysRun, &gAgent));
|
||||
registerFloater("anims_explorer", boost::bind(LLFloaterExploreAnimations::show));
|
||||
registerFloater("appearance", boost::bind(LLFloaterCustomize::show));
|
||||
@@ -172,37 +174,38 @@ struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
|
||||
registerFloater("buy land", boost::bind(&LLViewerParcelMgr::startBuyLand, boost::bind(LLViewerParcelMgr::getInstance), false));
|
||||
registerFloater("complaint reporter", boost::bind(LLFloaterReporter::showFromMenu, COMPLAINT_REPORT));
|
||||
registerFloater("DayCycle", boost::bind(LLFloaterDayCycle::show), boost::bind(LLFloaterDayCycle::isOpen));
|
||||
registerFloater("debug avatar", boost::bind(handle_debug_avatar_textures, (void*)NULL));
|
||||
registerFloater("debug settings", boost::bind(handle_singleton_toggle<LLFloaterSettingsDebug>, (void*)NULL));
|
||||
registerFloater("edit ui", boost::bind(LLFloaterEditUI::show, (void*)NULL));
|
||||
registerFloater("debug avatar", boost::bind(handle_debug_avatar_textures, nullptr));
|
||||
registerFloater("debug settings", boost::bind(handle_singleton_toggle<LLFloaterSettingsDebug>, nullptr));
|
||||
registerFloater("edit ui", boost::bind(LLFloaterEditUI::show, nullptr));
|
||||
registerFloater("EnvSettings", boost::bind(LLFloaterEnvSettings::show), boost::bind(LLFloaterEnvSettings::isOpen));
|
||||
registerFloater("experience_search", boost::bind(show_xp_picker, LLSD()));
|
||||
registerFloater("fly", boost::bind(LLAgent::toggleFlying));
|
||||
registerFloater("font test", boost::bind(LLFloaterFontTest::show, (void*)NULL));
|
||||
registerFloater("god tools", boost::bind(LLFloaterGodTools::show, (void*)NULL));
|
||||
registerFloater("grid options", boost::bind(LLFloaterBuildOptions::show, (void*)NULL));
|
||||
registerFloater("font test", boost::bind(LLFloaterFontTest::show, nullptr));
|
||||
registerFloater("god tools", boost::bind(LLFloaterGodTools::show, nullptr));
|
||||
registerFloater("grid options", boost::bind(LLFloaterBuildOptions::show, nullptr));
|
||||
registerFloater("group titles", boost::bind(HBFloaterGroupTitles::toggle));
|
||||
//Singu TODO: Re-implement f1 help.
|
||||
//registerFloater("help f1", boost::bind(/*gViewerHtmlHelp.show*/));
|
||||
registerFloater("help tutorial", boost::bind(LLFloaterHUD::showHUD));
|
||||
registerFloater("inventory", boost::bind(LLPanelMainInventory::toggleVisibility, (void*)NULL), boost::bind(is_visible_view, static_cast<boost::function<LLView* ()> >(LLPanelMainInventory::getActiveInventory)));
|
||||
registerFloater("inventory", boost::bind(LLPanelMainInventory::toggleVisibility, nullptr), boost::bind(is_visible_view, static_cast<std::function<LLView* ()> >(LLPanelMainInventory::getActiveInventory)));
|
||||
registerFloater("local assets", boost::bind(FloaterLocalAssetBrowser::show, (void*)0));
|
||||
registerFloater("mean events", boost::bind(LLFloaterBump::show, (void*)NULL));
|
||||
registerFloater("media ticker", boost::bind(handle_ticker_toggle, (void*)NULL), boost::bind(SHFloaterMediaTicker::instanceExists));
|
||||
registerFloater("memleak", boost::bind(LLFloaterMemLeak::show, (void*)NULL));
|
||||
registerFloater("mean events", boost::bind(LLFloaterBump::show, nullptr));
|
||||
registerFloater("media ticker", boost::bind(handle_ticker_toggle, nullptr), boost::bind(SHFloaterMediaTicker::instanceExists));
|
||||
registerFloater("memleak", boost::bind(LLFloaterMemLeak::show, nullptr));
|
||||
registerFloater("messagelog", boost::bind(LLFloaterMessageLog::show));
|
||||
registerFloater("mouselook", boost::bind(toggle_mouselook));
|
||||
registerFloater("my land", boost::bind(LLFloaterLandHoldings::show, (void*)NULL));
|
||||
registerFloater("my land", boost::bind(LLFloaterLandHoldings::show, nullptr));
|
||||
registerFloater("outfit", boost::bind(show_outfit_dialog));
|
||||
registerFloater("preferences", boost::bind(LLFloaterPreference::show, (void*)NULL));
|
||||
registerFloater("preferences", boost::bind(LLFloaterPreference::show, nullptr));
|
||||
registerFloater("quit", boost::bind(&LLAppViewer::userQuit, LLAppViewer::instance()));
|
||||
registerFloater("RegionDebugConsole", boost::bind(handle_singleton_toggle<LLFloaterRegionDebugConsole>, (void*)NULL), boost::bind(LLFloaterRegionDebugConsole::instanceExists));
|
||||
registerFloater("RegionDebugConsole", boost::bind(handle_singleton_toggle<LLFloaterRegionDebugConsole>, nullptr), boost::bind(LLFloaterRegionDebugConsole::instanceExists));
|
||||
registerFloater("script errors", boost::bind(LLFloaterScriptDebug::show, LLUUID::null));
|
||||
registerFloater("search", boost::bind(toggle_search_floater));
|
||||
registerFloater("show inspect", boost::bind(LLFloaterInspect::showInstance, LLSD()));
|
||||
registerFloater("sit", boost::bind(toggle_sit));
|
||||
registerFloater("snapshot", boost::bind(LLFloaterSnapshot::show, (void*)NULL));
|
||||
registerFloater("snapshot", boost::bind(LLFloaterSnapshot::show, nullptr));
|
||||
registerFloater("sound_explorer", boost::bind(LLFloaterExploreSounds::toggle), boost::bind(LLFloaterExploreSounds::visible));
|
||||
registerFloater("test", boost::bind(LLFloaterTest::show, (void*)NULL));
|
||||
registerFloater("test", boost::bind(LLFloaterTest::show, nullptr));
|
||||
// Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu
|
||||
registerFloater("WaterSettings", boost::bind(LLFloaterWater::show), boost::bind(LLFloaterWater::isOpen));
|
||||
registerFloater("Windlight", boost::bind(LLFloaterWindLight::show), boost::bind(LLFloaterWindLight::isOpen));
|
||||
@@ -220,6 +223,7 @@ struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
|
||||
registerFloater<LLFloaterChatterBox> ("communicate");
|
||||
registerFloater<LLFloaterDestinations> ("destinations");
|
||||
registerFloater<LLFloaterDisplayName> ("displayname");
|
||||
registerFloater<LLFloaterExperiences> ("experiences");
|
||||
registerFloater<LLFloaterMyFriends> ("friends", 0);
|
||||
registerFloater<LLFloaterGesture> ("gestures");
|
||||
registerFloater<LLFloaterMyFriends> ("groups", 1);
|
||||
@@ -248,12 +252,13 @@ struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
|
||||
registerFloater<RlvFloaterStrings>("rlv strings");
|
||||
// [/RLVa:LF]
|
||||
}
|
||||
public:
|
||||
template <typename T>
|
||||
void registerConsole(const std::string& name, T* console)
|
||||
{
|
||||
registerFloater(name, boost::bind(&T::setVisible, console, !boost::bind(&T::getVisible, console)), boost::bind(&T::getVisible, console));
|
||||
}
|
||||
void registerFloater(const std::string& name, boost::function<void ()> show, boost::function<bool ()> visible = NULL)
|
||||
void registerFloater(const std::string& name, std::function<void ()> show, std::function<bool ()> visible = nullptr)
|
||||
{
|
||||
mEntries.insert( std::make_pair( name, std::make_pair( show, visible ) ) );
|
||||
}
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
#include "llcachename.h"
|
||||
#include "llagent.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "llinventory.h"
|
||||
#include "llscrolllistitem.h"
|
||||
#include "llscrolllistcell.h"
|
||||
#include "llscrolllistcolumn.h"
|
||||
#include "llsdparam.h"
|
||||
#include "lltrans.h"
|
||||
@@ -49,6 +51,7 @@ void LLNameListItem::NameTypeNames::declareValues()
|
||||
declare("INDIVIDUAL", INDIVIDUAL);
|
||||
declare("GROUP", GROUP);
|
||||
declare("SPECIAL", SPECIAL);
|
||||
declare("EXPERIENCE", EXPERIENCE);
|
||||
}
|
||||
|
||||
LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border, bool draw_heading, S32 name_column_index, const std::string& name_system, const std::string& tooltip)
|
||||
@@ -134,6 +137,7 @@ BOOL LLNameListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
case LLNameListItem::INDIVIDUAL: LLAvatarActions::showProfile(item->getValue()); break;
|
||||
case LLNameListItem::GROUP: LLGroupActions::show(item->getValue()); break;
|
||||
case LLNameListItem::EXPERIENCE: LLFloaterExperienceProfile::showInstance(item->getValue()); break;
|
||||
default: return false;
|
||||
}
|
||||
handled = true;
|
||||
@@ -159,8 +163,9 @@ LFIDBearer::Type LLNameListCtrl::getSelectedType() const
|
||||
{
|
||||
switch (static_cast<LLNameListItem*>(item)->getNameType())
|
||||
{
|
||||
CONVERT_TO_RETTYPE(case LLNameListItem::INDIVIDUAL, AVATAR);
|
||||
CONVERT_TO_RETTYPE(case LLNameListItem::INDIVIDUAL, AVATAR)
|
||||
CONVERT_TO_RETTYPE(case LLNameListItem::GROUP, GROUP)
|
||||
CONVERT_TO_RETTYPE(case LLNameListItem::EXPERIENCE, EXPERIENCE)
|
||||
CONVERT_TO_RETTYPE(default, COUNT) // Invalid, but just use count instead
|
||||
}
|
||||
}
|
||||
@@ -212,7 +217,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
||||
LLUUID id = name_item.value().asUUID();
|
||||
LLNameListItem* item = new LLNameListItem(name_item);
|
||||
|
||||
if (!item) return NULL;
|
||||
if (!item) return nullptr;
|
||||
|
||||
LLScrollListCtrl::addRow(item, name_item, pos);
|
||||
|
||||
@@ -277,6 +282,8 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LLNameListItem::EXPERIENCE:
|
||||
// just use supplied name
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ public:
|
||||
{
|
||||
INDIVIDUAL,
|
||||
GROUP,
|
||||
SPECIAL
|
||||
SPECIAL,
|
||||
EXPERIENCE
|
||||
};
|
||||
|
||||
// provide names for enums
|
||||
@@ -98,8 +99,8 @@ public:
|
||||
Alternative<S32> column_index;
|
||||
Alternative<std::string> column_name;
|
||||
NameColumn()
|
||||
: column_name("name_column"),
|
||||
column_index("name_column_index", 0)
|
||||
: column_index("name_column_index", 0),
|
||||
column_name("name_column")
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -118,7 +119,7 @@ protected:
|
||||
}
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const override;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
// Add a user to the list by name. It will be added, the name
|
||||
@@ -127,7 +128,7 @@ public:
|
||||
BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null, const std::string& prefix = LLStringUtil::null);
|
||||
LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
|
||||
|
||||
/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
|
||||
/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL) override;
|
||||
LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null,
|
||||
const std::string& prefix = LLStringUtil::null);
|
||||
|
||||
@@ -146,7 +147,7 @@ public:
|
||||
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
|
||||
EAcceptance *accept,
|
||||
std::string& tooltip_msg);
|
||||
std::string& tooltip_msg) override;
|
||||
BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override;
|
||||
|
||||
Type getSelectedType() const override final;
|
||||
@@ -160,8 +161,9 @@ private:
|
||||
|
||||
private:
|
||||
S32 mNameColumnIndex;
|
||||
//std::string mNameColumn;
|
||||
BOOL mAllowCallingCardDrop;
|
||||
const LLCachedControl<S32> mNameSystem;
|
||||
const LLCachedControl<S32> mNameSystem; // Singu Note: Instead of mShortNames
|
||||
typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
|
||||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
|
||||
@@ -169,7 +171,7 @@ private:
|
||||
namelist_complete_signal_t mNameListCompleteSignal;
|
||||
|
||||
public:
|
||||
boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback)
|
||||
boost::signals2::connection setOnNameListCompleteCallback(std::function<void(bool)> onNameListCompleteCallback)
|
||||
{
|
||||
return mNameListCompleteSignal.connect(onNameListCompleteCallback);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "llagentdata.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
@@ -67,7 +69,8 @@ void LLNameUI::setType(const Type& type)
|
||||
else
|
||||
{
|
||||
sInstances.erase(this);
|
||||
mConnections[1] = gSavedSettings.getControl(mNameSystem)->getCommitSignal()->connect(boost::bind(&LLNameUI::setNameText, this));
|
||||
if (type == AVATAR)
|
||||
mConnections[1] = gSavedSettings.getControl(mNameSystem)->getCommitSignal()->connect(boost::bind(&LLNameUI::setNameText, this));
|
||||
}
|
||||
mType = type;
|
||||
}
|
||||
@@ -84,7 +87,8 @@ void LLNameUI::setNameID(const LLUUID& name_id, const Type& type)
|
||||
}
|
||||
else
|
||||
{
|
||||
setText(LLTrans::getString(mType == GROUP ? "GroupNameNone" : "AvatarNameNobody"));
|
||||
setText(LLTrans::getString(mType == GROUP ? "GroupNameNone" :
|
||||
mType == AVATAR ? "AvatarNameNobody" : "ExperienceNameNull"));
|
||||
displayAsLink(false);
|
||||
}
|
||||
}
|
||||
@@ -98,6 +102,15 @@ void LLNameUI::setNameText()
|
||||
{
|
||||
got_name = gCacheName->getGroupName(mNameID, name);
|
||||
}
|
||||
else if (mType == EXPERIENCE)
|
||||
{
|
||||
auto& cache = LLExperienceCache::instance();
|
||||
const auto& exp = cache.get(mNameID);
|
||||
if (got_name = exp.isMap())
|
||||
name = exp.has(LLExperienceCache::MISSING) && exp[LLExperienceCache::MISSING] ? LLTrans::getString("ExperienceNameNull") : exp[LLExperienceCache::NAME].asString();
|
||||
else
|
||||
cache.get(mNameID, boost::bind(&LLNameUI::setNameText, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
@@ -149,6 +162,7 @@ void LLNameUI::showProfile()
|
||||
{
|
||||
case LFIDBearer::GROUP: LLGroupActions::show(mNameID); break;
|
||||
case LFIDBearer::AVATAR: LLAvatarActions::showProfile(mNameID); break;
|
||||
case LFIDBearer::EXPERIENCE: LLFloaterExperienceProfile::showInstance(mNameID); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
280
indra/newview/llpanelexperiencelisteditor.cpp
Normal file
280
indra/newview/llpanelexperiencelisteditor.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* @file llpanelexperiencelisteditor.cpp
|
||||
* @brief Editor for building a list of experiences
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&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 "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelexperiencelisteditor.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llfloaterexperiencepicker.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
//#include "llfloaterreg.h"
|
||||
#include "llhandle.h"
|
||||
#include "llnamelistctrl.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llagent.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
|
||||
/* Singu Note: We do not have injectors, so we'll have to call this function instead
|
||||
static LLPanelInjector<LLPanelExperienceListEditor> t_panel_experience_list_editor("panel_experience_list_editor");
|
||||
*/
|
||||
void* create_xp_list_editor(void* data)
|
||||
{
|
||||
return *reinterpret_cast<LLPanelExperienceListEditor**>(data) = new LLPanelExperienceListEditor;
|
||||
}
|
||||
|
||||
|
||||
LLPanelExperienceListEditor::LLPanelExperienceListEditor()
|
||||
:mItems(nullptr)
|
||||
,mAdd(nullptr)
|
||||
,mRemove(nullptr)
|
||||
,mProfile(nullptr)
|
||||
,mAddedCallback()
|
||||
,mRemovedCallback()
|
||||
,mReadonly(false)
|
||||
,mMaxExperienceIDs(0)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLPanelExperienceListEditor::postBuild()
|
||||
{
|
||||
mItems = getChild<LLScrollListCtrl>("experience_list");
|
||||
mAdd = getChild<LLButton>("btn_add");
|
||||
mRemove = getChild<LLButton>("btn_remove");
|
||||
mProfile = getChild<LLButton>("btn_profile");
|
||||
|
||||
childSetAction("btn_add", boost::bind(&LLPanelExperienceListEditor::onAdd, this));
|
||||
childSetAction("btn_remove", boost::bind(&LLPanelExperienceListEditor::onRemove, this));
|
||||
childSetAction("btn_profile", boost::bind(&LLPanelExperienceListEditor::onProfile, this));
|
||||
|
||||
mItems->setCommitCallback(boost::bind(&LLPanelExperienceListEditor::checkButtonsEnabled, this));
|
||||
|
||||
checkButtonsEnabled();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const uuid_list_t& LLPanelExperienceListEditor::getExperienceIds() const
|
||||
{
|
||||
return mExperienceIds;
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::addExperienceIds( const uuid_vec_t& experience_ids )
|
||||
{
|
||||
// the commented out code in this function is handled by the callback and no longer necessary!
|
||||
|
||||
//mExperienceIds.insert(experience_ids.begin(), experience_ids.end());
|
||||
//onItems();
|
||||
if(!mAddedCallback.empty())
|
||||
{
|
||||
for(uuid_vec_t::const_iterator it = experience_ids.begin(); it != experience_ids.end(); ++it)
|
||||
{
|
||||
mAddedCallback(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLPanelExperienceListEditor::setExperienceIds( const LLSD& experience_ids )
|
||||
{
|
||||
mExperienceIds.clear();
|
||||
for_each(experience_ids.beginArray(), experience_ids.endArray(), [this] (const LLUUID& id)
|
||||
{
|
||||
// Using insert(range) doesn't work here because the conversion from
|
||||
// LLSD to LLUUID is ambiguous: have to specify asUUID() for each entry.
|
||||
mExperienceIds.insert(id);
|
||||
});
|
||||
onItems();
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::addExperience( const LLUUID& id )
|
||||
{
|
||||
mExperienceIds.insert(id);
|
||||
onItems();
|
||||
}
|
||||
void LLPanelExperienceListEditor::onAdd()
|
||||
{
|
||||
if(!mPicker.isDead())
|
||||
{
|
||||
mPicker.markDead();
|
||||
}
|
||||
|
||||
mKey.generateNewID();
|
||||
|
||||
LLFloaterExperiencePicker* picker = LLFloaterExperiencePicker::show(boost::bind(&LLPanelExperienceListEditor::addExperienceIds, this, _1), mKey, FALSE, TRUE, mFilters, mAdd);
|
||||
mPicker = picker->getDerivedHandle<LLFloaterExperiencePicker>();
|
||||
}
|
||||
|
||||
|
||||
void LLPanelExperienceListEditor::onRemove()
|
||||
{
|
||||
// the commented out code in this function is handled by the callback and no longer necessary!
|
||||
|
||||
std::vector<LLScrollListItem*> items= mItems->getAllSelected();
|
||||
std::vector<LLScrollListItem*>::iterator it = items.begin();
|
||||
for(/**/; it != items.end(); ++it)
|
||||
{
|
||||
if((*it) != nullptr)
|
||||
{
|
||||
//mExperienceIds.erase((*it)->getValue());
|
||||
mRemovedCallback((*it)->getValue());
|
||||
}
|
||||
}
|
||||
mItems->selectFirstItem();
|
||||
checkButtonsEnabled();
|
||||
//onItems();
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::onProfile()
|
||||
{
|
||||
LLScrollListItem* item = mItems->getFirstSelected();
|
||||
if(item)
|
||||
{
|
||||
LLFloaterExperienceProfile::showInstance(item->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::checkButtonsEnabled()
|
||||
{
|
||||
mAdd->setEnabled(!mReadonly);
|
||||
int selected = mItems->getNumSelected();
|
||||
|
||||
bool remove_enabled = !mReadonly && selected>0;
|
||||
if(remove_enabled && mSticky)
|
||||
{
|
||||
std::vector<LLScrollListItem*> items= mItems->getAllSelected();
|
||||
std::vector<LLScrollListItem*>::iterator it = items.begin();
|
||||
for(/**/; it != items.end() && remove_enabled; ++it)
|
||||
{
|
||||
if((*it) != nullptr)
|
||||
{
|
||||
remove_enabled = !mSticky((*it)->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
mRemove->setEnabled(remove_enabled);
|
||||
mProfile->setEnabled(selected==1);
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::onItems()
|
||||
{
|
||||
mItems->deleteAllItems();
|
||||
|
||||
LLSD item;
|
||||
uuid_list_t::iterator it = mExperienceIds.begin();
|
||||
for(/**/; it != mExperienceIds.end(); ++it)
|
||||
{
|
||||
const LLUUID& experience = *it;
|
||||
item["id"]=experience;
|
||||
item["target"] = LLNameListItem::EXPERIENCE;
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "experience_name";
|
||||
columns[0]["value"] = getString("loading");
|
||||
mItems->addElement(item);
|
||||
|
||||
LLExperienceCache::instance().get(experience, boost::bind(&LLPanelExperienceListEditor::experienceDetailsCallback,
|
||||
getDerivedHandle<LLPanelExperienceListEditor>(), _1));
|
||||
}
|
||||
|
||||
|
||||
if(mItems->getItemCount() == 0)
|
||||
{
|
||||
mItems->setCommentText(getString("no_results"));
|
||||
}
|
||||
|
||||
|
||||
checkButtonsEnabled();
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::experienceDetailsCallback( LLHandle<LLPanelExperienceListEditor> panel, const LLSD& experience )
|
||||
{
|
||||
if(!panel.isDead())
|
||||
{
|
||||
panel.get()->onExperienceDetails(experience);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::onExperienceDetails( const LLSD& experience )
|
||||
{
|
||||
LLScrollListItem* item = mItems->getItem(experience[LLExperienceCache::EXPERIENCE_ID]);
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
std::string experience_name_string = experience[LLExperienceCache::NAME].asString();
|
||||
if (experience_name_string.empty())
|
||||
{
|
||||
experience_name_string = LLTrans::getString("ExperienceNameUntitled");
|
||||
}
|
||||
|
||||
item->getColumn(0)->setValue(experience_name_string);
|
||||
}
|
||||
|
||||
LLPanelExperienceListEditor::~LLPanelExperienceListEditor()
|
||||
{
|
||||
if(!mPicker.isDead())
|
||||
{
|
||||
mPicker.get()->close();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::loading()
|
||||
{
|
||||
mItems->clear();
|
||||
mItems->setCommentText( getString("loading"));
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::setReadonly( bool val )
|
||||
{
|
||||
mReadonly = val;
|
||||
checkButtonsEnabled();
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::refreshExperienceCounter()
|
||||
{
|
||||
if(mMaxExperienceIDs > 0)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[EXPERIENCES]"] = llformat("%d", mItems->getItemCount());
|
||||
args["[MAXEXPERIENCES]"] = llformat("%d", mMaxExperienceIDs);
|
||||
getChild<LLTextBox>("text_count")->setText(LLTrans::getString("ExperiencesCounter", args));
|
||||
}
|
||||
}
|
||||
|
||||
boost::signals2::connection LLPanelExperienceListEditor::setAddedCallback( list_changed_signal_t::slot_type cb )
|
||||
{
|
||||
return mAddedCallback.connect(cb);
|
||||
}
|
||||
|
||||
boost::signals2::connection LLPanelExperienceListEditor::setRemovedCallback( list_changed_signal_t::slot_type cb )
|
||||
{
|
||||
return mRemovedCallback.connect(cb);
|
||||
}
|
||||
|
||||
102
indra/newview/llpanelexperiencelisteditor.h
Normal file
102
indra/newview/llpanelexperiencelisteditor.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file llpanelexperiencelisteditor.cpp
|
||||
* @brief Editor for building a list of experiences
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&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_LLPANELEXPERIENCELISTEDITOR_H
|
||||
#define LL_LLPANELEXPERIENCELISTEDITOR_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
#include <set>
|
||||
|
||||
class LLNameListCtrl;
|
||||
class LLScrollListCtrl;
|
||||
class LLButton;
|
||||
class LLFloaterExperiencePicker;
|
||||
|
||||
void* create_xp_list_editor(void* data); // <singu/>
|
||||
class LLPanelExperienceListEditor final : public LLPanel
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::signals2::signal<void (const LLUUID&) > list_changed_signal_t;
|
||||
// filter function for experiences, return true if the experience should be hidden.
|
||||
typedef std::function<bool (const LLSD&)> experience_function;
|
||||
typedef std::vector<experience_function> filter_list;
|
||||
typedef LLHandle<LLFloaterExperiencePicker> PickerHandle;
|
||||
LLPanelExperienceListEditor();
|
||||
~LLPanelExperienceListEditor();
|
||||
BOOL postBuild() override;
|
||||
|
||||
void loading();
|
||||
|
||||
const uuid_list_t& getExperienceIds()const;
|
||||
void setExperienceIds(const LLSD& experience_ids);
|
||||
void addExperienceIds(const uuid_vec_t& experience_ids);
|
||||
|
||||
void addExperience(const LLUUID& id);
|
||||
|
||||
boost::signals2::connection setAddedCallback(list_changed_signal_t::slot_type cb );
|
||||
boost::signals2::connection setRemovedCallback(list_changed_signal_t::slot_type cb );
|
||||
|
||||
bool getReadonly() const { return mReadonly; }
|
||||
void setReadonly(bool val);
|
||||
|
||||
void refreshExperienceCounter();
|
||||
|
||||
void addFilter(experience_function func){mFilters.push_back(func);}
|
||||
void setStickyFunction(experience_function func){mSticky = func;}
|
||||
U32 getMaxExperienceIDs() const { return mMaxExperienceIDs; }
|
||||
void setMaxExperienceIDs(U32 val) { mMaxExperienceIDs = val; }
|
||||
private:
|
||||
|
||||
void onItems();
|
||||
void onRemove();
|
||||
void onAdd();
|
||||
void onProfile();
|
||||
|
||||
void checkButtonsEnabled();
|
||||
static void experienceDetailsCallback( LLHandle<LLPanelExperienceListEditor> panel, const LLSD& experience );
|
||||
void onExperienceDetails( const LLSD& experience );
|
||||
void processResponse( const LLSD& content );
|
||||
uuid_list_t mExperienceIds;
|
||||
|
||||
|
||||
LLScrollListCtrl* mItems;
|
||||
filter_list mFilters;
|
||||
LLButton* mAdd;
|
||||
LLButton* mRemove;
|
||||
LLButton* mProfile;
|
||||
PickerHandle mPicker;
|
||||
list_changed_signal_t mAddedCallback;
|
||||
list_changed_signal_t mRemovedCallback;
|
||||
LLUUID mKey;
|
||||
bool mReadonly;
|
||||
experience_function mSticky;
|
||||
U32 mMaxExperienceIDs;
|
||||
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELEXPERIENCELISTEDITOR_H
|
||||
270
indra/newview/llpanelexperiencelog.cpp
Normal file
270
indra/newview/llpanelexperiencelog.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/**
|
||||
* @file llpanelexperiencelog.cpp
|
||||
* @brief llpanelexperiencelog
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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 "llpanelexperiencelog.h"
|
||||
|
||||
#include "llexperiencelog.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llbutton.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
//#include "llfloaterreg.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llfloaterreporter.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
|
||||
|
||||
#define BTN_PROFILE_XP "btn_profile_xp"
|
||||
#define BTN_REPORT_XP "btn_report_xp"
|
||||
|
||||
/* Singu Note: We do not have injectors, so we'll have to call this function instead
|
||||
static LLPanelInjector<LLPanelExperienceLog> register_experiences_panel("experience_log");
|
||||
*/
|
||||
void* create_xp_log(void* data) { return new LLPanelExperienceLog(false); }
|
||||
|
||||
|
||||
LLPanelExperienceLog::LLPanelExperienceLog(bool build)
|
||||
: mEventList(nullptr)
|
||||
, mPageSize(25)
|
||||
, mCurrentPage(0)
|
||||
{
|
||||
//buildFromFile("panel_experience_log.xml");
|
||||
if (build) LLUICtrlFactory::getInstance()->buildPanel(this, "panel_experience_log.xml"); // Singu Note: Use filename in xml
|
||||
}
|
||||
|
||||
BOOL LLPanelExperienceLog::postBuild( void )
|
||||
{
|
||||
LLExperienceLog* log = LLExperienceLog::getInstance();
|
||||
mEventList = getChild<LLScrollListCtrl>("experience_log_list");
|
||||
mEventList->setCommitCallback(boost::bind(&LLPanelExperienceLog::onSelectionChanged, this));
|
||||
mEventList->setDoubleClickCallback( boost::bind(&LLPanelExperienceLog::onProfileExperience, this));
|
||||
|
||||
getChild<LLButton>("btn_clear")->setCommitCallback(boost::bind(&LLExperienceLog::clear, log));
|
||||
getChild<LLButton>("btn_clear")->setCommitCallback(boost::bind(&LLPanelExperienceLog::refresh, this));
|
||||
|
||||
getChild<LLButton>(BTN_PROFILE_XP)->setCommitCallback(boost::bind(&LLPanelExperienceLog::onProfileExperience, this));
|
||||
getChild<LLButton>(BTN_REPORT_XP )->setCommitCallback(boost::bind(&LLPanelExperienceLog::onReportExperience, this));
|
||||
getChild<LLButton>("btn_notify" )->setCommitCallback(boost::bind(&LLPanelExperienceLog::onNotify, this));
|
||||
getChild<LLButton>("btn_next" )->setCommitCallback(boost::bind(&LLPanelExperienceLog::onNext, this));
|
||||
getChild<LLButton>("btn_prev" )->setCommitCallback(boost::bind(&LLPanelExperienceLog::onPrev, this));
|
||||
|
||||
LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("notify_all");
|
||||
check->set(log->getNotifyNewEvent());
|
||||
check->setCommitCallback(boost::bind(&LLPanelExperienceLog::notifyChanged, this));
|
||||
|
||||
|
||||
LLSpinCtrl* spin = getChild<LLSpinCtrl>("logsizespinner");
|
||||
spin->set(log->getMaxDays());
|
||||
spin->setCommitCallback(boost::bind(&LLPanelExperienceLog::logSizeChanged, this));
|
||||
|
||||
mPageSize = log->getPageSize();
|
||||
refresh();
|
||||
mNewEvent = LLExperienceLog::instance().addUpdateSignal(boost::bind(&LLPanelExperienceLog::refresh, this));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLPanelExperienceLog* LLPanelExperienceLog::create()
|
||||
{
|
||||
return new LLPanelExperienceLog();
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::refresh()
|
||||
{
|
||||
S32 selected = mEventList->getFirstSelectedIndex();
|
||||
mEventList->deleteAllItems();
|
||||
const LLSD events = LLExperienceLog::instance().getEvents();
|
||||
|
||||
if(events.size() == 0)
|
||||
{
|
||||
mEventList->setCommentText(getString("no_events"));
|
||||
return;
|
||||
}
|
||||
|
||||
setAllChildrenEnabled(FALSE);
|
||||
|
||||
LLSD item;
|
||||
bool waiting = false;
|
||||
LLUUID waiting_id;
|
||||
|
||||
U32 itemsToSkip = mPageSize*mCurrentPage;
|
||||
U32 items = 0;
|
||||
bool moreItems = false;
|
||||
|
||||
if (!events.emptyMap())
|
||||
{
|
||||
LLSD::map_const_iterator day = events.endMap();
|
||||
do
|
||||
{
|
||||
--day;
|
||||
const std::string& date = day->first;
|
||||
if (LLExperienceLog::instance().isExpired(date))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const LLSD& dayArray = day->second;
|
||||
U32 size = dayArray.size();
|
||||
if(itemsToSkip > size)
|
||||
{
|
||||
itemsToSkip -= size;
|
||||
continue;
|
||||
}
|
||||
if(items >= mPageSize && size > 0)
|
||||
{
|
||||
moreItems = true;
|
||||
break;
|
||||
}
|
||||
for(int i = dayArray.size() - itemsToSkip - 1; i >= 0; i--)
|
||||
{
|
||||
if (items >= mPageSize)
|
||||
{
|
||||
moreItems = true;
|
||||
break;
|
||||
}
|
||||
const LLSD event = dayArray[i];
|
||||
LLUUID id = event[LLExperienceCache::EXPERIENCE_ID].asUUID();
|
||||
const LLSD& experience = LLExperienceCache::instance().get(id);
|
||||
if(experience.isUndefined()){
|
||||
waiting = true;
|
||||
waiting_id = id;
|
||||
}
|
||||
if(!waiting)
|
||||
{
|
||||
item["id"] = event;
|
||||
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "time";
|
||||
columns[0]["value"] = day->first+event["Time"].asString();
|
||||
columns[1]["column"] = "event";
|
||||
columns[1]["value"] = LLExperienceLog::getPermissionString(event, "ExperiencePermissionShort");
|
||||
columns[2]["column"] = "experience_name";
|
||||
columns[2]["value"] = experience[LLExperienceCache::NAME].asString();
|
||||
columns[3]["column"] = "object_name";
|
||||
columns[3]["value"] = event["ObjectName"].asString();
|
||||
mEventList->addElement(item);
|
||||
}
|
||||
++items;
|
||||
}
|
||||
} while (day != events.beginMap());
|
||||
}
|
||||
if (waiting)
|
||||
{
|
||||
mEventList->deleteAllItems();
|
||||
mEventList->setCommentText(getString("loading"));
|
||||
LLExperienceCache::instance().get(waiting_id, boost::bind(&LLPanelExperienceLog::refresh, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
setAllChildrenEnabled(TRUE);
|
||||
|
||||
mEventList->setEnabled(TRUE);
|
||||
getChild<LLButton>("btn_next")->setEnabled(moreItems);
|
||||
getChild<LLButton>("btn_prev")->setEnabled(mCurrentPage>0);
|
||||
getChild<LLButton>("btn_clear")->setEnabled(mEventList->getItemCount()>0);
|
||||
if (selected < 0)
|
||||
{
|
||||
selected = 0;
|
||||
}
|
||||
mEventList->selectNthItem(selected);
|
||||
onSelectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::onProfileExperience()
|
||||
{
|
||||
LLSD event = getSelectedEvent();
|
||||
if (event.isDefined())
|
||||
{
|
||||
LLFloaterExperienceProfile::showInstance(event[LLExperienceCache::EXPERIENCE_ID].asUUID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::onReportExperience()
|
||||
{
|
||||
LLSD event = getSelectedEvent();
|
||||
if (event.isDefined())
|
||||
{
|
||||
LLFloaterReporter::showFromExperience(event[LLExperienceCache::EXPERIENCE_ID].asUUID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::onNotify()
|
||||
{
|
||||
LLSD event = getSelectedEvent();
|
||||
if (event.isDefined())
|
||||
{
|
||||
LLExperienceLog::instance().notify(event);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::onNext()
|
||||
{
|
||||
mCurrentPage++;
|
||||
refresh();
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::onPrev()
|
||||
{
|
||||
if(mCurrentPage>0)
|
||||
{
|
||||
mCurrentPage--;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::notifyChanged()
|
||||
{
|
||||
LLExperienceLog::instance().setNotifyNewEvent(getChild<LLCheckBoxCtrl>("notify_all")->get());
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::logSizeChanged()
|
||||
{
|
||||
int value = (int)(getChild<LLSpinCtrl>("logsizespinner")->get());
|
||||
LLExperienceLog::instance().setMaxDays(value);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void LLPanelExperienceLog::onSelectionChanged()
|
||||
{
|
||||
bool enabled = (1 == mEventList->getNumSelected());
|
||||
getChild<LLButton>(BTN_REPORT_XP)->setEnabled(enabled);
|
||||
getChild<LLButton>(BTN_PROFILE_XP)->setEnabled(enabled);
|
||||
getChild<LLButton>("btn_notify")->setEnabled(enabled);
|
||||
}
|
||||
|
||||
LLSD LLPanelExperienceLog::getSelectedEvent()
|
||||
{
|
||||
LLScrollListItem* item = mEventList->getFirstSelected();
|
||||
if(item)
|
||||
{
|
||||
return item->getValue();
|
||||
}
|
||||
return LLSD();
|
||||
}
|
||||
65
indra/newview/llpanelexperiencelog.h
Normal file
65
indra/newview/llpanelexperiencelog.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file llpanelexperiencelog.h
|
||||
* @brief llpanelexperiencelog and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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_LLPANELEXPERIENCELOG_H
|
||||
#define LL_LLPANELEXPERIENCELOG_H
|
||||
|
||||
#include "llpanel.h"
|
||||
class LLScrollListCtrl;
|
||||
|
||||
void* create_xp_log(void* data);
|
||||
class LLPanelExperienceLog final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
|
||||
LLPanelExperienceLog(bool build = true);
|
||||
|
||||
static LLPanelExperienceLog* create();
|
||||
|
||||
/*virtual*/ BOOL postBuild(void) override;
|
||||
|
||||
void refresh() override;
|
||||
protected:
|
||||
void logSizeChanged();
|
||||
void notifyChanged();
|
||||
void onNext();
|
||||
void onNotify();
|
||||
void onPrev();
|
||||
void onProfileExperience();
|
||||
void onReportExperience();
|
||||
void onSelectionChanged();
|
||||
|
||||
LLSD getSelectedEvent();
|
||||
private:
|
||||
LLScrollListCtrl* mEventList;
|
||||
U32 mPageSize;
|
||||
U32 mCurrentPage;
|
||||
boost::signals2::scoped_connection mNewEvent;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELEXPERIENCELOG_H
|
||||
456
indra/newview/llpanelexperiencepicker.cpp
Normal file
456
indra/newview/llpanelexperiencepicker.cpp
Normal file
@@ -0,0 +1,456 @@
|
||||
/**
|
||||
* @file llpanelexperiencepicker.cpp
|
||||
* @brief Implementation of llpanelexperiencepicker
|
||||
* @author dolphin@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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 "llpanelexperiencepicker.h"
|
||||
|
||||
|
||||
#include "lllineeditor.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
//#include "llfloaterreg.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llagent.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llslurl.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llfloater.h"
|
||||
#include "lltrans.h"
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#define BTN_FIND "find"
|
||||
#define BTN_OK "ok_btn"
|
||||
#define BTN_CANCEL "cancel_btn"
|
||||
#define BTN_PROFILE "profile_btn"
|
||||
#define BTN_LEFT "left_btn"
|
||||
#define BTN_RIGHT "right_btn"
|
||||
#define TEXT_EDIT "edit"
|
||||
#define TEXT_MATURITY "maturity"
|
||||
#define LIST_RESULTS "search_results"
|
||||
#define PANEL_SEARCH "search_panel"
|
||||
|
||||
const static std::string columnSpace = " ";
|
||||
|
||||
/* Singu Note: We do not have injectors, so we'll have to call this function instead
|
||||
static LLPanelInjector<LLPanelExperiencePicker> t_panel_status("llpanelexperiencepicker");
|
||||
*/
|
||||
void* create_xp_picker(void* data) { return new LLPanelExperiencePicker(false); }
|
||||
|
||||
LLPanelExperiencePicker::LLPanelExperiencePicker(bool build)
|
||||
:LLPanel()
|
||||
{
|
||||
//buildFromFile("panel_experience_search.xml");
|
||||
if (build) LLUICtrlFactory::getInstance()->buildPanel(this, "panel_experience_search.xml"); // Singu Note: Use filename in xml
|
||||
setDefaultFilters();
|
||||
}
|
||||
|
||||
LLPanelExperiencePicker::~LLPanelExperiencePicker()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLPanelExperiencePicker::postBuild()
|
||||
{
|
||||
getChild<LLLineEditor>(TEXT_EDIT)->setKeystrokeCallback(boost::bind(&LLPanelExperiencePicker::editKeystroke, this, _1));
|
||||
|
||||
childSetAction(BTN_FIND, boost::bind(&LLPanelExperiencePicker::onBtnFind, this));
|
||||
getChildView(BTN_FIND)->setEnabled(TRUE);
|
||||
|
||||
LLScrollListCtrl* searchresults = getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
searchresults->setDoubleClickCallback( boost::bind(&LLPanelExperiencePicker::onBtnSelect, this));
|
||||
searchresults->setCommitCallback(boost::bind(&LLPanelExperiencePicker::onList, this));
|
||||
getChildView(LIST_RESULTS)->setEnabled(FALSE);
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("no_results"));
|
||||
|
||||
childSetAction(BTN_OK, boost::bind(&LLPanelExperiencePicker::onBtnSelect, this));
|
||||
getChildView(BTN_OK)->setEnabled(FALSE);
|
||||
childSetAction(BTN_CANCEL, boost::bind(&LLPanelExperiencePicker::onBtnClose, this));
|
||||
childSetAction(BTN_PROFILE, boost::bind(&LLPanelExperiencePicker::onBtnProfile, this));
|
||||
getChildView(BTN_PROFILE)->setEnabled(FALSE);
|
||||
|
||||
getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(2);
|
||||
getChild<LLComboBox>(TEXT_MATURITY)->setCommitCallback(boost::bind(&LLPanelExperiencePicker::onMaturity, this));
|
||||
getChild<LLUICtrl>(TEXT_EDIT)->setFocus(TRUE);
|
||||
|
||||
childSetAction(BTN_LEFT, boost::bind(&LLPanelExperiencePicker::onPage, this, -1));
|
||||
childSetAction(BTN_RIGHT, boost::bind(&LLPanelExperiencePicker::onPage, this, 1));
|
||||
|
||||
LLPanel* search_panel = getChild<LLPanel>(PANEL_SEARCH);
|
||||
if (search_panel)
|
||||
{
|
||||
// Start searching when Return is pressed in the line editor.
|
||||
search_panel->setDefaultBtn(BTN_FIND);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::editKeystroke(class LLLineEditor* caller)
|
||||
{
|
||||
getChildView(BTN_FIND)->setEnabled(!caller->getText().empty());
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onBtnFind()
|
||||
{
|
||||
mCurrentPage=1;
|
||||
boost::cmatch what;
|
||||
std::string text = getChild<LLUICtrl>(TEXT_EDIT)->getValue().asString();
|
||||
// *TODO: this should be part of LLUrlEntry
|
||||
static const boost::regex expression("secondlife:///app/experience/[\\da-f-]+/profile");
|
||||
if (boost::regex_match(text.c_str(), what, expression))
|
||||
{
|
||||
LLURI uri(text);
|
||||
LLSD path_array = uri.pathArray();
|
||||
if (path_array.size() == 4)
|
||||
{
|
||||
std::string exp_id = path_array.get(2).asString();
|
||||
LLUUID experience_id(exp_id);
|
||||
if (!experience_id.isNull())
|
||||
{
|
||||
const LLSD& experience_details = LLExperienceCache::instance().get(experience_id);
|
||||
if(!experience_details.isUndefined())
|
||||
{
|
||||
std::string experience_name_string = experience_details[LLExperienceCache::NAME].asString();
|
||||
if(!experience_name_string.empty())
|
||||
{
|
||||
getChild<LLUICtrl>(TEXT_EDIT)->setValue(experience_name_string);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->deleteAllItems();
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("searching"));
|
||||
|
||||
getChildView(BTN_OK)->setEnabled(FALSE);
|
||||
getChildView(BTN_PROFILE)->setEnabled(FALSE);
|
||||
|
||||
getChildView(BTN_RIGHT)->setEnabled(FALSE);
|
||||
getChildView(BTN_LEFT)->setEnabled(FALSE);
|
||||
LLExperienceCache::instance().get(experience_id, boost::bind(&LLPanelExperiencePicker::onBtnFind, this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
find();
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onList()
|
||||
{
|
||||
bool enabled = isSelectButtonEnabled();
|
||||
getChildView(BTN_OK)->setEnabled(enabled);
|
||||
|
||||
enabled = enabled && getChild<LLScrollListCtrl>(LIST_RESULTS)->getNumSelected() == 1;
|
||||
getChildView(BTN_PROFILE)->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::find()
|
||||
{
|
||||
std::string text = getChild<LLUICtrl>(TEXT_EDIT)->getValue().asString();
|
||||
mQueryID.generate();
|
||||
|
||||
LLExperienceCache::instance().findExperienceByName(text, mCurrentPage,
|
||||
boost::bind(&LLPanelExperiencePicker::findResults, getDerivedHandle<LLPanelExperiencePicker>(), mQueryID, _1));
|
||||
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->deleteAllItems();
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("searching"));
|
||||
|
||||
getChildView(BTN_OK)->setEnabled(FALSE);
|
||||
getChildView(BTN_PROFILE)->setEnabled(FALSE);
|
||||
|
||||
getChildView(BTN_RIGHT)->setEnabled(FALSE);
|
||||
getChildView(BTN_LEFT)->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLPanelExperiencePicker::findResults(LLHandle<LLPanelExperiencePicker> hparent, LLUUID queryId, LLSD foundResult)
|
||||
{
|
||||
if (hparent.isDead())
|
||||
return;
|
||||
|
||||
LLPanelExperiencePicker* panel = hparent.get();
|
||||
if (panel)
|
||||
{
|
||||
panel->processResponse(queryId, foundResult);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::isSelectButtonEnabled()
|
||||
{
|
||||
LLScrollListCtrl* list=getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
return list->getFirstSelectedIndex() >=0;
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::getSelectedExperienceIds( const LLScrollListCtrl* results, uuid_vec_t &experience_ids )
|
||||
{
|
||||
std::vector<LLScrollListItem*> items = results->getAllSelected();
|
||||
for(std::vector<LLScrollListItem*>::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
LLScrollListItem* item = *it;
|
||||
if (item->getUUID().notNull())
|
||||
{
|
||||
experience_ids.push_back(item->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::setAllowMultiple( bool allow_multiple )
|
||||
{
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setAllowMultipleSelection(allow_multiple);
|
||||
}
|
||||
|
||||
|
||||
void name_callback(const LLHandle<LLPanelExperiencePicker>& floater, const LLUUID& experience_id, const LLUUID& agent_id, const LLAvatarName& av_name)
|
||||
{
|
||||
if (floater.isDead())
|
||||
return;
|
||||
LLPanelExperiencePicker* picker = floater.get();
|
||||
LLScrollListCtrl* search_results = picker->getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
|
||||
LLScrollListItem* item = search_results->getItem(experience_id);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item->getColumn(2)->setValue(columnSpace+av_name.getNSName());
|
||||
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::processResponse( const LLUUID& query_id, const LLSD& content )
|
||||
{
|
||||
if (query_id != mQueryID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mResponse = content;
|
||||
|
||||
getChildView(BTN_RIGHT)->setEnabled(content.has("next_page_url"));
|
||||
getChildView(BTN_LEFT)->setEnabled(content.has("previous_page_url"));
|
||||
|
||||
filterContent();
|
||||
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onBtnSelect()
|
||||
{
|
||||
if (!isSelectButtonEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSelectionCallback != nullptr)
|
||||
{
|
||||
const LLScrollListCtrl* results = getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
uuid_vec_t experience_ids;
|
||||
|
||||
getSelectedExperienceIds(results, experience_ids);
|
||||
mSelectionCallback(experience_ids);
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->deselectAllItems(TRUE);
|
||||
if (mCloseOnSelect)
|
||||
{
|
||||
mCloseOnSelect = FALSE;
|
||||
onBtnClose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onBtnProfile();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onBtnClose()
|
||||
{
|
||||
LLFloater* floater = static_cast<LLFloater*>(getParent());
|
||||
if (floater)
|
||||
{
|
||||
floater->close();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onBtnProfile()
|
||||
{
|
||||
LLScrollListItem* item = getChild<LLScrollListCtrl>(LIST_RESULTS)->getFirstSelected();
|
||||
if (item)
|
||||
{
|
||||
LLFloaterExperienceProfile::showInstance(item->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLPanelExperiencePicker::getMaturityString(int maturity)
|
||||
{
|
||||
if (maturity <= SIM_ACCESS_PG)
|
||||
{
|
||||
return getString("maturity_icon_general");
|
||||
}
|
||||
else if (maturity <= SIM_ACCESS_MATURE)
|
||||
{
|
||||
return getString("maturity_icon_moderate");
|
||||
}
|
||||
return getString("maturity_icon_adult");
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::filterContent()
|
||||
{
|
||||
LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
|
||||
const LLSD& experiences=mResponse["experience_keys"];
|
||||
|
||||
search_results->deleteAllItems();
|
||||
|
||||
LLSD item;
|
||||
LLSD::array_const_iterator it = experiences.beginArray();
|
||||
for ( ; it != experiences.endArray(); ++it)
|
||||
{
|
||||
const LLSD& experience = *it;
|
||||
|
||||
if (isExperienceHidden(experience))
|
||||
continue;
|
||||
|
||||
std::string experience_name_string = experience[LLExperienceCache::NAME].asString();
|
||||
if (experience_name_string.empty())
|
||||
{
|
||||
experience_name_string = LLTrans::getString("ExperienceNameUntitled");
|
||||
}
|
||||
|
||||
item["id"]=experience[LLExperienceCache::EXPERIENCE_ID];
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "maturity";
|
||||
columns[0]["value"] = getMaturityString(experience[LLExperienceCache::MATURITY].asInteger());
|
||||
columns[0]["type"]="icon";
|
||||
columns[0]["halign"]="right";
|
||||
columns[1]["column"] = "experience_name";
|
||||
columns[1]["value"] = columnSpace+experience_name_string;
|
||||
columns[2]["column"] = "owner";
|
||||
columns[2]["value"] = columnSpace+getString("loading");
|
||||
search_results->addElement(item);
|
||||
LLAvatarNameCache::get(experience[LLExperienceCache::AGENT_ID], boost::bind(name_callback, getDerivedHandle<LLPanelExperiencePicker>(), experience[LLExperienceCache::EXPERIENCE_ID], _1, _2));
|
||||
}
|
||||
|
||||
if (search_results->isEmpty())
|
||||
{
|
||||
LLStringUtil::format_map_t map;
|
||||
std::string search_text = getChild<LLUICtrl>(TEXT_EDIT)->getValue().asString();
|
||||
map["[TEXT]"] = search_text;
|
||||
if (search_text.empty())
|
||||
{
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("no_results"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("not_found", map));
|
||||
}
|
||||
search_results->setEnabled(false);
|
||||
getChildView(BTN_OK)->setEnabled(false);
|
||||
getChildView(BTN_PROFILE)->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChildView(BTN_OK)->setEnabled(true);
|
||||
search_results->setEnabled(true);
|
||||
search_results->sortByColumnIndex(1, TRUE);
|
||||
std::string text = getChild<LLUICtrl>(TEXT_EDIT)->getValue().asString();
|
||||
if (!search_results->selectItemByLabel(text, TRUE))
|
||||
{
|
||||
search_results->selectFirstItem();
|
||||
}
|
||||
onList();
|
||||
search_results->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onMaturity()
|
||||
{
|
||||
if (mResponse.has("experience_keys") && mResponse["experience_keys"].beginArray() != mResponse["experience_keys"].endArray())
|
||||
{
|
||||
filterContent();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::isExperienceHidden( const LLSD& experience) const
|
||||
{
|
||||
bool hide=false;
|
||||
filter_list::const_iterator it = mFilters.begin();
|
||||
for(/**/;it != mFilters.end(); ++it)
|
||||
{
|
||||
if ((*it)(experience)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return hide;
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::FilterOverRating( const LLSD& experience )
|
||||
{
|
||||
int maturity = getChild<LLComboBox>(TEXT_MATURITY)->getSelectedValue().asInteger();
|
||||
return experience[LLExperienceCache::MATURITY].asInteger() > maturity;
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::FilterWithProperty( const LLSD& experience, S32 prop)
|
||||
{
|
||||
return (experience[LLExperienceCache::PROPERTIES].asInteger() & prop) != 0;
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::FilterWithoutProperties( const LLSD& experience, S32 prop)
|
||||
{
|
||||
return ((experience[LLExperienceCache::PROPERTIES].asInteger() & prop) == prop);
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::FilterWithoutProperty( const LLSD& experience, S32 prop )
|
||||
{
|
||||
return (experience[LLExperienceCache::PROPERTIES].asInteger() & prop) == 0;
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::setDefaultFilters()
|
||||
{
|
||||
mFilters.clear();
|
||||
addFilter(boost::bind(&LLPanelExperiencePicker::FilterOverRating, this, _1));
|
||||
}
|
||||
|
||||
bool LLPanelExperiencePicker::FilterMatching( const LLSD& experience, const LLUUID& id )
|
||||
{
|
||||
if (experience.isUUID())
|
||||
{
|
||||
return experience.asUUID() == id;
|
||||
}
|
||||
return experience[LLExperienceCache::EXPERIENCE_ID].asUUID() == id;
|
||||
}
|
||||
|
||||
void LLPanelExperiencePicker::onPage( S32 direction )
|
||||
{
|
||||
mCurrentPage += direction;
|
||||
if (mCurrentPage < 1)
|
||||
{
|
||||
mCurrentPage = 1;
|
||||
}
|
||||
find();
|
||||
}
|
||||
|
||||
96
indra/newview/llpanelexperiencepicker.h
Normal file
96
indra/newview/llpanelexperiencepicker.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file llpanelexperiencepicker.h
|
||||
* @brief Header file for llpanelexperiencepicker
|
||||
* @author dolphin@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, 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_LLPANELEXPERIENCEPICKER_H
|
||||
#define LL_LLPANELEXPERIENCEPICKER_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLScrollListCtrl;
|
||||
class LLLineEditor;
|
||||
|
||||
void* create_xp_picker(void* data);
|
||||
class LLPanelExperiencePicker final : public LLPanel
|
||||
{
|
||||
public:
|
||||
friend class LLExperienceSearchResponder;
|
||||
friend class LLFloaterExperiencePicker;
|
||||
|
||||
typedef std::function<void (const uuid_vec_t&)> select_callback_t;
|
||||
// filter function for experiences, return true if the experience should be hidden.
|
||||
typedef std::function<bool (const LLSD&)> filter_function;
|
||||
typedef std::vector<filter_function> filter_list;
|
||||
|
||||
LLPanelExperiencePicker(bool build = true);
|
||||
virtual ~LLPanelExperiencePicker();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void addFilter(filter_function func){mFilters.push_back(func);}
|
||||
template <class IT>
|
||||
void addFilters(IT begin, IT end){mFilters.insert(mFilters.end(), begin, end);}
|
||||
void setDefaultFilters();
|
||||
|
||||
static bool FilterWithProperty(const LLSD& experience, S32 prop);
|
||||
static bool FilterWithoutProperties(const LLSD& experience, S32 prop);
|
||||
static bool FilterWithoutProperty(const LLSD& experience, S32 prop);
|
||||
static bool FilterMatching(const LLSD& experience, const LLUUID& id);
|
||||
bool FilterOverRating(const LLSD& experience);
|
||||
|
||||
private:
|
||||
void editKeystroke(LLLineEditor* caller);
|
||||
|
||||
void onBtnFind();
|
||||
void onBtnSelect();
|
||||
void onBtnClose();
|
||||
void onBtnProfile();
|
||||
void onList();
|
||||
void onMaturity();
|
||||
void onPage(S32 direction);
|
||||
|
||||
void getSelectedExperienceIds( const LLScrollListCtrl* results, uuid_vec_t &experience_ids );
|
||||
void setAllowMultiple(bool allow_multiple);
|
||||
|
||||
void find();
|
||||
static void findResults(LLHandle<LLPanelExperiencePicker> hparent, LLUUID queryId, LLSD foundResult);
|
||||
|
||||
bool isSelectButtonEnabled();
|
||||
void processResponse( const LLUUID& query_id, const LLSD& content );
|
||||
|
||||
void filterContent();
|
||||
bool isExperienceHidden(const LLSD& experience) const ;
|
||||
std::string getMaturityString(int maturity);
|
||||
|
||||
|
||||
select_callback_t mSelectionCallback;
|
||||
filter_list mFilters;
|
||||
LLUUID mQueryID;
|
||||
LLSD mResponse;
|
||||
bool mCloseOnSelect;
|
||||
S32 mCurrentPage;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELEXPERIENCEPICKER_H
|
||||
153
indra/newview/llpanelexperiences.cpp
Normal file
153
indra/newview/llpanelexperiences.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @file llpanelexperiences.cpp
|
||||
* @brief LLPanelExperiences class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, 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 "lluictrlfactory.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llagent.h"
|
||||
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llpanelexperiences.h"
|
||||
#include "lllayoutstack.h"
|
||||
#include "llnamelistctrl.h"
|
||||
|
||||
//static LLPanelInjector<LLPanelExperiences> register_experiences_panel("experiences_panel");
|
||||
|
||||
LLPanelExperiences::LLPanelExperiences()
|
||||
: mExperiencesList(nullptr)
|
||||
{
|
||||
//buildFromFile("panel_experiences.xml");
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_experiences.xml");
|
||||
}
|
||||
|
||||
BOOL LLPanelExperiences::postBuild( void )
|
||||
{
|
||||
mExperiencesList = getChild<LLNameListCtrl>("experiences_list");
|
||||
if (hasString("loading_experiences"))
|
||||
{
|
||||
mExperiencesList->setCommentText(getString("loading_experiences"));
|
||||
}
|
||||
else if (hasString("no_experiences"))
|
||||
{
|
||||
mExperiencesList->setCommentText(getString("no_experiences"));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void addExperienceToList(const LLSD& experience, LLNameListCtrl* list)
|
||||
{
|
||||
// Don't add missing experiences, that seems wrong
|
||||
if (experience.has(LLExperienceCache::MISSING) && experience[LLExperienceCache::MISSING].asBoolean())
|
||||
return;
|
||||
|
||||
const auto& id = experience[LLExperienceCache::EXPERIENCE_ID];
|
||||
auto item = LLNameListCtrl::NameItem()
|
||||
.name(experience[LLExperienceCache::NAME].asString())
|
||||
.target(LLNameListItem::EXPERIENCE);
|
||||
item.value(id)
|
||||
.columns.add(LLScrollListCell::Params()); // Dummy column for names
|
||||
list->addNameItemRow(item);
|
||||
}
|
||||
|
||||
void LLPanelExperiences::setExperienceList( const LLSD& experiences )
|
||||
{
|
||||
mExperiencesList->setSortEnabled(false);
|
||||
|
||||
if (hasString("no_experiences"))
|
||||
{
|
||||
mExperiencesList->setCommentText(getString("no_experiences"));
|
||||
}
|
||||
mExperiencesList->clear();
|
||||
|
||||
auto& cache = LLExperienceCache::instance();
|
||||
LLSD::array_const_iterator it = experiences.beginArray();
|
||||
for( /**/ ; it != experiences.endArray(); ++it)
|
||||
{
|
||||
LLUUID public_key = it->asUUID();
|
||||
if (public_key.notNull())
|
||||
cache.get(public_key, boost::bind(addExperienceToList, _1, mExperiencesList));
|
||||
}
|
||||
|
||||
mExperiencesList->setSortEnabled(true);
|
||||
}
|
||||
|
||||
void LLPanelExperiences::getExperienceIdsList(uuid_vec_t& result)
|
||||
{
|
||||
result = mExperiencesList->getAllIDs();
|
||||
}
|
||||
|
||||
LLPanelExperiences* LLPanelExperiences::create(const std::string& name)
|
||||
{
|
||||
LLPanelExperiences* panel= new LLPanelExperiences();
|
||||
panel->setName(name);
|
||||
return panel;
|
||||
}
|
||||
|
||||
void LLPanelExperiences::removeExperiences( const LLSD& ids )
|
||||
{
|
||||
LLSD::array_const_iterator it = ids.beginArray();
|
||||
for( /**/ ; it != ids.endArray(); ++it)
|
||||
{
|
||||
removeExperience(it->asUUID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiences::removeExperience( const LLUUID& id )
|
||||
{
|
||||
mExperiencesList->removeNameItem(id);
|
||||
}
|
||||
|
||||
void LLPanelExperiences::addExperience( const LLUUID& id )
|
||||
{
|
||||
if (!mExperiencesList->getItem(id))
|
||||
{
|
||||
LLExperienceCache::instance().get(id, boost::bind(addExperienceToList, _1, mExperiencesList));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiences::setButtonAction(const std::string& label, const commit_signal_t::slot_type& cb )
|
||||
{
|
||||
if(label.empty())
|
||||
{
|
||||
getChild<LLLayoutPanel>("button_panel")->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLLayoutPanel>("button_panel")->setVisible(true);
|
||||
LLButton* child = getChild<LLButton>("btn_action");
|
||||
child->setCommitCallback(cb);
|
||||
child->setLabel(getString(label));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperiences::enableButton( bool enable )
|
||||
{
|
||||
getChild<LLButton>("btn_action")->setEnabled(enable);
|
||||
}
|
||||
54
indra/newview/llpanelexperiences.h
Normal file
54
indra/newview/llpanelexperiences.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file llpanelexperiences.h
|
||||
* @brief LLPanelExperiences class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, 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_LLPANELEXPERIENCES_H
|
||||
#define LL_LLPANELEXPERIENCES_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLPanelExperiences final
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelExperiences();
|
||||
|
||||
static LLPanelExperiences* create(const std::string& name);
|
||||
|
||||
/*virtual*/ BOOL postBuild(void) override;
|
||||
|
||||
void setExperienceList(const LLSD& experiences);
|
||||
void getExperienceIdsList(uuid_vec_t& result);
|
||||
|
||||
void removeExperiences( const LLSD& ids );
|
||||
void removeExperience( const LLUUID& id);
|
||||
void addExperience( const LLUUID& id);
|
||||
void setButtonAction(const std::string& label, const commit_signal_t::slot_type& cb);
|
||||
void enableButton(bool enable);
|
||||
|
||||
private:
|
||||
class LLNameListCtrl* mExperiencesList;
|
||||
};
|
||||
#endif // LL_LLPANELEXPERIENCES_H
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "llpanelgrouproles.h"
|
||||
#include "llpanelgroupvoting.h"
|
||||
#include "llpanelgrouplandmoney.h"
|
||||
#include "llpanelgroupexperiences.h"
|
||||
|
||||
// static
|
||||
void* LLPanelGroupTab::createTab(void* data)
|
||||
@@ -154,6 +155,8 @@ LLPanelGroup::LLPanelGroup(const LLUUID& group_id)
|
||||
&mID);
|
||||
mFactoryMap["land_money_tab"]= LLCallbackMap(LLPanelGroupLandMoney::createTab,
|
||||
&mID);
|
||||
mFactoryMap["experiences_tab"] = LLCallbackMap(LLPanelGroupExperiences::createTab,
|
||||
&mID);
|
||||
// Roles sub tabs
|
||||
mFactoryMap["members_sub_tab"] = LLCallbackMap(LLPanelGroupMembersSubTab::createTab, &mID);
|
||||
mFactoryMap["roles_sub_tab"] = LLCallbackMap(LLPanelGroupRolesSubTab::createTab, &mID);
|
||||
|
||||
131
indra/newview/llpanelgroupexperiences.cpp
Normal file
131
indra/newview/llpanelgroupexperiences.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @file llpanelgroupexperiences.cpp
|
||||
* @brief List of experiences owned by a group.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&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 "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelgroupexperiences.h"
|
||||
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llnamelistctrl.h"
|
||||
|
||||
void addExperienceToList(const LLSD& experience, LLNameListCtrl* list);
|
||||
|
||||
//static LLPanelInjector<LLPanelGroupExperiences> t_panel_group_experiences("panel_group_experiences");
|
||||
//static
|
||||
void* LLPanelGroupExperiences::createTab(void* data)
|
||||
{
|
||||
LLUUID* group_id = static_cast<LLUUID*>(data);
|
||||
return new LLPanelGroupExperiences("panel group experiences", *group_id);
|
||||
}
|
||||
|
||||
|
||||
LLPanelGroupExperiences::LLPanelGroupExperiences(const std::string& name, const LLUUID& id)
|
||||
: LLPanelGroupTab(name, id), mExperiencesList(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelGroupExperiences::~LLPanelGroupExperiences()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLPanelGroupExperiences::isVisibleByAgent(LLAgent* agentp)
|
||||
{
|
||||
//default to being visible
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLPanelGroupExperiences::postBuild()
|
||||
{
|
||||
mExperiencesList = getChild<LLNameListCtrl>("experiences_list");
|
||||
if (hasString("loading_experiences"))
|
||||
{
|
||||
mExperiencesList->setCommentText(getString("loading_experiences"));
|
||||
}
|
||||
else if (hasString("no_experiences"))
|
||||
{
|
||||
mExperiencesList->setCommentText(getString("no_experiences"));
|
||||
}
|
||||
|
||||
return LLPanelGroupTab::postBuild();
|
||||
}
|
||||
|
||||
void LLPanelGroupExperiences::activate()
|
||||
{
|
||||
if ((getGroupID() == LLUUID::null) || gDisconnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLExperienceCache::instance().getGroupExperiences(getGroupID(),
|
||||
boost::bind(&LLPanelGroupExperiences::groupExperiencesResults, getDerivedHandle<LLPanelGroupExperiences>(), _1));
|
||||
}
|
||||
|
||||
void LLPanelGroupExperiences::setGroupID(const LLUUID& id)
|
||||
{
|
||||
LLPanelGroupTab::setGroupID(id);
|
||||
|
||||
if (id == LLUUID::null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
activate();
|
||||
}
|
||||
|
||||
void LLPanelGroupExperiences::setExperienceList(const LLSD& experiences)
|
||||
{
|
||||
if (hasString("no_experiences"))
|
||||
{
|
||||
mExperiencesList->setCommentText(getString("no_experiences"));
|
||||
}
|
||||
mExperiencesList->clear();
|
||||
|
||||
auto& cache = LLExperienceCache::instance();
|
||||
LLSD::array_const_iterator it = experiences.beginArray();
|
||||
for ( /**/ ; it != experiences.endArray(); ++it)
|
||||
{
|
||||
LLUUID public_key = it->asUUID();
|
||||
if (public_key.notNull())
|
||||
cache.get(public_key, boost::bind(addExperienceToList, _1, mExperiencesList));
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLPanelGroupExperiences::groupExperiencesResults(LLHandle<LLPanelGroupExperiences> handle, const LLSD &experiences)
|
||||
{
|
||||
if (handle.isDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLPanelGroupExperiences* panel = handle.get();
|
||||
if (panel)
|
||||
{
|
||||
panel->setExperienceList(experiences);
|
||||
}
|
||||
}
|
||||
56
indra/newview/llpanelgroupexperiences.h
Normal file
56
indra/newview/llpanelgroupexperiences.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file llpanelgroupexperiences.h
|
||||
* @brief List of experiences owned by a group.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&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_LLPANELGROUPEXPERIENCES_H
|
||||
#define LL_LLPANELGROUPEXPERIENCES_H
|
||||
|
||||
#include "llpanelgroup.h"
|
||||
|
||||
class LLPanelGroupExperiences final : public LLPanelGroupTab
|
||||
{
|
||||
public:
|
||||
static void* createTab(void* data);
|
||||
LLPanelGroupExperiences(const std::string& name, const LLUUID& id);
|
||||
virtual ~LLPanelGroupExperiences();
|
||||
|
||||
// LLPanelGroupTab
|
||||
void activate() override;
|
||||
BOOL isVisibleByAgent(LLAgent* agentp) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void setGroupID(const LLUUID& id) override;
|
||||
|
||||
void setExperienceList(const LLSD& experiences);
|
||||
|
||||
protected:
|
||||
class LLNameListCtrl* mExperiencesList;
|
||||
|
||||
private:
|
||||
static void groupExperiencesResults(LLHandle<LLPanelGroupExperiences>, const LLSD &);
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,8 +81,8 @@ public:
|
||||
|
||||
void initMenu();
|
||||
|
||||
virtual void draw();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void draw() override;
|
||||
BOOL postBuild() override;
|
||||
BOOL canClose();
|
||||
void setEnableEditing(bool enable);
|
||||
|
||||
@@ -104,7 +104,6 @@ public:
|
||||
static void onClickForward(void* userdata);
|
||||
static void onBtnInsertSample(void*);
|
||||
static void onBtnInsertFunction(LLUICtrl*, void*);
|
||||
|
||||
// Singu TODO: modernize the menu callbacks and get rid of/update this giant block of static functions
|
||||
static BOOL hasChanged(void* userdata);
|
||||
static void onBtnSave(void*);
|
||||
@@ -127,7 +126,9 @@ public:
|
||||
static BOOL enableSelectAllMenu(void* userdata);
|
||||
static BOOL enableDeselectMenu(void* userdata);
|
||||
|
||||
virtual bool hasAccelerators() const { return true; }
|
||||
bool hasAccelerators() const override { return true; }
|
||||
LLUUID getAssociatedExperience() const;
|
||||
void setAssociatedExperience(const LLUUID& experience_id);
|
||||
|
||||
private:
|
||||
static bool onHelpWebDialog(const LLSD& notification, const LLSD& response);
|
||||
@@ -139,7 +140,7 @@ private:
|
||||
|
||||
void selectFirstError();
|
||||
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
BOOL handleKeyHere(KEY key, MASK mask) override;
|
||||
|
||||
void enableSave(BOOL b) {mEnableSave = b;}
|
||||
|
||||
@@ -169,6 +170,7 @@ private:
|
||||
BOOL mEnableSave;
|
||||
BOOL mHasScriptData;
|
||||
LLLiveLSLFile* mLiveFile;
|
||||
LLUUID mAssociatedExperience;
|
||||
|
||||
LLScriptEdContainer* mContainer; // parent view
|
||||
|
||||
@@ -194,41 +196,37 @@ protected:
|
||||
bool onExternalChange(const std::string& filename);
|
||||
virtual void saveIfNeeded(bool sync = true) = 0;
|
||||
|
||||
LLTextEditor* getEditor() { return mScriptEd->mEditor; }
|
||||
/*virtual*/ const char *getTitleName() const { return "Script"; }
|
||||
LLTextEditor* getEditor() const { return mScriptEd->mEditor; }
|
||||
/*virtual*/ const char *getTitleName() const override { return "Script"; }
|
||||
// <edit>
|
||||
/*virtual*/ BOOL canSaveAs() const;
|
||||
/*virtual*/ void saveAs();
|
||||
/*virtual*/ BOOL canSaveAs() const override;
|
||||
/*virtual*/ void saveAs() override;
|
||||
void saveAs_continued(AIFilePicker* filepicker);
|
||||
// </edit>
|
||||
|
||||
LLScriptEdCore* mScriptEd;
|
||||
};
|
||||
|
||||
// Used to view and edit a LSL from your inventory.
|
||||
class LLPreviewLSL : public LLScriptEdContainer
|
||||
// Used to view and edit an LSL script from your inventory.
|
||||
class LLPreviewLSL final : public LLScriptEdContainer
|
||||
{
|
||||
public:
|
||||
LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid );
|
||||
virtual void callbackLSLCompileSucceeded();
|
||||
virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
|
||||
|
||||
protected:
|
||||
virtual BOOL canClose();
|
||||
BOOL canClose() override;
|
||||
void closeIfNeeded();
|
||||
|
||||
virtual void loadAsset();
|
||||
/*virtual*/ void saveIfNeeded(bool sync = true);
|
||||
void loadAsset() override;
|
||||
/*virtual*/ void saveIfNeeded(bool sync = true) override;
|
||||
void uploadAssetViaCaps(const std::string& url,
|
||||
const std::string& filename,
|
||||
const LLUUID& item_id);
|
||||
#if 0 //Client side compiling disabled.
|
||||
void uploadAssetLegacy(const std::string& filename,
|
||||
const LLUUID& item_id,
|
||||
const LLTransactionID& tid);
|
||||
#endif
|
||||
|
||||
static void onSearchReplace(void* userdata);
|
||||
static void onLoad(void* userdata);
|
||||
@@ -237,10 +235,6 @@ protected:
|
||||
static void onLoadComplete(LLVFS *vfs, const LLUUID& uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
#if 0 //Client side compiling disabled.
|
||||
static void onSaveComplete(const LLUUID& uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||
static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
static void* createScriptEdPanel(void* userdata);
|
||||
@@ -254,8 +248,8 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
// Used to view and edit an LSL that is attached to an object.
|
||||
class LLLiveLSLEditor : public LLScriptEdContainer
|
||||
// Used to view and edit an LSL script that is attached to an object.
|
||||
class LLLiveLSLEditor final : public LLScriptEdContainer
|
||||
{
|
||||
friend class LLLiveLSLFile;
|
||||
public:
|
||||
@@ -269,29 +263,35 @@ public:
|
||||
bool is_script_running);
|
||||
virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
|
||||
void setIsNew() { mIsNew = TRUE; }
|
||||
|
||||
private:
|
||||
virtual BOOL canClose();
|
||||
void closeIfNeeded();
|
||||
virtual void draw();
|
||||
static void setAssociatedExperience(LLHandle<LLLiveLSLEditor> editor, const LLSD& experience);
|
||||
static void onToggleExperience(LLUICtrl* ui, void* userdata);
|
||||
static void onViewProfile(LLUICtrl* ui, void* userdata);
|
||||
|
||||
virtual void loadAsset();
|
||||
void setExperienceIds(const LLSD& experience_ids);
|
||||
void buildExperienceList();
|
||||
void updateExperiencePanel();
|
||||
void requestExperiences();
|
||||
void experienceChanged();
|
||||
void addAssociatedExperience(const LLSD& experience);
|
||||
|
||||
private:
|
||||
BOOL canClose() override;
|
||||
void closeIfNeeded();
|
||||
void draw() override;
|
||||
|
||||
void loadAsset() override;
|
||||
void loadAsset(BOOL is_new);
|
||||
/*virtual*/ void saveIfNeeded(bool sync = true);
|
||||
/*virtual*/ void saveIfNeeded(bool sync = true) override;
|
||||
void uploadAssetViaCaps(const std::string& url,
|
||||
const std::string& filename,
|
||||
const std::string& filename,
|
||||
const LLUUID& task_id,
|
||||
const LLUUID& item_id,
|
||||
BOOL is_running);
|
||||
#if 0 //Client side compiling disabled.
|
||||
void uploadAssetLegacy(const std::string& filename,
|
||||
LLViewerObject* object,
|
||||
const LLTransactionID& tid,
|
||||
BOOL is_running);
|
||||
#endif
|
||||
BOOL is_running,
|
||||
const LLUUID& experience_public_id);
|
||||
BOOL monoChecked() const;
|
||||
|
||||
|
||||
@@ -302,10 +302,6 @@ private:
|
||||
static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
#if 0 //Client side compiling disabled.
|
||||
static void onSaveTextComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||
static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||
#endif
|
||||
static void onRunningCheckboxClicked(LLUICtrl*, void* userdata);
|
||||
static void onReset(void* userdata);
|
||||
|
||||
@@ -317,6 +313,8 @@ private:
|
||||
|
||||
static void onMonoCheckboxClicked(LLUICtrl*, void* userdata);
|
||||
|
||||
static void receiveExperienceIds(const struct LLCoroResponder& responder, LLHandle<LLLiveLSLEditor> parent);
|
||||
|
||||
private:
|
||||
bool mIsNew;
|
||||
//LLUUID mTransmitID;
|
||||
@@ -330,9 +328,16 @@ private:
|
||||
S32 mPendingUploads;
|
||||
|
||||
BOOL getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert
|
||||
|
||||
|
||||
LLCheckBoxCtrl* mMonoCheckbox;
|
||||
BOOL mIsModifiable;
|
||||
|
||||
|
||||
LLComboBox* mExperiences;
|
||||
LLCheckBoxCtrl* mExperienceEnabled;
|
||||
LLSD mExperienceIds;
|
||||
|
||||
LLHandle<LLFloater> mExperienceProfile;
|
||||
};
|
||||
|
||||
#endif // LL_LLPREVIEWSCRIPT_H
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
#include "llviewermedia_streamingaudio.h"
|
||||
#include "llaudioengine.h"
|
||||
|
||||
|
||||
#if LL_FMODSTUDIO
|
||||
#ifdef LL_FMODSTUDIO
|
||||
# include "llaudioengine_fmodstudio.h"
|
||||
#endif
|
||||
|
||||
@@ -61,6 +60,7 @@
|
||||
|
||||
#include "llares.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "lllandmark.h"
|
||||
#include "llcachename.h"
|
||||
#include "lldir.h"
|
||||
@@ -230,7 +230,6 @@
|
||||
// </edit>
|
||||
|
||||
#include "llpathfindingmanager.h"
|
||||
#include "llevents.h"
|
||||
|
||||
#include "lgghunspell_wrapper.h"
|
||||
|
||||
@@ -238,6 +237,8 @@
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
#include "llevents.h"
|
||||
#include "llexperiencelog.h"
|
||||
#if LL_WINDOWS
|
||||
#include "llwindebug.h"
|
||||
#include "lldxhardware.h"
|
||||
@@ -1725,6 +1726,9 @@ bool idle_startup()
|
||||
// object is created. I think this must be done after setting the region. JC
|
||||
gAgent.setPositionAgent(agent_start_position_region);
|
||||
|
||||
display_startup();
|
||||
LLStartUp::initExperiences();
|
||||
|
||||
display_startup();
|
||||
LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT );
|
||||
return FALSE;
|
||||
@@ -3541,12 +3545,22 @@ void LLStartUp::initNameCache()
|
||||
LLAvatarNameCache::setUseUsernames(!phoenix_name_system || phoenix_name_system == 1 || phoenix_name_system == 3);
|
||||
}
|
||||
|
||||
|
||||
void LLStartUp::initExperiences()
|
||||
{
|
||||
// Should trigger loading the cache.
|
||||
LLExperienceCache::instance().setCapabilityQuery(
|
||||
boost::bind(&LLAgent::getRegionCapability, &gAgent, _1));
|
||||
|
||||
LLExperienceLog::instance().initialize();
|
||||
}
|
||||
|
||||
void LLStartUp::cleanupNameCache()
|
||||
{
|
||||
LLAvatarNameCache::cleanupClass();
|
||||
|
||||
delete gCacheName;
|
||||
gCacheName = NULL;
|
||||
gCacheName = nullptr;
|
||||
}
|
||||
|
||||
bool LLStartUp::dispatchURL()
|
||||
@@ -4278,3 +4292,4 @@ void transition_back_to_login_panel(const std::string& emsg)
|
||||
reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
|
||||
gSavedSettings.setBOOL("AutoLogin", FALSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
static void fontInit();
|
||||
|
||||
static void initNameCache();
|
||||
static void initExperiences();
|
||||
|
||||
static void cleanupNameCache();
|
||||
|
||||
|
||||
@@ -523,7 +523,7 @@ class SGHostBlackList{
|
||||
} //should make a functor. if i cared.
|
||||
|
||||
static void cleanup() {
|
||||
std::remove_if(blacklist.begin(), blacklist.end(), is_obsolete);
|
||||
(void)std::remove_if(blacklist.begin(), blacklist.end(), is_obsolete);
|
||||
}
|
||||
|
||||
static iter find(std::string host) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -121,20 +121,18 @@ LLViewerParcelMgr::LLViewerParcelMgr()
|
||||
mHoverRequestResult(0),
|
||||
mHoverWestSouth(),
|
||||
mHoverEastNorth(),
|
||||
mCollisionRegionHandle(0),
|
||||
mCollisionUpdateSignal(nullptr),
|
||||
mRenderCollision(FALSE),
|
||||
mRenderSelection(TRUE),
|
||||
mCollisionBanned(0),
|
||||
mCollisionTimer(),
|
||||
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0)
|
||||
mCollisionRegionHandle(0),
|
||||
mCollisionUpdateSignal(NULL),
|
||||
// [/SL:KB]
|
||||
mMediaParcelId(0),
|
||||
mMediaRegionId(0),
|
||||
mHighlightSegments(NULL),
|
||||
mCollisionSegments(NULL),
|
||||
mAgentParcelOverlay(NULL),
|
||||
mParcelsPerEdge(0)
|
||||
mHighlightSegments(nullptr),
|
||||
mCollisionSegments(nullptr),
|
||||
mAgentParcelOverlay(nullptr),
|
||||
mParcelsPerEdge(0),
|
||||
mMediaRegionId(0)
|
||||
{
|
||||
mCurrentParcel = new LLParcel();
|
||||
mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
|
||||
@@ -144,17 +142,12 @@ LLViewerParcelMgr::LLViewerParcelMgr()
|
||||
mHoverParcel = new LLParcel();
|
||||
mCollisionParcel = new LLParcel();
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
mParcelsPerEdge = S32(8192.f / PARCEL_GRID_STEP_METERS); // 8192 is the maximum region size on WhiteCore and solves the audio problem.
|
||||
//mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS );
|
||||
// </FS:CR> Aurora Sim
|
||||
mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
|
||||
resetSegments(mHighlightSegments);
|
||||
|
||||
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0)
|
||||
mCollisionBitmap = new U8[getCollisionBitmapSize()];
|
||||
memset(mCollisionBitmap, 0, getCollisionBitmapSize());
|
||||
// [/SL:KB]
|
||||
|
||||
mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
|
||||
resetSegments(mCollisionSegments);
|
||||
@@ -175,19 +168,14 @@ LLViewerParcelMgr::LLViewerParcelMgr()
|
||||
mAgentParcelOverlay[i] = 0;
|
||||
}
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
mParcelsPerEdge = S32(REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS);
|
||||
// </FS:CR> Aurora Sim
|
||||
|
||||
mTeleportInProgress = TRUE; // the initial parcel update is treated like teleport
|
||||
}
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
void LLViewerParcelMgr::init(F32 region_size)
|
||||
{
|
||||
mParcelsPerEdge = S32(region_size / PARCEL_GRID_STEP_METERS);
|
||||
}
|
||||
// </FS:CR> Aurora Sim
|
||||
|
||||
LLViewerParcelMgr::~LLViewerParcelMgr()
|
||||
{
|
||||
@@ -212,10 +200,8 @@ LLViewerParcelMgr::~LLViewerParcelMgr()
|
||||
delete[] mHighlightSegments;
|
||||
mHighlightSegments = NULL;
|
||||
|
||||
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0)
|
||||
delete[] mCollisionBitmap;
|
||||
mCollisionBitmap = NULL;
|
||||
// [/SL:KB]
|
||||
|
||||
delete[] mCollisionSegments;
|
||||
mCollisionSegments = NULL;
|
||||
@@ -239,11 +225,9 @@ void LLViewerParcelMgr::dump()
|
||||
mCurrentParcel->dump();
|
||||
LL_INFOS() << "banning " << mCurrentParcel->mBanList.size() << LL_ENDL;
|
||||
|
||||
access_map_const_iterator cit = mCurrentParcel->mBanList.begin();
|
||||
access_map_const_iterator end = mCurrentParcel->mBanList.end();
|
||||
for ( ; cit != end; ++cit)
|
||||
for (const auto& pair : mCurrentParcel->mBanList)
|
||||
{
|
||||
LL_INFOS() << "ban id " << (*cit).first << LL_ENDL;
|
||||
LL_INFOS() << "ban id " << pair.first << LL_ENDL;
|
||||
}
|
||||
LL_INFOS() << "Hover parcel:" << LL_ENDL;
|
||||
mHoverParcel->dump();
|
||||
@@ -252,7 +236,7 @@ void LLViewerParcelMgr::dump()
|
||||
}
|
||||
|
||||
|
||||
LLViewerRegion* LLViewerParcelMgr::getSelectionRegion()
|
||||
LLViewerRegion* LLViewerParcelMgr::getSelectionRegion() const
|
||||
{
|
||||
return LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
|
||||
}
|
||||
@@ -472,14 +456,9 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectParcelInRectangle()
|
||||
void LLViewerParcelMgr::selectCollisionParcel()
|
||||
{
|
||||
// BUG: Claim to be in the agent's region
|
||||
// <FS:CR> Aurora Sim
|
||||
//mWestSouth = gAgent.getRegion()->getOriginGlobal();
|
||||
//mEastNorth = mWestSouth;
|
||||
//mEastNorth += LLVector3d(PARCEL_GRID_STEP_METERS, PARCEL_GRID_STEP_METERS, 0.0);
|
||||
mWestSouth = getSelectionRegion()->getOriginGlobal();
|
||||
mEastNorth = mWestSouth;
|
||||
mEastNorth += LLVector3d(getSelectionRegion()->getWidth()/REGION_WIDTH_METERS * PARCEL_GRID_STEP_METERS, getSelectionRegion()->getWidth()/REGION_WIDTH_METERS * PARCEL_GRID_STEP_METERS, 0.0);
|
||||
// </FS:CR> Aurora Sim
|
||||
|
||||
// BUG: must be in the sim you are in
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
@@ -891,8 +870,8 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const
|
||||
|
||||
void LLViewerParcelMgr::render()
|
||||
{
|
||||
static const LLCachedControl<bool> RenderParcelSelection("RenderParcelSelection");
|
||||
if (mSelected && mRenderSelection && RenderParcelSelection)
|
||||
static const LLCachedControl<bool> render_parcel_selection(gSavedSettings, "RenderParcelSelection");
|
||||
if (mSelected && mRenderSelection && render_parcel_selection)
|
||||
{
|
||||
// Rendering is done in agent-coordinates, so need to supply
|
||||
// an appropriate offset to the render code.
|
||||
@@ -912,8 +891,8 @@ void LLViewerParcelMgr::renderParcelCollision()
|
||||
mRenderCollision = FALSE;
|
||||
}
|
||||
|
||||
static const LLCachedControl<bool> ShowBanLines("ShowBanLines");
|
||||
if (mRenderCollision && ShowBanLines)
|
||||
static const LLCachedControl<bool> render_ban_line(gSavedSettings, "ShowBanLines");
|
||||
if (mRenderCollision && render_ban_line)
|
||||
{
|
||||
LLViewerRegion* regionp = gAgent.getRegion();
|
||||
if (regionp)
|
||||
@@ -936,7 +915,7 @@ void LLViewerParcelMgr::sendParcelAccessListRequest(U32 flags)
|
||||
if (!region) return;
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
|
||||
|
||||
if (flags & AL_BAN)
|
||||
{
|
||||
@@ -946,6 +925,14 @@ void LLViewerParcelMgr::sendParcelAccessListRequest(U32 flags)
|
||||
{
|
||||
mCurrentParcel->mAccessList.clear();
|
||||
}
|
||||
if (flags & AL_ALLOW_EXPERIENCE)
|
||||
{
|
||||
mCurrentParcel->clearExperienceKeysByType(EXPERIENCE_KEY_TYPE_ALLOWED);
|
||||
}
|
||||
if (flags & AL_BLOCK_EXPERIENCE)
|
||||
{
|
||||
mCurrentParcel->clearExperienceKeysByType(EXPERIENCE_KEY_TYPE_BLOCKED);
|
||||
}
|
||||
|
||||
// Only the headers differ
|
||||
msg->newMessageFast(_PREHASH_ParcelAccessListRequest);
|
||||
@@ -1322,10 +1309,13 @@ const std::string& LLViewerParcelMgr::getAgentParcelName() const
|
||||
|
||||
void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region)
|
||||
{
|
||||
if(!parcel) return;
|
||||
if (!parcel)
|
||||
return;
|
||||
|
||||
LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
|
||||
if (!region) return;
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
//LL_INFOS() << "found region: " << region->getName() << LL_ENDL;
|
||||
|
||||
LLSD body;
|
||||
@@ -1338,6 +1328,7 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
|
||||
parcel->packMessage(body);
|
||||
LL_INFOS() << "Sending parcel properties update via capability to: "
|
||||
<< url << LL_ENDL;
|
||||
|
||||
LLHTTPClient::post(url, body, new LLHTTPClient::ResponderIgnore);
|
||||
}
|
||||
else
|
||||
@@ -1365,10 +1356,8 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
|
||||
static U32 last_west, last_south;
|
||||
|
||||
// only request parcel info when tooltip is shown
|
||||
if (!gSavedSettings.getBOOL("ShowLandHoverTip"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return;
|
||||
|
||||
// only request parcel info if position has changed outside of the
|
||||
// last parcel grid step
|
||||
U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
|
||||
@@ -1390,6 +1379,7 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Send a rectangle around the point.
|
||||
// This means the parcel sent back is at least a rectangle around the point,
|
||||
// which is more efficient for public land. Fewer requests are sent. JC
|
||||
@@ -1437,11 +1427,7 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
|
||||
return;
|
||||
}
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
//S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge;
|
||||
//S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
|
||||
S32 expected_size = 1024;
|
||||
// </FS:CR> Aurora Sim
|
||||
if (packed_overlay_size != expected_size)
|
||||
{
|
||||
LL_WARNS() << "Got parcel overlay size " << packed_overlay_size
|
||||
@@ -1504,13 +1490,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
||||
S32 other_clean_time = 0;
|
||||
|
||||
LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance();
|
||||
// <FS:CR> Aurora Sim
|
||||
LLViewerRegion* msg_region = LLWorld::getInstance()->getRegion(msg->getSender());
|
||||
if(msg_region)
|
||||
parcel_mgr.mParcelsPerEdge = S32(msg_region->getWidth() / PARCEL_GRID_STEP_METERS);
|
||||
else
|
||||
parcel_mgr.mParcelsPerEdge = S32(gAgent.getRegion()->getWidth() / PARCEL_GRID_STEP_METERS);
|
||||
// </FS:CR> Aurora Sim
|
||||
|
||||
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
|
||||
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
|
||||
@@ -1624,6 +1608,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
||||
|
||||
if (parcel == parcel_mgr.mAgentParcel)
|
||||
{
|
||||
// new agent parcel
|
||||
S32 bitmap_size = parcel_mgr.mParcelsPerEdge
|
||||
* parcel_mgr.mParcelsPerEdge
|
||||
/ 8;
|
||||
@@ -1636,6 +1621,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
||||
// Let interesting parties know about agent parcel change.
|
||||
LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance();
|
||||
|
||||
// Notify anything that wants to know when the agent changes parcels
|
||||
instance->mAgentParcelChangedSignal();
|
||||
|
||||
if (instance->mTeleportInProgress)
|
||||
@@ -1714,7 +1700,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
||||
}
|
||||
|
||||
// Request access list information for this land
|
||||
parcel_mgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN);
|
||||
parcel_mgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_ALLOW_EXPERIENCE | AL_BLOCK_EXPERIENCE);
|
||||
|
||||
// Request dwell for this land, if it's not public land.
|
||||
parcel_mgr.mSelectedDwell = DWELL_NAN;
|
||||
@@ -1827,12 +1813,14 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
||||
{
|
||||
LL_INFOS() << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL;
|
||||
// clears the URL
|
||||
// null value causes fade out
|
||||
gAudiop->startInternetStream(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
else if (!gAudiop->getInternetStreamURL().empty())
|
||||
{
|
||||
LL_INFOS() << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL;
|
||||
// null value causes fade out
|
||||
gAudiop->startInternetStream(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
@@ -1857,7 +1845,7 @@ void optionally_start_music(LLParcel* parcel)
|
||||
// changed as part of SL-4878
|
||||
if (gOverlayBar && gOverlayBar->musicPlaying())
|
||||
{
|
||||
LLPanelNearByMedia* nearby_media_panel = LLFloaterNearbyMedia::instanceExists() ? LLFloaterNearbyMedia::getInstance()->getMediaPanel() : NULL;
|
||||
LLPanelNearByMedia* nearby_media_panel = LLFloaterNearbyMedia::instanceExists() ? LLFloaterNearbyMedia::getInstance()->getMediaPanel() : nullptr;
|
||||
if ((nearby_media_panel &&
|
||||
nearby_media_panel->getParcelAudioAutoStart()) ||
|
||||
// or they have expressed no opinion in the UI, but have autoplay on...
|
||||
@@ -1865,6 +1853,7 @@ void optionally_start_music(LLParcel* parcel)
|
||||
/*gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&*/
|
||||
gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
|
||||
{
|
||||
LL_INFOS() << "Starting parcel music " << parcel->getMusicURL() << LL_ENDL;
|
||||
LLViewerParcelMedia::playStreamingMusic(parcel);
|
||||
return;
|
||||
}
|
||||
@@ -1891,7 +1880,7 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void
|
||||
|
||||
if (parcel_id != parcel->getLocalID())
|
||||
{
|
||||
LL_WARNS() << "processParcelAccessListReply for parcel " << parcel_id
|
||||
LL_WARNS_ONCE("") << "processParcelAccessListReply for parcel " << parcel_id
|
||||
<< " which isn't the selected parcel " << parcel->getLocalID()<< LL_ENDL;
|
||||
return;
|
||||
}
|
||||
@@ -1904,6 +1893,14 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void
|
||||
{
|
||||
parcel->unpackAccessEntries(msg, &(parcel->mBanList) );
|
||||
}
|
||||
else if (message_flags & AL_ALLOW_EXPERIENCE)
|
||||
{
|
||||
parcel->unpackExperienceEntries(msg, EXPERIENCE_KEY_TYPE_ALLOWED);
|
||||
}
|
||||
else if (message_flags & AL_BLOCK_EXPERIENCE)
|
||||
{
|
||||
parcel->unpackExperienceEntries(msg, EXPERIENCE_KEY_TYPE_BLOCKED);
|
||||
}
|
||||
/*else if (message_flags & AL_RENTER)
|
||||
{
|
||||
parcel->unpackAccessEntries(msg, &(parcel->mRenterList) );
|
||||
@@ -1938,10 +1935,6 @@ void LLViewerParcelMgr::processParcelDwellReply(LLMessageSystem* msg, void**)
|
||||
|
||||
void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
|
||||
{
|
||||
|
||||
LLUUID transactionUUID;
|
||||
transactionUUID.generate();
|
||||
|
||||
if (!mSelected)
|
||||
{
|
||||
return;
|
||||
@@ -1950,125 +1943,95 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
|
||||
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
|
||||
if (!region) return;
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
LLParcel* parcel = mCurrentParcel;
|
||||
if (!parcel) return;
|
||||
|
||||
if (which & AL_ACCESS)
|
||||
{
|
||||
S32 count = parcel->mAccessList.size();
|
||||
S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
|
||||
S32 sequence_id = 1;
|
||||
BOOL start_message = TRUE;
|
||||
BOOL initial = TRUE;
|
||||
|
||||
access_map_const_iterator cit = parcel->mAccessList.begin();
|
||||
access_map_const_iterator end = parcel->mAccessList.end();
|
||||
while ( (cit != end) || initial )
|
||||
{
|
||||
if (start_message)
|
||||
{
|
||||
msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addU32Fast(_PREHASH_Flags, AL_ACCESS);
|
||||
msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
|
||||
msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
|
||||
msg->addS32Fast(_PREHASH_Sections, num_sections);
|
||||
start_message = FALSE;
|
||||
|
||||
if (initial && (cit == end))
|
||||
{
|
||||
// pack an empty block if there will be no data
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
|
||||
msg->addS32Fast(_PREHASH_Time, 0 );
|
||||
msg->addU32Fast(_PREHASH_Flags, 0 );
|
||||
}
|
||||
|
||||
initial = FALSE;
|
||||
sequence_id++;
|
||||
|
||||
}
|
||||
|
||||
while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES))
|
||||
{
|
||||
|
||||
const LLAccessEntry& entry = (*cit).second;
|
||||
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, entry.mID );
|
||||
msg->addS32Fast(_PREHASH_Time, entry.mTime );
|
||||
msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
|
||||
++cit;
|
||||
}
|
||||
|
||||
start_message = TRUE;
|
||||
msg->sendReliable( region->getHost() );
|
||||
}
|
||||
{
|
||||
sendParcelAccessListUpdate(AL_ACCESS, parcel->mAccessList, region, parcel->getLocalID());
|
||||
}
|
||||
|
||||
if (which & AL_BAN)
|
||||
{
|
||||
S32 count = parcel->mBanList.size();
|
||||
S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
|
||||
S32 sequence_id = 1;
|
||||
BOOL start_message = TRUE;
|
||||
BOOL initial = TRUE;
|
||||
{
|
||||
sendParcelAccessListUpdate(AL_BAN, parcel->mBanList, region, parcel->getLocalID());
|
||||
}
|
||||
|
||||
access_map_const_iterator cit = parcel->mBanList.begin();
|
||||
access_map_const_iterator end = parcel->mBanList.end();
|
||||
while ( (cit != end) || initial )
|
||||
{
|
||||
if (start_message)
|
||||
{
|
||||
msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addU32Fast(_PREHASH_Flags, AL_BAN);
|
||||
msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
|
||||
msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
|
||||
msg->addS32Fast(_PREHASH_Sections, num_sections);
|
||||
start_message = FALSE;
|
||||
if (which & AL_ALLOW_EXPERIENCE)
|
||||
{
|
||||
sendParcelAccessListUpdate(AL_ALLOW_EXPERIENCE, parcel->getExperienceKeysByType(EXPERIENCE_KEY_TYPE_ALLOWED), region, parcel->getLocalID());
|
||||
}
|
||||
|
||||
if (initial && (cit == end))
|
||||
{
|
||||
// pack an empty block if there will be no data
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
|
||||
msg->addS32Fast(_PREHASH_Time, 0 );
|
||||
msg->addU32Fast(_PREHASH_Flags, 0 );
|
||||
}
|
||||
|
||||
initial = FALSE;
|
||||
sequence_id++;
|
||||
|
||||
}
|
||||
|
||||
while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES))
|
||||
{
|
||||
const LLAccessEntry& entry = (*cit).second;
|
||||
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, entry.mID );
|
||||
msg->addS32Fast(_PREHASH_Time, entry.mTime );
|
||||
msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
|
||||
++cit;
|
||||
}
|
||||
|
||||
start_message = TRUE;
|
||||
msg->sendReliable( region->getHost() );
|
||||
}
|
||||
if (which & AL_BLOCK_EXPERIENCE)
|
||||
{
|
||||
sendParcelAccessListUpdate(AL_BLOCK_EXPERIENCE, parcel->getExperienceKeysByType(EXPERIENCE_KEY_TYPE_BLOCKED), region, parcel->getLocalID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 flags, const LLAccessEntry::map& entries, LLViewerRegion* region, S32 parcel_local_id)
|
||||
{
|
||||
S32 count = entries.size();
|
||||
S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
|
||||
S32 sequence_id = 1;
|
||||
BOOL start_message = TRUE;
|
||||
BOOL initial = TRUE;
|
||||
|
||||
|
||||
LLUUID transactionUUID;
|
||||
transactionUUID.generate();
|
||||
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
LLAccessEntry::map::const_iterator cit = entries.begin();
|
||||
LLAccessEntry::map::const_iterator end = entries.end();
|
||||
while ( (cit != end) || initial )
|
||||
{
|
||||
if (start_message)
|
||||
{
|
||||
msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addU32Fast(_PREHASH_Flags, flags);
|
||||
msg->addS32(_PREHASH_LocalID, parcel_local_id);
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
|
||||
msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
|
||||
msg->addS32Fast(_PREHASH_Sections, num_sections);
|
||||
start_message = FALSE;
|
||||
|
||||
if (initial && (cit == end))
|
||||
{
|
||||
// pack an empty block if there will be no data
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
|
||||
msg->addS32Fast(_PREHASH_Time, 0 );
|
||||
msg->addU32Fast(_PREHASH_Flags, 0 );
|
||||
}
|
||||
|
||||
initial = FALSE;
|
||||
sequence_id++;
|
||||
|
||||
}
|
||||
|
||||
while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES))
|
||||
{
|
||||
|
||||
const LLAccessEntry& entry = (*cit).second;
|
||||
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, entry.mID );
|
||||
msg->addS32Fast(_PREHASH_Time, entry.mTime );
|
||||
msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
|
||||
++cit;
|
||||
}
|
||||
|
||||
start_message = TRUE;
|
||||
msg->sendReliable( region->getHost() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLViewerParcelMgr::deedLandToGroup()
|
||||
{
|
||||
std::string group_name;
|
||||
@@ -2597,11 +2560,9 @@ void LLViewerParcelMgr::onTeleportFailed()
|
||||
mTeleportFailedSignal();
|
||||
}
|
||||
|
||||
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0)
|
||||
boost::signals2::connection LLViewerParcelMgr::setCollisionUpdateCallback(const collision_update_signal_t::slot_type & cb)
|
||||
{
|
||||
if (!mCollisionUpdateSignal)
|
||||
mCollisionUpdateSignal = new collision_update_signal_t();
|
||||
return mCollisionUpdateSignal->connect(cb);
|
||||
}
|
||||
// [/SL:KB]
|
||||
|
||||
@@ -33,12 +33,6 @@
|
||||
#include "llparcelselection.h"
|
||||
#include "llui.h"
|
||||
|
||||
#ifndef BOOST_FUNCTION_HPP_INCLUDED
|
||||
#include <boost/function.hpp>
|
||||
#define BOOST_FUNCTION_HPP_INCLUDED
|
||||
#endif
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
class LLUUID;
|
||||
class LLMessageSystem;
|
||||
class LLParcel;
|
||||
@@ -78,26 +72,24 @@ public:
|
||||
|
||||
class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
|
||||
{
|
||||
|
||||
public:
|
||||
typedef boost::function<void (const LLVector3d&)> teleport_finished_callback_t;
|
||||
typedef boost::signals2::signal<void (const LLVector3d&)> teleport_finished_signal_t;
|
||||
typedef boost::function<void()> parcel_changed_callback_t;
|
||||
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
|
||||
|
||||
friend class LLSingleton<LLViewerParcelMgr>;
|
||||
LLViewerParcelMgr();
|
||||
~LLViewerParcelMgr();
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
public:
|
||||
typedef std::function<void (const LLVector3d&)> teleport_finished_callback_t;
|
||||
typedef boost::signals2::signal<void (const LLVector3d&)> teleport_finished_signal_t;
|
||||
typedef std::function<void()> parcel_changed_callback_t;
|
||||
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
|
||||
|
||||
void init(F32 region_size);
|
||||
// </FS:CR> Aurora Sim
|
||||
static void cleanupGlobals();
|
||||
|
||||
BOOL selectionEmpty() const;
|
||||
F32 getSelectionWidth() const { return F32(mEastNorth.mdV[VX] - mWestSouth.mdV[VX]); }
|
||||
F32 getSelectionHeight() const { return F32(mEastNorth.mdV[VY] - mWestSouth.mdV[VY]); }
|
||||
BOOL getSelection(LLVector3d &min, LLVector3d &max) { min = mWestSouth; max = mEastNorth; return !selectionEmpty();}
|
||||
LLViewerRegion* getSelectionRegion();
|
||||
LLViewerRegion* getSelectionRegion() const;
|
||||
F32 getDwelling() const { return mSelectedDwell;}
|
||||
|
||||
void getDisplayInfo(S32* area, S32* claim, S32* rent, BOOL* for_sale, F32* dwell);
|
||||
@@ -168,14 +160,13 @@ public:
|
||||
LLParcel* getHoverParcel() const;
|
||||
|
||||
LLParcel* getCollisionParcel() const;
|
||||
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0)
|
||||
|
||||
const U8* getCollisionBitmap() const { return mCollisionBitmap; }
|
||||
size_t getCollisionBitmapSize() const { return mParcelsPerEdge * mParcelsPerEdge / 8; }
|
||||
U64 getCollisionRegionHandle() const { return mCollisionRegionHandle; }
|
||||
|
||||
typedef boost::signals2::signal<void (const LLViewerRegion*)> collision_update_signal_t;
|
||||
boost::signals2::connection setCollisionUpdateCallback(const collision_update_signal_t::slot_type & cb);
|
||||
// [/SL:KB]
|
||||
|
||||
// Can this agent build on the parcel he is on?
|
||||
// Used for parcel property icons in nav bar.
|
||||
@@ -304,6 +295,8 @@ public:
|
||||
static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power);
|
||||
|
||||
private:
|
||||
static void sendParcelAccessListUpdate(U32 flags, const std::map<LLUUID, class LLAccessEntry>& entries, LLViewerRegion* region, S32 parcel_local_id);
|
||||
static void sendParcelExperienceUpdate( const U32 flags, uuid_vec_t experience_ids, LLViewerRegion* region, S32 parcel_local_id );
|
||||
static bool releaseAlertCB(const LLSD& notification, const LLSD& response);
|
||||
|
||||
// If the user is claiming land and the current selection
|
||||
@@ -368,11 +361,9 @@ private:
|
||||
// Watch for pending collisions with a parcel you can't access.
|
||||
// If it's coming, draw the parcel's boundaries.
|
||||
LLParcel* mCollisionParcel;
|
||||
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0)
|
||||
U8* mCollisionBitmap;
|
||||
U64 mCollisionRegionHandle;
|
||||
collision_update_signal_t* mCollisionUpdateSignal;
|
||||
// [/SL:KB]
|
||||
U8* mCollisionSegments;
|
||||
BOOL mRenderCollision;
|
||||
BOOL mRenderSelection;
|
||||
|
||||
@@ -1971,6 +1971,7 @@ void LLViewerRegion::unpackRegionHandshake()
|
||||
|
||||
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
||||
{
|
||||
capabilityNames.append("AbuseCategories");
|
||||
capabilityNames.append("AgentPreferences");
|
||||
capabilityNames.append("AgentState");
|
||||
capabilityNames.append("AttachmentResources");
|
||||
@@ -1995,9 +1996,23 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
||||
capabilityNames.append("IncrementCOFVersion");
|
||||
capabilityNames.append("GamingData"); //Used by certain grids.
|
||||
AISAPI::getCapNames(capabilityNames);
|
||||
|
||||
capabilityNames.append("GetDisplayNames");
|
||||
capabilityNames.append("GetExperiences");
|
||||
capabilityNames.append("AgentExperiences");
|
||||
capabilityNames.append("FindExperienceByName");
|
||||
capabilityNames.append("GetExperienceInfo");
|
||||
capabilityNames.append("GetAdminExperiences");
|
||||
capabilityNames.append("GetCreatorExperiences");
|
||||
capabilityNames.append("ExperiencePreferences");
|
||||
capabilityNames.append("GroupExperiences");
|
||||
capabilityNames.append("UpdateExperience");
|
||||
capabilityNames.append("IsExperienceAdmin");
|
||||
capabilityNames.append("IsExperienceContributor");
|
||||
capabilityNames.append("RegionExperiences");
|
||||
capabilityNames.append("GetMesh");
|
||||
capabilityNames.append("GetMesh2"); // Used on SecondLife(tm) sim versions 280647 and higher (13.09.17).
|
||||
capabilityNames.append("GetMesh2");
|
||||
capabilityNames.append("GetMetadata");
|
||||
capabilityNames.append("GetObjectCost");
|
||||
capabilityNames.append("GetObjectPhysicsData");
|
||||
capabilityNames.append("GetTexture");
|
||||
|
||||
@@ -146,6 +146,9 @@ const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session
|
||||
const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk
|
||||
const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session
|
||||
|
||||
const U64 GP_EXPERIENCE_ADMIN = 0x1LL << 49; // has admin rights to any experiences owned by this group
|
||||
const U64 GP_EXPERIENCE_CREATOR = 0x1LL << 50; // can sign scripts for experiences owned by this group
|
||||
|
||||
// Group Banning
|
||||
const U64 GP_GROUP_BAN_ACCESS = 0x1LL << 51; // Allows access to ban / un-ban agents from a group.
|
||||
|
||||
|
||||
BIN
indra/newview/skins/default/textures/Blank.png
Normal file
BIN
indra/newview/skins/default/textures/Blank.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 B |
Binary file not shown.
|
After Width: | Height: | Size: 22 B |
BIN
indra/newview/skins/default/textures/icn_toolbar_experiences.tga
Normal file
BIN
indra/newview/skins/default/textures/icn_toolbar_experiences.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 B |
@@ -299,6 +299,8 @@ with the same filename but different name
|
||||
<texture name="icon_event.tga"/>
|
||||
<texture name="icon_event_adult.tga"/>
|
||||
<texture name="icon_event_mature.tga"/>
|
||||
<texture name="icon_for_sale.tga"/>
|
||||
<texture name="Generic_Experience" file_name="Blank.png" preload="false" />
|
||||
<texture name="icon_groupnotice.tga"/>
|
||||
<texture name="icon_groupnoticeinventory.tga"/>
|
||||
<texture name="icon_lock.tga"/>
|
||||
@@ -373,6 +375,8 @@ with the same filename but different name
|
||||
<texture name="media_btn_scrollright.png"/>
|
||||
<texture name="media_btn_scrollup.png"/>
|
||||
<texture name="media_btn_stoploading.png"/>
|
||||
<texture name="map_event_adult.tga"/>
|
||||
|
||||
<texture name="media_icon.tga" file_name="icn_label_media.tga" />
|
||||
<texture name="media_panel_bg.png" preload="true" scale.left="9" scale.top="9" scale.right="9" scale.bottom="9" />
|
||||
<texture name="media_panel_divider.png"/>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="floater_report_abuse" title="Missbrauch melden">
|
||||
<string name="Screenshot">Foto</string>
|
||||
|
||||
<string name="Ridiculous1">Belästigung > Nutzer leckt wiederholt Finger und berührt mich</string>
|
||||
<string name="Ridiculous2">Land > Anmaßung > Nutzer will nicht auf seiner Seite des Fahrzeug bleiben</string>
|
||||
<string name="Ridiculous3">Freud > Nutzer bekundet Interesse an Ihrer Mutter</string>
|
||||
<check_box label="Screenshot einschließen" name="screen_check"/>
|
||||
<text name="reporter_title">Melder:</text>
|
||||
<text name="reporter_field">Loremipsum Dolorsitamut</text>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
title="About [SHORT_APP_NAME]" width="470">
|
||||
<tab_container follows="all" bottom="1" border="false" left="10" height="414" width="450" name="about_tab" tab_position="top">
|
||||
<panel border="false" height="386" label="Info" help_topic="about_support_tab" name="support_panel">
|
||||
<text_editor parse_urls="true" follows="top|left" font="SansSerif" top="-1" bg_readonly_color="transparent" left="3" max_length="65536" name="support_editor" bottom="28" width="443" word_wrap="true"/>
|
||||
<text_editor allow_html="true" follows="top|left" font="SansSerif" top="-1" bg_readonly_color="transparent" left="3" max_length="65536" name="support_editor" bottom="28" width="443" word_wrap="true" enabled="false"/>
|
||||
<button follows="left|top" label="Copy to Clipboard" name="copy_btn" right="-5" bottom="0" top_pad="5" height="25" width="180"/>
|
||||
</panel>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
name="floaterland" rect_control="FloaterLandRect5" title="About Land"
|
||||
width="460">
|
||||
<tab_container bottom="-420" enabled="true" follows="left|top|right|bottom" height="400"
|
||||
left="1" mouse_opaque="false" name="landtab" tab_position="top" width="459">
|
||||
left="1" mouse_opaque="false" name="landtab" tab_position="top" tab_width="0" width="459">
|
||||
<panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom"
|
||||
height="333" label="General" left="1" mouse_opaque="true"
|
||||
name="land_general_panel" width="458">
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
positioning="cascading"
|
||||
legacy_header_height="18"
|
||||
can_resize="true"
|
||||
height="350"
|
||||
layout="topleft"
|
||||
min_height="200"
|
||||
min_width="400"
|
||||
name="experiencepicker"
|
||||
help_topic="experiencepicker"
|
||||
title="Choose Experience"
|
||||
width="350">
|
||||
</floater>
|
||||
@@ -0,0 +1,593 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
|
||||
<floater
|
||||
positioning="cascading"
|
||||
can_close="true"
|
||||
enabled="true"
|
||||
can_resize="true"
|
||||
help_topic="floater_experienceprofile"
|
||||
title="Experience Profile"
|
||||
save_rect="true"
|
||||
rect_control="FloaterExperienceProfileRect"
|
||||
min_width="345"
|
||||
min_height="325"
|
||||
width="358"
|
||||
height="650">
|
||||
<floater.string
|
||||
name="empty_slurl">
|
||||
(none)
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="maturity_icon_general">
|
||||
map_event.tga
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="maturity_icon_moderate">
|
||||
map_event_mature.tga
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="maturity_icon_adult">
|
||||
map_event_adult.tga
|
||||
</floater.string>
|
||||
<name_box
|
||||
follows="top|left|right"
|
||||
font="SansSerifHugeBold"
|
||||
height="26"
|
||||
name="experience_title"
|
||||
id_type="3"
|
||||
bottom="-42"
|
||||
value=""
|
||||
use_ellipses="true"
|
||||
click_for_profile="false"
|
||||
mouse_opaque="false"
|
||||
left="10"
|
||||
right="-3"/>
|
||||
<tab_container
|
||||
hide_tabs="true"
|
||||
follows="all"
|
||||
height="610"
|
||||
left="5"
|
||||
min_height="250"
|
||||
bottom_delta="-605"
|
||||
width="348"
|
||||
name="tab_container">
|
||||
<panel
|
||||
background_visible="true"
|
||||
follows="all"
|
||||
height="540"
|
||||
left="0"
|
||||
min_height="250"
|
||||
bottom="-540"
|
||||
width="348"
|
||||
name="panel_experience_info">
|
||||
<scroll_container
|
||||
follows="all"
|
||||
height="530"
|
||||
left="0"
|
||||
name="xp_scroll"
|
||||
opaque="true"
|
||||
bottom="0"
|
||||
width="348">
|
||||
<panel
|
||||
follows="top|left|right"
|
||||
height="550"
|
||||
left="0"
|
||||
name="scrolling_panel"
|
||||
bottom="-550"
|
||||
width="315"
|
||||
min_width="315">
|
||||
<layout_stack
|
||||
follows="all"
|
||||
height="550"
|
||||
left="0"
|
||||
animate="false"
|
||||
bottom="-550"
|
||||
orientation="vertical"
|
||||
width="315">
|
||||
<layout_panel
|
||||
follows="all"
|
||||
height="19"
|
||||
left="0"
|
||||
bottom="-19"
|
||||
auto_resize="false"
|
||||
visible="false"
|
||||
width="315"
|
||||
name="top panel">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
height="19"
|
||||
bottom_delta="-19"
|
||||
left="10"
|
||||
right="-123"
|
||||
visible="false"
|
||||
name="grid_wide"/>
|
||||
<button
|
||||
follows="top|right"
|
||||
height="23"
|
||||
label="Edit"
|
||||
name="edit_btn"
|
||||
width="100"
|
||||
visible="false"
|
||||
bottom_delta="-46"
|
||||
right="-14"/>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="all"
|
||||
height="197"
|
||||
left="0"
|
||||
bottom="-197"
|
||||
auto_resize="false"
|
||||
visible="false"
|
||||
width="315"
|
||||
name="image_panel">
|
||||
<texture_picker
|
||||
enabled="false"
|
||||
fallback_image="default_land_picture.j2c"
|
||||
follows="left|top"
|
||||
height="197"
|
||||
left="10"
|
||||
name="logo"
|
||||
bottom="-207"
|
||||
width="290" />
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows=""
|
||||
height="50"
|
||||
left="0"
|
||||
bottom="-50"
|
||||
auto_resize="false"
|
||||
width="315"
|
||||
visible="false"
|
||||
name="description panel">
|
||||
<text_editor
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
enabled="false"
|
||||
height="50"
|
||||
left="10"
|
||||
name="experience_description"
|
||||
bottom="-50"
|
||||
value=""
|
||||
width="305"
|
||||
max_length="2048"/>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows=""
|
||||
height="18"
|
||||
left="0"
|
||||
bottom="-18"
|
||||
auto_resize="false"
|
||||
width="315"
|
||||
visible="true"
|
||||
name="maturity panel">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
left="10"
|
||||
name="ContentRating"
|
||||
width="75">
|
||||
Rating:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
left_delta="77"
|
||||
valign="center"
|
||||
name="ContentRatingText"
|
||||
bottom_delta="3"
|
||||
width="188">
|
||||
</text>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="all"
|
||||
height="46"
|
||||
left="0"
|
||||
bottom="-51"
|
||||
width="313"
|
||||
visible="false"
|
||||
auto_resize="false"
|
||||
name="location panel">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
left="10"
|
||||
name="Location"
|
||||
width="290">
|
||||
Location:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
left="10"
|
||||
valign="center"
|
||||
use_ellipses="true"
|
||||
name="LocationTextText"
|
||||
width="288">
|
||||
</text>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="all"
|
||||
height="53"
|
||||
left="0"
|
||||
bottom="-58"
|
||||
width="313"
|
||||
visible="false"
|
||||
auto_resize="false"
|
||||
name="marketplace panel">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
left="10"
|
||||
width="290">
|
||||
Marketplace store:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
left="10"
|
||||
valign="center"
|
||||
use_ellipses="true"
|
||||
name="marketplace"
|
||||
width="288">
|
||||
</text>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
left="0"
|
||||
bottom="-18"
|
||||
auto_resize="false"
|
||||
width="315">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="18"
|
||||
left="10"
|
||||
name="Owner"
|
||||
width="75">
|
||||
Owner:
|
||||
</text>
|
||||
<name_box
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
left_delta="77"
|
||||
valign="center"
|
||||
name="OwnerText"
|
||||
use_ellipses="true"
|
||||
bottom_delta="0"
|
||||
width="188">
|
||||
</name_box>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="all"
|
||||
height="18"
|
||||
left="0"
|
||||
bottom="-23"
|
||||
width="313"
|
||||
visible="false"
|
||||
auto_resize="false"
|
||||
name="group_panel">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
left="10"
|
||||
name="Group"
|
||||
width="75">
|
||||
Group:
|
||||
</text>
|
||||
<name_box
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
left_delta="77"
|
||||
valign="center"
|
||||
name="GroupText"
|
||||
id_type="1"
|
||||
use_ellipses="true"
|
||||
bottom_delta="0"
|
||||
width="188">
|
||||
</name_box>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="all"
|
||||
height="75"
|
||||
left="0"
|
||||
bottom="-80"
|
||||
width="313"
|
||||
auto_resize="false"
|
||||
visible="true"
|
||||
name="perm panel">
|
||||
<button
|
||||
follows="bottom|left"
|
||||
height="23"
|
||||
label="Allow"
|
||||
name="allow_btn"
|
||||
width="94"
|
||||
bottom_delta="-26"
|
||||
left="7"
|
||||
enabled="false"/>
|
||||
<button
|
||||
follows="bottom|left"
|
||||
height="23"
|
||||
label="Forget"
|
||||
name="forget_btn"
|
||||
width="94"
|
||||
bottom_delta="0"
|
||||
left_delta="97"
|
||||
enabled="false"/>
|
||||
<button
|
||||
follows="bottom|left"
|
||||
height="23"
|
||||
label="Block"
|
||||
name="block_btn"
|
||||
width="94"
|
||||
bottom_delta="0"
|
||||
left_delta="97"
|
||||
enabled="false"/>
|
||||
<text
|
||||
type="string"
|
||||
halign="center"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
left="10"
|
||||
name="privileged"
|
||||
visible="false"
|
||||
width="288">
|
||||
This experience is enabled for all residents.
|
||||
</text>
|
||||
<button
|
||||
follows="bottom|left"
|
||||
height="23"
|
||||
label="Report Abuse"
|
||||
name="report_btn"
|
||||
width="94"
|
||||
bottom_delta="-5"
|
||||
left="104"
|
||||
enabled="true"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
</panel>
|
||||
</scroll_container>
|
||||
</panel>
|
||||
<panel
|
||||
background_visible="true"
|
||||
follows="all"
|
||||
height="540"
|
||||
left="0"
|
||||
top="0"
|
||||
width="348"
|
||||
name="edit_panel_experience_info">
|
||||
<scroll_container
|
||||
follows="all"
|
||||
height="520"
|
||||
left="9"
|
||||
name="edit_xp_scroll"
|
||||
opaque="true"
|
||||
bottom_delta="-530"
|
||||
width="330">
|
||||
<panel
|
||||
follows="top|left|right"
|
||||
height="590"
|
||||
left="0"
|
||||
name="edit_scrolling_panel"
|
||||
top="0"
|
||||
width="310">
|
||||
<texture_picker
|
||||
enabled="true"
|
||||
fallback_image="default_land_picture.j2c"
|
||||
follows="left|top"
|
||||
height="197"
|
||||
left="10"
|
||||
name="edit_logo"
|
||||
top="10"
|
||||
width="290" />
|
||||
<text
|
||||
follows="left|top|right"
|
||||
height="14"
|
||||
left="10"
|
||||
name="edit_experience_title_label"
|
||||
use_ellipses="true"
|
||||
value="Name:"
|
||||
right="-10"/>
|
||||
<line_editor
|
||||
follows="left|top|right"
|
||||
height="19"
|
||||
left="10"
|
||||
name="edit_experience_title"
|
||||
max_length_bytes="63"
|
||||
right="-10"/>
|
||||
<text
|
||||
follows="left|top|right"
|
||||
height="14"
|
||||
left="10"
|
||||
bottom_delta="-24"
|
||||
name="edit_experience_desc_label"
|
||||
use_ellipses="true"
|
||||
value="Description:"
|
||||
right="-10"/>
|
||||
<text_editor
|
||||
follows="left|top|right"
|
||||
height="57"
|
||||
left="11"
|
||||
name="edit_experience_description"
|
||||
max_length="2048"
|
||||
right="-11"
|
||||
word_wrap="true"/>
|
||||
<button
|
||||
bottom_delta="-33"
|
||||
left="10"
|
||||
width="125"
|
||||
height="23"
|
||||
name="Group_btn"
|
||||
label="Group"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="14"
|
||||
left_delta="135"
|
||||
bottom_delta="-32"
|
||||
use_ellipses="true"
|
||||
name="edit_GroupText"
|
||||
right="-10" />
|
||||
<text
|
||||
bottom_delta="-26"
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
left="10"
|
||||
name="edit_ContentRating"
|
||||
right="-10">
|
||||
Rating:
|
||||
</text>
|
||||
<combo_box
|
||||
follows="right|top"
|
||||
height="20"
|
||||
label="Moderate"
|
||||
right="-10"
|
||||
bottom_delta="-1"
|
||||
tool_tip="Increasing the maturity rating on an experience will reset permission for all residents which have allowed the experience."
|
||||
name="edit_ContentRatingText"
|
||||
width="105">
|
||||
<combo_item
|
||||
label="Adult"
|
||||
name="Adult"
|
||||
value="42"/>
|
||||
<combo_item
|
||||
label="Moderate"
|
||||
name="Mature"
|
||||
value="21"/>
|
||||
<combo_item
|
||||
label="General"
|
||||
name="PG"
|
||||
value="13"/>
|
||||
</combo_box>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
left="10"
|
||||
bottom_delta="-24"
|
||||
name="edit_Location"
|
||||
right="90">
|
||||
Location:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="14"
|
||||
left_delta="85"
|
||||
bottom_delta="-28"
|
||||
use_ellipses="true"
|
||||
name="edit_LocationTextText"
|
||||
right="-10" />
|
||||
<button
|
||||
left="10"
|
||||
width="125"
|
||||
height="23"
|
||||
name="location_btn"
|
||||
label="Set to Current"
|
||||
/>
|
||||
<button
|
||||
bottom_delta="0"
|
||||
height="23"
|
||||
follows="top|right"
|
||||
right="-10"
|
||||
width="125"
|
||||
name="clear_btn"
|
||||
label="Clear Location"/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="14"
|
||||
bottom_delta="-33"
|
||||
left="10"
|
||||
right="-10">
|
||||
Marketplace store:
|
||||
</text>
|
||||
<line_editor
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="19"
|
||||
left="10"
|
||||
max_length_bytes="255"
|
||||
valign="center"
|
||||
name="edit_marketplace"
|
||||
right="-10"/>
|
||||
<check_box width="140"
|
||||
height="21"
|
||||
left="10"
|
||||
follows="top|left"
|
||||
tool_tip=""
|
||||
label="Enable Experience"
|
||||
name="edit_enable_btn"/>
|
||||
<check_box width="125"
|
||||
height="21"
|
||||
bottom_delta="-42"
|
||||
right="-10"
|
||||
visible="false"
|
||||
follows="top|left|right"
|
||||
label="Hide In Search"
|
||||
name="edit_private_btn"/>
|
||||
<text
|
||||
follows="left|top|right"
|
||||
height="25"
|
||||
left="10"
|
||||
bottom_delta="35"
|
||||
name="changes"
|
||||
use_ellipses="true"
|
||||
word_wrap="true"
|
||||
value="Experience changes may take several minutes to be seen on all regions."
|
||||
right="-10"/>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
label="Back"
|
||||
name="cancel_btn"
|
||||
width="125"
|
||||
botttom_delta="38"
|
||||
left="10"
|
||||
visible="true"/>
|
||||
<button
|
||||
follows="top|right"
|
||||
height="23"
|
||||
label="Save"
|
||||
name="save_btn"
|
||||
bottom_delta="-46"
|
||||
width="125"
|
||||
right="-10"
|
||||
visible="true"/>
|
||||
</panel>
|
||||
</scroll_container>
|
||||
</panel>
|
||||
</tab_container>
|
||||
</floater>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
|
||||
<floater
|
||||
can_close="true"
|
||||
can_resize="true"
|
||||
height="400"
|
||||
width="500"
|
||||
min_height="300"
|
||||
min_width="500"
|
||||
help_topic="floater_experiences"
|
||||
name="floater_experiences"
|
||||
save_rect="true"
|
||||
rect_control="FloaterExperiencesRect"
|
||||
single_instance="true"
|
||||
reuse_instance="false"
|
||||
bg_opaque_color="0 0.5 0 0.3"
|
||||
title="Experiences">
|
||||
<tab_container
|
||||
bottom="-417"
|
||||
left="3"
|
||||
right="-3"
|
||||
follows="all"
|
||||
height="394"
|
||||
name="xp_tabs">
|
||||
</tab_container>
|
||||
|
||||
</floater>
|
||||
@@ -73,6 +73,32 @@
|
||||
mouse_opaque="true" name="LabelAcquiredDate" v_pad="0" width="252">
|
||||
Wed May 24 12:50:46 2006
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="LabelItemExperienceTitle"
|
||||
bottom_delta="-10"
|
||||
width="78"
|
||||
visible="true">
|
||||
Experience:
|
||||
</text>
|
||||
<name_box
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="78"
|
||||
name="LabelItemExperience"
|
||||
bottom_delta="0"
|
||||
width="210"
|
||||
id_type="3"
|
||||
visible="true"
|
||||
/>
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="-10" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
|
||||
@@ -194,6 +220,7 @@
|
||||
enabled="true" follows="left|top|right" font="SansSerifSmall" height="16"
|
||||
is_unicode="false" left_delta="56" max_length="25" mouse_opaque="true"
|
||||
name="Edit Cost" width="242" />
|
||||
<floater.string name="loading_experience">(loading)</floater.string>
|
||||
<string name="unknown">
|
||||
(unknown)
|
||||
</string>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater bottom="-668" can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||
can_resize="true" enabled="true" follows="left|top" height="550" left="306"
|
||||
can_resize="true" enabled="true" follows="left|top" height="572" left="306"
|
||||
min_height="271" min_width="290" mouse_opaque="true" name="script ed float"
|
||||
rect_control="FloaterOpenObjectRect" title="Script: New Script" width="500" border_drop_shadow_visible="false" border_visible="false" bevel_style="none" border_style="line" border_thickness="0">
|
||||
<button bottom="-538" enabled="true" follows="right|bottom" font="SansSerif"
|
||||
@@ -12,6 +12,32 @@
|
||||
<check_box bottom="-540" enabled="false" follows="left|bottom" font="SansSerif"
|
||||
height="18" hidden="false" initial_value="true" label="Mono" left="82"
|
||||
mouse_opaque="true" name="mono" radio_style="false" width="100" />
|
||||
<check_box width="130"
|
||||
height="21"
|
||||
enabled="false"
|
||||
left="12"
|
||||
bottom_delta="-21"
|
||||
follows="bottom|left"
|
||||
label="Use Experience"
|
||||
name="enable_xp" />
|
||||
<combo_box
|
||||
label=""
|
||||
bottom_delta="0"
|
||||
height="20"
|
||||
left="149"
|
||||
right="466"
|
||||
follows="left|bottom|right"
|
||||
visible="true"
|
||||
name="Experiences..." />
|
||||
<button label=""
|
||||
name="view_profile"
|
||||
image_overlay="arrow_right.tga"
|
||||
height="20"
|
||||
width="20"
|
||||
right="486"
|
||||
bottom_delta="0"
|
||||
follows="right"
|
||||
visible="false"/>
|
||||
<panel bottom="-524" enabled="true" follows="left|top|right|bottom" height="506"
|
||||
left="1" name="script ed panel" width="497" border_drop_shadow_visible="false" border_visible="false" bevel_style="none" border_style="line" border_thickness="0" />
|
||||
<string name="not_allowed">
|
||||
@@ -20,4 +46,13 @@
|
||||
<string name="script_running">
|
||||
Running
|
||||
</string>
|
||||
<string name="experience_enabled">
|
||||
Uncheck to remove the current experience
|
||||
</string>
|
||||
<string name="no_experiences">
|
||||
You are not authorized for any experiences
|
||||
</string>
|
||||
<string name="add_experiences">
|
||||
Select to add an experience
|
||||
</string>
|
||||
</floater>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
help_topic="floater_region_tracker"
|
||||
single_instance="true"
|
||||
reuse_instance="true"
|
||||
layout="topleft"
|
||||
height="250"
|
||||
width="408"
|
||||
min_height="150"
|
||||
@@ -28,7 +27,6 @@
|
||||
bottom_delta="7"
|
||||
halign="center"
|
||||
height="31"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
width="31"
|
||||
mouse_opaque="true"
|
||||
@@ -40,7 +38,6 @@
|
||||
bottom_delta="0"
|
||||
halign="center"
|
||||
height="31"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
width="31"
|
||||
mouse_opaque="true"
|
||||
@@ -52,7 +49,6 @@
|
||||
bottom_delta="0"
|
||||
halign="center"
|
||||
height="31"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
width="31"
|
||||
mouse_opaque="true"
|
||||
@@ -64,7 +60,6 @@
|
||||
tool_tip="Double click an entry to open it on the world map."
|
||||
height="195"
|
||||
width="400"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
bottom_delta="-199"
|
||||
left="4"
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
<string name="Screenshot">
|
||||
Screenshot
|
||||
</string>
|
||||
<string name="Ridiculous1" value="Harassment > User keeps licking finger and touching me"/>
|
||||
<string name="Ridiculous2" value="Land > Encroachment > User won't stay on their side of the car"/>
|
||||
<string name="Ridiculous3" value="Freud > User has taken an interest in their mother"/>
|
||||
<texture_picker allow_no_texture="true" bottom="-150" default_image_name="None"
|
||||
follows="left|top" height="114" label="" left="238" mouse_opaque="true"
|
||||
name="screenshot" width="134" />
|
||||
@@ -17,12 +20,12 @@
|
||||
mouse_opaque="true" name="reporter_title" v_pad="0" width="50">
|
||||
Reporter:
|
||||
</text>
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-48" drop_shadow_visible="true" follows="left|top"
|
||||
<name_box bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-48" drop_shadow_visible="true" follows="left|top" click_for_profile="false"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="62"
|
||||
mouse_opaque="true" name="reporter_field" v_pad="0" width="150">
|
||||
Loremipsum Dolorsitamut
|
||||
</text>
|
||||
</name_box>
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-64" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left="16"
|
||||
@@ -75,12 +78,12 @@
|
||||
mouse_opaque="true" name="owner_name_label" v_pad="0" width="60">
|
||||
Owner:
|
||||
</text>
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="0" drop_shadow_visible="true" follows="left|top"
|
||||
<name_box bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="0" drop_shadow_visible="true" follows="left|top" rlv_sensitive="true"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="66"
|
||||
mouse_opaque="true" name="owner_name" v_pad="0" width="109">
|
||||
Hendrerit Vulputate
|
||||
</text>
|
||||
</name_box>
|
||||
<combo_box bottom_delta="-48" follows="left|top" height="20" left="16" mouse_opaque="true"
|
||||
name="category_combo"
|
||||
tool_tip="Category -- select the category that best describes this report"
|
||||
@@ -116,19 +119,19 @@
|
||||
<combo_box.item
|
||||
label="Fraud > L$ or USD $"
|
||||
name="Fraud__US$"
|
||||
value="50" />
|
||||
value="47" />
|
||||
<combo_box.item
|
||||
name="Ridiculous3"
|
||||
name="Ridiculous3"
|
||||
label="Freud > User has taken an interest in their mother"
|
||||
value="100" />
|
||||
value="1000" />
|
||||
<combo_box.item
|
||||
label="Harassment > Targeted behavior intended to disrupt"
|
||||
name="Harassment__Solicting_inciting_others_to_violate_ToS"
|
||||
value="55" />
|
||||
value="51" />
|
||||
<combo_box.item
|
||||
label="Harassment > User keeps licking finger and touching me"
|
||||
name="Ridiculous1"
|
||||
value="100"/>
|
||||
value="1000"/>
|
||||
<combo_box.item
|
||||
label="Indecency > Broadly offensive content or conduct"
|
||||
name="Indecency__Broadly_offensive_content_or_conduct"
|
||||
@@ -152,9 +155,9 @@
|
||||
<combo_box.item
|
||||
name="Ridiculous2"
|
||||
label="Land > Encroachment > User won't stay on their side of the car"
|
||||
value="100" />
|
||||
value="1000" />
|
||||
<combo_box.item
|
||||
label="Gaming Policy Violation"
|
||||
label="Skill Gaming Policy Violation"
|
||||
name="Wagering_gambling"
|
||||
value="67" />
|
||||
<combo_box.item
|
||||
@@ -215,9 +218,9 @@
|
||||
bottom_delta="-32" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="48" left="70"
|
||||
mouse_opaque="true" name="bug_aviso" v_pad="0" width="308">
|
||||
Please be specific about the date, location, nature of
|
||||
abuse, relevant chat/IM text, and select the object
|
||||
if possible.
|
||||
Please be as specific as possible: date, location,
|
||||
nature of abuse, relevant chat/IM text, etc.
|
||||
* Incomplete reports won't be investigated
|
||||
</text>
|
||||
<text_editor bottom_delta="-152" embedded_items="false"
|
||||
follows="left|top" font="SansSerifSmall" height="146" left="16"
|
||||
|
||||
@@ -58,15 +58,17 @@
|
||||
<check_box bottom_delta="-20" label="TP History" name="teleport_history_btn" follows="left|right" control_name="ToolbarVisibleTeleportHistory"/>
|
||||
<check_box bottom_delta="-20" label="Map" name="map_btn" follows="left|right" control_name="ToolbarVisibleWorldMap"/>
|
||||
<check_box bottom_delta="-20" label="Mini-Map" name="minimap_btn" follows="left|right" control_name="ToolbarVisibleMiniMap"/>
|
||||
<check_box bottom_delta="-20" label="Experiences" name="experiences_btn" follows="left|right" control_name="ToolbarVisibleExperiences"/>
|
||||
<check_box bottom_delta="-20" label="Experience Search" name="experience_search_btn" follows="left|right" control_name="ToolbarVisibleExperiencePicker"/>
|
||||
<!-- [RLVa:LF] -->
|
||||
<check_box bottom_delta="-20" label="RLVa Restrictions" name="rlv_restrictions_btn" follows="left|right" control_name="ToolbarVisibleRLVRestrictions"/>
|
||||
<check_box bottom_delta="-20" label="RLVa Locks" name="rlv_locks_btn" follows="left|right" control_name="ToolbarVisibleRLVLocks"/>
|
||||
<check_box bottom_delta="-20" label="RLVa Strings" name="rlv_strings_btn" follows="left|right" control_name="ToolbarVisibleRLVStrings"/>
|
||||
<!-- [/RLVa:LF] -->
|
||||
<check_box bottom_delta="-20" label="Memory Leak" name="memleak_btn" follows="left|right" control_name="ToolbarVisibleMemLeak" visibility_control="QAMode"/>
|
||||
<check_box bottom_delta="-20" label="Message Log" name="message_log_btn" follows="left|right" control_name="ToolbarVisibleMessageLog"/>
|
||||
<check_box bottom="-38" label="Message Log" name="message_log_btn" follows="left|right" control_name="ToolbarVisibleMessageLog" left_delta="160"/>
|
||||
<check_box bottom_delta="-20" label="Statistics" name="stats_btn" follows="left|right" control_name="ToolbarVisibleStatBar"/>
|
||||
<check_box bottom="-38" label="Notifications Console" name="notifications_console_btn" follows="left|right" control_name="ToolbarVisibleNotificationsConsole" left_delta="160"/>
|
||||
<check_box bottom_delta="-20" label="Notifications Console" name="notifications_console_btn" follows="left|right" control_name="ToolbarVisibleNotificationsConsole"/>
|
||||
<check_box bottom_delta="-20" label="Debug Console" name="debug_console_btn" follows="left|right" control_name="ToolbarVisibleDebugConsole"/>
|
||||
<check_box bottom_delta="-20" label="Region Console" name="region_console_btn" follows="left|right" control_name="ToolbarVisibleRegionDebugConsole"/>
|
||||
<check_box bottom_delta="-20" label="Fast Timers" name="fast_timers_btn" follows="left|right" control_name="ToolbarVisibleFastTimers"/>
|
||||
@@ -80,9 +82,9 @@
|
||||
<check_box bottom_delta="-20" label="Make Outfit" name="make_outfit_btn" follows="left|right" control_name="ToolbarVisibleOutfit"/>
|
||||
<check_box bottom_delta="-20" label="Outfits" name="outfits_btn" follows="left|right" control_name="ToolbarVisibleInventoryOutfits"/>
|
||||
<check_box bottom_delta="-20" label="Favorites" name="favs_btn" follows="left|right" control_name="ToolbarVisibleInventoryFavs"/>
|
||||
<check_box bottom_delta="-20" label="Received Items" name="received_items_btn" follows="left|right" control_name="ToolbarVisibleInventoryReceivedItems"/>
|
||||
<check_box bottom="-38" label="Received Items" name="received_items_btn" follows="left|right" control_name="ToolbarVisibleInventoryReceivedItems" left_delta="160"/>
|
||||
<check_box bottom_delta="-20" label="Marketplace Listings" name="marketplace_listings_btn" follows="left|right" control_name="ToolbarVisibleMarketplaceListings"/>
|
||||
<check_box bottom="-38" label="Marketplace" name="marketplace_btn" follows="left|right" control_name="ToolbarVisibleMarketplace" left_delta="160"/>
|
||||
<check_box bottom_delta="-20" label="Marketplace" name="marketplace_btn" follows="left|right" control_name="ToolbarVisibleMarketplace"/>
|
||||
<check_box bottom_delta="-20" label="Preferences" name="preferences_btn" follows="left|right" control_name="ToolbarVisiblePreferences"/>
|
||||
<check_box bottom_delta="-20" label="Joystick Config" name="joystick_btn" follows="left|right" control_name="ToolbarVisibleJoystick"/>
|
||||
<check_box bottom_delta="-20" label="Autoreplace" name="auto_replace_btn" follows="left|right" control_name="ToolbarVisibleAutoReplace"/>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user