svn merge -r106715:HEAD svn+ssh://svn.lindenlab.com/svn/linden/branches/q/notifications-merge-r106715 . QAR-1149 -- Final merge of notifications to trunk.
parent
95f365789f
commit
667ca55bad
|
|
@ -36,9 +36,12 @@
|
|||
|
||||
#include "apr_time.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "lltimer.h"
|
||||
|
||||
static const F64 DATE_EPOCH = 0.0;
|
||||
|
||||
static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
|
||||
|
|
@ -122,7 +125,7 @@ void LLDate::toHTTPDateStream(std::ostream& s) const
|
|||
<< " GMT";
|
||||
|
||||
// RFC 1123 date does not use microseconds
|
||||
llinfos << "Date in RFC 1123 format is " << s << llendl;
|
||||
//llinfos << "Date in RFC 1123 format is " << s << llendl;
|
||||
}
|
||||
|
||||
void LLDate::toStream(std::ostream& s) const
|
||||
|
|
@ -239,6 +242,17 @@ bool operator!=(const LLDate& first, const LLDate& second)
|
|||
return (first.secondsSinceEpoch() != second.secondsSinceEpoch());
|
||||
}
|
||||
|
||||
/* static */ LLDate LLDate::now()
|
||||
{
|
||||
// time() returns seconds, we want fractions of a second, which LLTimer provides --RN
|
||||
return LLDate(LLTimer::getTotalSeconds());
|
||||
}
|
||||
|
||||
bool LLDate::operator<(const LLDate& rhs) const
|
||||
{
|
||||
return mSecondsSinceEpoch < rhs.mSecondsSinceEpoch;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLDate& date)
|
||||
{
|
||||
date.toStream(s);
|
||||
|
|
@ -250,3 +264,4 @@ std::istream& operator>>(std::istream& s, LLDate& date)
|
|||
date.fromStream(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#define LL_LLDATE_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "stdtypes.h"
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ public:
|
|||
LLDate();
|
||||
|
||||
/**
|
||||
* @brief Construct a date equal to epoch.
|
||||
* @brief Construct a date equal the source date.
|
||||
*/
|
||||
LLDate(const LLDate& date);
|
||||
|
||||
|
|
@ -111,6 +112,32 @@ public:
|
|||
* @param seconds The number of seconds since epoch UTC.
|
||||
*/
|
||||
void secondsSinceEpoch(F64 seconds);
|
||||
|
||||
/**
|
||||
* @brief Create an LLDate object set to the current time.
|
||||
*
|
||||
* @return The number of seconds since epoch UTC.
|
||||
*/
|
||||
static LLDate now();
|
||||
|
||||
/**
|
||||
* @brief Compare dates using operator< so we can order them using STL.
|
||||
*
|
||||
* @param rhs -- the right hand side of the comparison operator
|
||||
*/
|
||||
bool operator<(const LLDate& rhs) const;
|
||||
|
||||
/**
|
||||
* @brief Remaining comparison operators in terms of operator<
|
||||
* This conforms to the expectation of STL.
|
||||
*
|
||||
* @param rhs -- the right hand side of the comparison operator
|
||||
*/
|
||||
bool operator>(const LLDate& rhs) const { return rhs < *this; }
|
||||
bool operator<=(const LLDate& rhs) const { return !(rhs < *this); }
|
||||
bool operator>=(const LLDate& rhs) const { return !(*this < rhs); }
|
||||
bool operator!=(const LLDate& rhs) const { return (*this < rhs) || (rhs < *this); }
|
||||
bool operator==(const LLDate& rhs) const { return !(*this != rhs); }
|
||||
|
||||
private:
|
||||
F64 mSecondsSinceEpoch;
|
||||
|
|
|
|||
|
|
@ -409,53 +409,58 @@ protected:
|
|||
//
|
||||
// class Foo: public LLSingleton<Foo>{};
|
||||
//
|
||||
// Foo* instance = Foo::getInstance();
|
||||
// Foo& instance = Foo::instance();
|
||||
//
|
||||
// The second way is to define a seperate class that exposes the singleton
|
||||
// interface:
|
||||
// The second way is to use the singleton class directly, without inheritance:
|
||||
//
|
||||
// class FooSingleton: public LLSingleton<Foo>{};
|
||||
// typedef LLSingleton<Foo> FooSingleton;
|
||||
//
|
||||
// Foo* instance = FooSingleton::getInstance();
|
||||
// Foo& instance = FooSingleton::instance();
|
||||
//
|
||||
// In this case, the class being managed as a singleton needs to provide an
|
||||
// initSingleton() method since the LLSingleton virtual method won't be
|
||||
// available
|
||||
//
|
||||
// As currently written, it is not thread-safe.
|
||||
#if LL_WINDOWS && _MSC_VER < 1400 // this is Visual C++ 2003 or earlier
|
||||
template <typename T>
|
||||
class LLSingleton
|
||||
{
|
||||
public:
|
||||
virtual ~LLSingleton() {}
|
||||
#ifdef LL_MSVC7
|
||||
// workaround for VC7 compiler bug
|
||||
// adapted from http://www.codeproject.com/KB/tips/VC2003MeyersSingletonBug.aspx
|
||||
// our version doesn't introduce a nested struct so that you can still declare LLSingleton<MyClass>
|
||||
// a friend and hide your constructor
|
||||
|
||||
template <typename T>
|
||||
class LLSingleton
|
||||
{
|
||||
public:
|
||||
static T* getInstance()
|
||||
static T* getInstance()
|
||||
{
|
||||
LLSingleton<T> singleton;
|
||||
return singleton.get();
|
||||
}
|
||||
private:
|
||||
T* get()
|
||||
{
|
||||
static T instance;
|
||||
return &instance;
|
||||
return singleton.vsHack();
|
||||
}
|
||||
|
||||
};
|
||||
T* vsHack()
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
class LLSingleton
|
||||
{
|
||||
public:
|
||||
static T* getInstance()
|
||||
#endif
|
||||
{
|
||||
static T instance;
|
||||
static bool needs_init = true;
|
||||
if (needs_init)
|
||||
{
|
||||
needs_init = false;
|
||||
instance.initSingleton();
|
||||
}
|
||||
return &instance;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
static T& instance()
|
||||
{
|
||||
return *getInstance();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void initSingleton() {}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ namespace
|
|||
|
||||
virtual bool has(const LLSD::String&) const;
|
||||
virtual LLSD get(const LLSD::String&) const;
|
||||
void insert(const LLSD::String& k, const LLSD& v);
|
||||
LLSD& insert(const LLSD::String& k, const LLSD& v);
|
||||
virtual void erase(const LLSD::String&);
|
||||
LLSD& ref(const LLSD::String&);
|
||||
virtual const LLSD& ref(const LLSD::String&) const;
|
||||
|
|
@ -388,9 +388,14 @@ namespace
|
|||
return (i != mData.end()) ? i->second : LLSD();
|
||||
}
|
||||
|
||||
void ImplMap::insert(const LLSD::String& k, const LLSD& v)
|
||||
LLSD& ImplMap::insert(const LLSD::String& k, const LLSD& v)
|
||||
{
|
||||
mData.insert(DataMap::value_type(k, v));
|
||||
#ifdef LL_MSVC7
|
||||
return *((LLSD*)this);
|
||||
#else
|
||||
return *dynamic_cast<LLSD*>(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImplMap::erase(const LLSD::String& k)
|
||||
|
|
@ -436,7 +441,7 @@ namespace
|
|||
virtual int size() const;
|
||||
virtual LLSD get(LLSD::Integer) const;
|
||||
void set(LLSD::Integer, const LLSD&);
|
||||
void insert(LLSD::Integer, const LLSD&);
|
||||
LLSD& insert(LLSD::Integer, const LLSD&);
|
||||
void append(const LLSD&);
|
||||
virtual void erase(LLSD::Integer);
|
||||
LLSD& ref(LLSD::Integer);
|
||||
|
|
@ -485,9 +490,15 @@ namespace
|
|||
mData[index] = v;
|
||||
}
|
||||
|
||||
void ImplArray::insert(LLSD::Integer i, const LLSD& v)
|
||||
LLSD& ImplArray::insert(LLSD::Integer i, const LLSD& v)
|
||||
{
|
||||
if (i < 0) { return; }
|
||||
if (i < 0) {
|
||||
#ifdef LL_MSVC7
|
||||
return *((LLSD*)this);
|
||||
#else
|
||||
return *dynamic_cast<LLSD*>(this);
|
||||
#endif
|
||||
}
|
||||
DataVector::size_type index = i;
|
||||
|
||||
if (index >= mData.size())
|
||||
|
|
@ -496,6 +507,11 @@ namespace
|
|||
}
|
||||
|
||||
mData.insert(mData.begin() + index, v);
|
||||
#ifdef LL_MSVC7
|
||||
return *((LLSD*)this);
|
||||
#else
|
||||
return *dynamic_cast<LLSD*>(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImplArray::append(const LLSD& v)
|
||||
|
|
@ -739,8 +755,11 @@ LLSD LLSD::emptyMap()
|
|||
bool LLSD::has(const String& k) const { return safe(impl).has(k); }
|
||||
LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
|
||||
|
||||
void LLSD::insert(const String& k, const LLSD& v)
|
||||
{ makeMap(impl).insert(k, v); }
|
||||
LLSD& LLSD::insert(const String& k, const LLSD& v)
|
||||
{
|
||||
makeMap(impl).insert(k, v);
|
||||
return *dynamic_cast<LLSD*>(this);
|
||||
}
|
||||
void LLSD::erase(const String& k) { makeMap(impl).erase(k); }
|
||||
|
||||
LLSD& LLSD::operator[](const String& k)
|
||||
|
|
@ -761,8 +780,11 @@ int LLSD::size() const { return safe(impl).size(); }
|
|||
LLSD LLSD::get(Integer i) const { return safe(impl).get(i); }
|
||||
void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); }
|
||||
|
||||
void LLSD::insert(Integer i, const LLSD& v)
|
||||
{ makeArray(impl).insert(i, v); }
|
||||
LLSD& LLSD::insert(Integer i, const LLSD& v)
|
||||
{
|
||||
makeArray(impl).insert(i, v);
|
||||
return *this;
|
||||
}
|
||||
void LLSD::append(const LLSD& v) { makeArray(impl).append(v); }
|
||||
void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ public:
|
|||
|
||||
bool has(const String&) const;
|
||||
LLSD get(const String&) const;
|
||||
void insert(const String&, const LLSD&);
|
||||
LLSD& insert(const String&, const LLSD&);
|
||||
void erase(const String&);
|
||||
|
||||
LLSD& operator[](const String&);
|
||||
|
|
@ -237,7 +237,7 @@ public:
|
|||
|
||||
LLSD get(Integer) const;
|
||||
void set(Integer, const LLSD&);
|
||||
void insert(Integer, const LLSD&);
|
||||
LLSD& insert(Integer, const LLSD&);
|
||||
void append(const LLSD&);
|
||||
void erase(Integer);
|
||||
|
||||
|
|
|
|||
|
|
@ -569,6 +569,14 @@ LLEventTimer::LLEventTimer(F32 period)
|
|||
sActiveList.push_back(this);
|
||||
}
|
||||
|
||||
LLEventTimer::LLEventTimer(const LLDate& time)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
|
||||
sActiveList.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
LLEventTimer::~LLEventTimer()
|
||||
{
|
||||
sActiveList.remove(this);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <limits.h>
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "lldate.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
|
@ -173,6 +174,7 @@ class LLEventTimer
|
|||
{
|
||||
public:
|
||||
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
|
||||
LLEventTimer(const LLDate& time);
|
||||
virtual ~LLEventTimer();
|
||||
|
||||
//function to be called at the supplied frequency
|
||||
|
|
|
|||
|
|
@ -908,6 +908,21 @@ BOOL LLUUID::parseUUID(const std::string& buf, LLUUID* value)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//static
|
||||
LLUUID LLUUID::generateNewID(std::string hash_string)
|
||||
{
|
||||
LLUUID new_id;
|
||||
if (hash_string.empty())
|
||||
{
|
||||
new_id.generate();
|
||||
}
|
||||
else
|
||||
{
|
||||
new_id.generate(hash_string);
|
||||
}
|
||||
return new_id;
|
||||
}
|
||||
|
||||
LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const
|
||||
{
|
||||
LLAssetID result;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ public:
|
|||
//
|
||||
void generate(); // Generate a new UUID
|
||||
void generate(const std::string& stream); //Generate a new UUID based on hash of input stream
|
||||
|
||||
static LLUUID generateNewID(std::string stream = ""); //static version of above for use in initializer expressions such as constructor params, etc.
|
||||
|
||||
BOOL set(const char *in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings
|
||||
BOOL set(const std::string& in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings
|
||||
void setNull(); // Faster than setting to LLUUID::null.
|
||||
|
|
@ -124,7 +127,7 @@ public:
|
|||
static S32 getNodeID(unsigned char * node_id);
|
||||
|
||||
static BOOL parseUUID(const std::string& buf, LLUUID* value);
|
||||
|
||||
|
||||
U8 mData[UUID_BYTES];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public:
|
|||
// become a singleton and this pattern will more easily disambiguate them.
|
||||
typedef LLSingleton<LLGlobalEconomy> Singleton;
|
||||
|
||||
void initSingleton() { }
|
||||
|
||||
virtual void print();
|
||||
|
||||
static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
|
||||
|
|
|
|||
|
|
@ -103,6 +103,30 @@ const F32 FP_MAG_THRESHOLD = 0.0000001f;
|
|||
// TODO: Replace with logic like is_approx_equal
|
||||
inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
|
||||
|
||||
// These functions work by interpreting sign+exp+mantissa as an unsigned
|
||||
// integer.
|
||||
// For example:
|
||||
// x = <sign>1 <exponent>00000010 <mantissa>00000000000000000000000
|
||||
// y = <sign>1 <exponent>00000001 <mantissa>11111111111111111111111
|
||||
//
|
||||
// interpreted as ints =
|
||||
// x = 10000001000000000000000000000000
|
||||
// y = 10000000111111111111111111111111
|
||||
// which is clearly a different of 1 in the least significant bit
|
||||
// Values with the same exponent can be trivially shown to work.
|
||||
//
|
||||
// WARNING: Denormals of opposite sign do not work
|
||||
// x = <sign>1 <exponent>00000000 <mantissa>00000000000000000000001
|
||||
// y = <sign>0 <exponent>00000000 <mantissa>00000000000000000000001
|
||||
// Although these values differ by 2 in the LSB, the sign bit makes
|
||||
// the int comparison fail.
|
||||
//
|
||||
// WARNING: NaNs can compare equal
|
||||
// There is no special treatment of exceptional values like NaNs
|
||||
//
|
||||
// WARNING: Infinity is comparable with F32_MAX and negative
|
||||
// infinity is comparable with F32_MIN
|
||||
|
||||
inline BOOL is_approx_equal(F32 x, F32 y)
|
||||
{
|
||||
const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
|
||||
|
|
|
|||
|
|
@ -223,6 +223,11 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return mLeft <= mRight && mBottom <= mTop;
|
||||
}
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
return mLeft == mRight || mBottom == mTop;
|
||||
|
|
|
|||
|
|
@ -980,13 +980,10 @@ void LLGLState::initClass()
|
|||
{
|
||||
sStateMap[GL_DITHER] = GL_TRUE;
|
||||
// sStateMap[GL_TEXTURE_2D] = GL_TRUE;
|
||||
|
||||
|
||||
//make sure multisample defaults to disabled
|
||||
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
//default vertex arrays to enabled.
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ set(llui_SOURCE_FILES
|
|||
lleditmenuhandler.cpp
|
||||
llfloater.cpp
|
||||
llfocusmgr.cpp
|
||||
llfunctorregistry.cpp
|
||||
lliconctrl.cpp
|
||||
llkeywords.cpp
|
||||
lllineeditor.cpp
|
||||
|
|
@ -43,6 +44,7 @@ set(llui_SOURCE_FILES
|
|||
llmodaldialog.cpp
|
||||
llmultislider.cpp
|
||||
llmultisliderctrl.cpp
|
||||
llnotifications.cpp
|
||||
llpanel.cpp
|
||||
llprogressbar.cpp
|
||||
llradiogroup.cpp
|
||||
|
|
@ -86,6 +88,7 @@ set(llui_HEADER_FILES
|
|||
lleditmenuhandler.h
|
||||
llfloater.h
|
||||
llfocusmgr.h
|
||||
llfunctorregistry.h
|
||||
llhtmlhelp.h
|
||||
lliconctrl.h
|
||||
llkeywords.h
|
||||
|
|
@ -95,6 +98,7 @@ set(llui_HEADER_FILES
|
|||
llmodaldialog.h
|
||||
llmultisliderctrl.h
|
||||
llmultislider.h
|
||||
llnotifications.h
|
||||
llpanel.h
|
||||
llprogressbar.h
|
||||
llradiogroup.h
|
||||
|
|
|
|||
|
|
@ -72,11 +72,12 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
|
|||
mTextEntryTentative(TRUE),
|
||||
mListPosition(BELOW),
|
||||
mPrearrangeCallback( NULL ),
|
||||
mTextEntryCallback( NULL )
|
||||
mTextEntryCallback( NULL ),
|
||||
mLabel(label)
|
||||
{
|
||||
// Always use text box
|
||||
// Text label button
|
||||
mButton = new LLButton(label,
|
||||
mButton = new LLButton(mLabel,
|
||||
LLRect(),
|
||||
LLStringUtil::null,
|
||||
NULL, this);
|
||||
|
|
@ -197,7 +198,12 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
|
|||
}
|
||||
}
|
||||
|
||||
combo_box->selectFirstItem();
|
||||
// if providing user text entry or descriptive label
|
||||
// don't select an item under the hood
|
||||
if (!combo_box->acceptsTextInput() && combo_box->mLabel.empty())
|
||||
{
|
||||
combo_box->selectFirstItem();
|
||||
}
|
||||
|
||||
return combo_box;
|
||||
}
|
||||
|
|
@ -259,7 +265,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, BOO
|
|||
{
|
||||
LLScrollListItem* item = mList->addSimpleElement(name, pos);
|
||||
item->setEnabled(enabled);
|
||||
mList->selectFirstItem();
|
||||
if (!mAllowTextEntry && mLabel.empty())
|
||||
{
|
||||
selectFirstItem();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
@ -268,7 +277,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, const LLUUID& id, EAd
|
|||
{
|
||||
LLScrollListItem* item = mList->addSimpleElement(name, pos, id);
|
||||
item->setEnabled(enabled);
|
||||
mList->selectFirstItem();
|
||||
if (!mAllowTextEntry && mLabel.empty())
|
||||
{
|
||||
selectFirstItem();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +290,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, void* userdata, EAddP
|
|||
LLScrollListItem* item = mList->addSimpleElement(name, pos);
|
||||
item->setEnabled(enabled);
|
||||
item->setUserdata( userdata );
|
||||
mList->selectFirstItem();
|
||||
if (!mAllowTextEntry && mLabel.empty())
|
||||
{
|
||||
selectFirstItem();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +302,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, LLSD value, EAddPosit
|
|||
{
|
||||
LLScrollListItem* item = mList->addSimpleElement(name, pos, value);
|
||||
item->setEnabled(enabled);
|
||||
mList->selectFirstItem();
|
||||
if (!mAllowTextEntry && mLabel.empty())
|
||||
{
|
||||
selectFirstItem();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ protected:
|
|||
LLScrollListCtrl* mList;
|
||||
EPreferredPosition mListPosition;
|
||||
LLPointer<LLUIImage> mArrowImage;
|
||||
std::string mLabel;
|
||||
|
||||
private:
|
||||
S32 mButtonPadding;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ LLFloater::LLFloater() :
|
|||
}
|
||||
mDragHandle = NULL;
|
||||
mHandle.bind(this);
|
||||
mNotificationContext = new LLFloaterNotificationContext(getHandle());
|
||||
}
|
||||
|
||||
LLFloater::LLFloater(const std::string& name)
|
||||
|
|
@ -220,6 +221,7 @@ void LLFloater::initFloater(const std::string& title,
|
|||
BOOL drag_on_left, BOOL minimizable, BOOL close_btn)
|
||||
{
|
||||
mHandle.bind(this);
|
||||
mNotificationContext = new LLFloaterNotificationContext(getHandle());
|
||||
|
||||
// Init function can be called more than once, so clear out old data.
|
||||
for (S32 i = 0; i < BUTTON_COUNT; i++)
|
||||
|
|
@ -429,6 +431,9 @@ void LLFloater::initFloater(const std::string& title,
|
|||
// virtual
|
||||
LLFloater::~LLFloater()
|
||||
{
|
||||
delete mNotificationContext;
|
||||
mNotificationContext = NULL;
|
||||
|
||||
control_map_t::iterator itor;
|
||||
for (itor = mFloaterControls.begin(); itor != mFloaterControls.end(); ++itor)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llnotifications.h"
|
||||
#include <set>
|
||||
|
||||
class LLDragHandle;
|
||||
|
|
@ -46,6 +47,7 @@ class LLResizeHandle;
|
|||
class LLResizeBar;
|
||||
class LLButton;
|
||||
class LLMultiFloater;
|
||||
class LLFloater;
|
||||
|
||||
const S32 LLFLOATER_VPAD = 6;
|
||||
const S32 LLFLOATER_HPAD = 6;
|
||||
|
|
@ -70,6 +72,20 @@ const BOOL CLOSE_NO = FALSE;
|
|||
const BOOL ADJUST_VERTICAL_YES = TRUE;
|
||||
const BOOL ADJUST_VERTICAL_NO = FALSE;
|
||||
|
||||
// associates a given notification instance with a particular floater
|
||||
class LLFloaterNotificationContext :
|
||||
public LLNotificationContext
|
||||
{
|
||||
public:
|
||||
LLFloaterNotificationContext(LLHandle<LLFloater> floater_handle) :
|
||||
mFloaterHandle(floater_handle)
|
||||
{}
|
||||
|
||||
LLFloater* getFloater() { return mFloaterHandle.get(); }
|
||||
private:
|
||||
LLHandle<LLFloater> mFloaterHandle;
|
||||
};
|
||||
|
||||
|
||||
class LLFloater : public LLPanel
|
||||
{
|
||||
|
|
@ -213,6 +229,11 @@ public:
|
|||
// handle refocusing.
|
||||
static void closeFocusedFloater();
|
||||
|
||||
LLNotification::Params contextualNotification(const std::string& name)
|
||||
{
|
||||
return LLNotification::Params(name).context(mNotificationContext);
|
||||
}
|
||||
|
||||
static void onClickClose(void *userdata);
|
||||
static void onClickMinimize(void *userdata);
|
||||
static void onClickTearOff(void *userdata);
|
||||
|
|
@ -299,7 +320,7 @@ private:
|
|||
S32 mPreviousMinimizedBottom;
|
||||
S32 mPreviousMinimizedLeft;
|
||||
|
||||
private:
|
||||
LLFloaterNotificationContext* mNotificationContext;
|
||||
LLRootHandle<LLFloater> mHandle;
|
||||
};
|
||||
|
||||
|
|
@ -467,7 +488,6 @@ template <class T> class LLFloaterSingleton : public LLUISingleton<T, Visibility
|
|||
{
|
||||
};
|
||||
|
||||
|
||||
extern LLFloaterView* gFloaterView;
|
||||
|
||||
#endif // LL_FLOATER_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @file llfunctorregistry.cpp
|
||||
* @author Kent Quirk
|
||||
* @brief Maintains a registry of named callback functors taking a single LLSD parameter
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2008, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
**/
|
||||
|
||||
#include "llfunctorregistry.h"
|
||||
|
||||
// This is a default functor always resident in the system.
|
||||
// It's used whenever a functor isn't found in the registry, so that
|
||||
// we at least log the data relating to the user response.
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @file llfunctorregistry.h
|
||||
* @author Kent Quirk
|
||||
* @brief Maintains a registry of named callback functors taking a single LLSD parameter
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-2007, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFUNCTORREGISTRY_H
|
||||
#define LL_LLFUNCTORREGISTRY_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include "llsd.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
/**
|
||||
* @class LLFunctorRegistry
|
||||
* @brief Maintains a collection of named functors for remote binding
|
||||
* (mainly for use in callbacks from notifications and other signals)
|
||||
* @see LLNotifications
|
||||
*
|
||||
* This class maintains a collection of named functors in a singleton.
|
||||
* We wanted to be able to persist notifications with their callbacks
|
||||
* across restarts of the viewer; we couldn't store functors that way.
|
||||
* Using this registry, systems that require a functor to be maintained
|
||||
* long term can register it at system startup, and then pass in the
|
||||
* functor by name.
|
||||
*/
|
||||
|
||||
template <typename FUNCTOR_TYPE>
|
||||
class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
|
||||
{
|
||||
friend class LLSingleton<LLFunctorRegistry>;
|
||||
LOG_CLASS(LLFunctorRegistry);
|
||||
private:
|
||||
LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing")
|
||||
{
|
||||
mMap[LOGFUNCTOR] = log_functor;
|
||||
mMap[DONOTHING] = do_nothing;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef FUNCTOR_TYPE ResponseFunctor;
|
||||
typedef typename std::map<std::string, FUNCTOR_TYPE> FunctorMap;
|
||||
|
||||
bool registerFunctor(const std::string& name, ResponseFunctor f)
|
||||
{
|
||||
bool retval = true;
|
||||
typename FunctorMap::iterator it = mMap.find(name);
|
||||
if (mMap.count(name) == 0)
|
||||
{
|
||||
mMap[name] = f;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "attempt to store duplicate name '" << name << "' in LLFunctorRegistry. NOT ADDED." << llendl;
|
||||
retval = false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool unregisterFunctor(const std::string& name)
|
||||
{
|
||||
if (mMap.count(name) == 0)
|
||||
{
|
||||
llwarns << "trying to remove '" << name << "' from LLFunctorRegistry but it's not there." << llendl;
|
||||
return false;
|
||||
}
|
||||
mMap.erase(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
FUNCTOR_TYPE getFunctor(const std::string& name)
|
||||
{
|
||||
typename FunctorMap::iterator it = mMap.find(name);
|
||||
if (mMap.count(name) != 0)
|
||||
{
|
||||
return mMap[name];
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "tried to find '" << name << "' in LLFunctorRegistry, but it wasn't there." << llendl;
|
||||
return mMap[LOGFUNCTOR];
|
||||
}
|
||||
}
|
||||
|
||||
const std::string LOGFUNCTOR;
|
||||
const std::string DONOTHING;
|
||||
|
||||
private:
|
||||
|
||||
static void log_functor(const LLSD& notification, const LLSD& payload)
|
||||
{
|
||||
llwarns << "log_functor called with payload: " << payload << llendl;
|
||||
}
|
||||
|
||||
static void do_nothing(const LLSD& notification, const LLSD& payload)
|
||||
{
|
||||
// what the sign sez
|
||||
}
|
||||
|
||||
FunctorMap mMap;
|
||||
};
|
||||
|
||||
template <typename FUNCTOR_TYPE>
|
||||
class LLFunctorRegistration
|
||||
{
|
||||
public:
|
||||
LLFunctorRegistration(const std::string& name, FUNCTOR_TYPE functor)
|
||||
{
|
||||
LLFunctorRegistry<FUNCTOR_TYPE>::instance().registerFunctor(name, functor);
|
||||
}
|
||||
};
|
||||
|
||||
#endif//LL_LLFUNCTORREGISTRY_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,892 @@
|
|||
/**
|
||||
* @file llnotifications.h
|
||||
* @brief Non-UI manager and support for keeping a prioritized list of notifications
|
||||
* @author Q (with assistance from Richard and Coco)
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2008, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNOTIFICATIONS_H
|
||||
#define LL_LLNOTIFICATIONS_H
|
||||
|
||||
/**
|
||||
* This system is intended to provide a singleton mechanism for adding
|
||||
* notifications to one of an arbitrary set of event channels.
|
||||
*
|
||||
* Controlling JIRA: DEV-9061
|
||||
*
|
||||
* Every notification has (see code for full list):
|
||||
* - a textual name, which is used to look up its template in the XML files
|
||||
* - a payload, which is a block of LLSD
|
||||
* - a channel, which is normally extracted from the XML files but
|
||||
* can be overridden.
|
||||
* - a timestamp, used to order the notifications
|
||||
* - expiration time -- if nonzero, specifies a time after which the
|
||||
* notification will no longer be valid.
|
||||
* - a callback name and a couple of status bits related to callbacks (see below)
|
||||
*
|
||||
* There is a management class called LLNotifications, which is an LLSingleton.
|
||||
* The class maintains a collection of all of the notifications received
|
||||
* or processed during this session, and also manages the persistence
|
||||
* of those notifications that must be persisted.
|
||||
*
|
||||
* We also have Channels. A channel is a view on a collection of notifications;
|
||||
* The collection is defined by a filter function that controls which
|
||||
* notifications are in the channel, and its ordering is controlled by
|
||||
* a comparator.
|
||||
*
|
||||
* There is a hierarchy of channels; notifications flow down from
|
||||
* the management class (LLNotifications, which itself inherits from
|
||||
* The channel base class) to the individual channels.
|
||||
* Any change to notifications (add, delete, modify) is
|
||||
* automatically propagated through the channel hierarchy.
|
||||
*
|
||||
* We provide methods for adding a new notification, for removing
|
||||
* one, and for managing channels. Channels are relatively cheap to construct
|
||||
* and maintain, so in general, human interfaces should use channels to
|
||||
* select and manage their lists of notifications.
|
||||
*
|
||||
* We also maintain a collection of templates that are loaded from the
|
||||
* XML file of template translations. The system supports substitution
|
||||
* of named variables from the payload into the XML file.
|
||||
*
|
||||
* By default, only the "unknown message" template is built into the system.
|
||||
* It is not an error to add a notification that's not found in the
|
||||
* template system, but it is logged.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/signal.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
// we want to minimize external dependencies, but this one is important
|
||||
#include "llsd.h"
|
||||
|
||||
// and we need this to manage the notification callbacks
|
||||
#include "llfunctorregistry.h"
|
||||
#include "llui.h"
|
||||
|
||||
class LLNotification;
|
||||
typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
|
||||
|
||||
/*****************************************************************************
|
||||
* Signal and handler declarations
|
||||
* Using a single handler signature means that we can have a common handler
|
||||
* type, rather than needing a distinct one for each different handler.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* A boost::signals Combiner that stops the first time a handler returns true
|
||||
* We need this because we want to have our handlers return bool, so that
|
||||
* we have the option to cause a handler to stop further processing. The
|
||||
* default handler fails when the signal returns a value but has no slots.
|
||||
*/
|
||||
struct LLStopWhenHandled
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template<typename InputIterator>
|
||||
result_type operator()(InputIterator first, InputIterator last) const
|
||||
{
|
||||
for (InputIterator si = first; si != last; ++si)
|
||||
{
|
||||
if (*si)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef enum e_notification_priority
|
||||
{
|
||||
NOTIFICATION_PRIORITY_UNSPECIFIED,
|
||||
NOTIFICATION_PRIORITY_LOW,
|
||||
NOTIFICATION_PRIORITY_NORMAL,
|
||||
NOTIFICATION_PRIORITY_HIGH,
|
||||
NOTIFICATION_PRIORITY_CRITICAL
|
||||
} ENotificationPriority;
|
||||
|
||||
/**
|
||||
* We want to have a standard signature for all signals; this way,
|
||||
* we can easily document a protocol for communicating across
|
||||
* dlls and into scripting languages someday.
|
||||
* we want to return a bool to indicate whether the signal has been
|
||||
* handled and should NOT be passed on to other listeners.
|
||||
* Return true to stop further handling of the signal, and false
|
||||
* to continue.
|
||||
* We take an LLSD because this way the contents of the signal
|
||||
* are independent of the API used to communicate it.
|
||||
* It is const ref because then there's low cost to pass it;
|
||||
* if you only need to inspect it, it's very cheap.
|
||||
*/
|
||||
|
||||
typedef boost::function<void (const LLSD&, const LLSD&)> LLNotificationResponder;
|
||||
|
||||
typedef LLFunctorRegistry<LLNotificationResponder> LLNotificationFunctorRegistry;
|
||||
typedef LLFunctorRegistration<LLNotificationResponder> LLNotificationFunctorRegistration;
|
||||
|
||||
typedef boost::signal<bool(const LLSD&), LLStopWhenHandled> LLStandardSignal;
|
||||
|
||||
// context data that can be looked up via a notification's payload by the display logic
|
||||
// derive from this class to implement specific contexts
|
||||
class LLNotificationContext : public LLInstanceTracker<LLNotificationContext, LLUUID>
|
||||
{
|
||||
public:
|
||||
LLNotificationContext() : LLInstanceTracker<LLNotificationContext, LLUUID>(LLUUID::generateNewID())
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~LLNotificationContext() {}
|
||||
|
||||
LLSD asLLSD() const
|
||||
{
|
||||
return getKey();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
// Contains notification form data, such as buttons and text fields along with
|
||||
// manipulator functions
|
||||
class LLNotificationForm
|
||||
{
|
||||
LOG_CLASS(LLNotificationForm);
|
||||
|
||||
public:
|
||||
typedef enum e_ignore_type
|
||||
{
|
||||
IGNORE_NO,
|
||||
IGNORE_WITH_DEFAULT_RESPONSE,
|
||||
IGNORE_WITH_LAST_RESPONSE,
|
||||
IGNORE_SHOW_AGAIN
|
||||
} EIgnoreType;
|
||||
|
||||
LLNotificationForm();
|
||||
LLNotificationForm(const LLSD& sd);
|
||||
LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node);
|
||||
|
||||
LLSD asLLSD() const;
|
||||
|
||||
S32 getNumElements() { return mFormData.size(); }
|
||||
LLSD getElement(S32 index) { return mFormData.get(index); }
|
||||
LLSD getElement(const std::string& element_name);
|
||||
bool hasElement(const std::string& element_name);
|
||||
void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD());
|
||||
void formatElements(const LLSD& substitutions);
|
||||
// appends form elements from another form serialized as LLSD
|
||||
void append(const LLSD& sub_form);
|
||||
std::string getDefaultOption();
|
||||
|
||||
EIgnoreType getIgnoreType() { return mIgnore; }
|
||||
std::string getIgnoreMessage() { return mIgnoreMsg; }
|
||||
|
||||
private:
|
||||
LLSD mFormData;
|
||||
EIgnoreType mIgnore;
|
||||
std::string mIgnoreMsg;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
|
||||
|
||||
// This is the class of object read from the XML file (notifications.xml,
|
||||
// from the appropriate local language directory).
|
||||
struct LLNotificationTemplate
|
||||
{
|
||||
LLNotificationTemplate();
|
||||
// the name of the notification -- the key used to identify it
|
||||
// Ideally, the key should follow variable naming rules
|
||||
// (no spaces or punctuation).
|
||||
std::string mName;
|
||||
// The type of the notification
|
||||
// used to control which queue it's stored in
|
||||
std::string mType;
|
||||
// The text used to display the notification. Replaceable parameters
|
||||
// are enclosed in square brackets like this [].
|
||||
std::string mMessage;
|
||||
// The label for the notification; used for
|
||||
// certain classes of notification (those with a window and a window title).
|
||||
// Also used when a notification pops up underneath the current one.
|
||||
// Replaceable parameters can be used in the label.
|
||||
std::string mLabel;
|
||||
// The name of the icon image. This should include an extension.
|
||||
std::string mIcon;
|
||||
// This is the Highlander bit -- "There Can Be Only One"
|
||||
// An outstanding notification with this bit set
|
||||
// is updated by an incoming notification with the same name,
|
||||
// rather than creating a new entry in the queue.
|
||||
// (used for things like progress indications, or repeating warnings
|
||||
// like "the grid is going down in N minutes")
|
||||
bool mUnique;
|
||||
// if we want to be unique only if a certain part of the payload is constant
|
||||
// specify the field names for the payload. The notification will only be
|
||||
// combined if all of the fields named in the context are identical in the
|
||||
// new and the old notification; otherwise, the notification will be
|
||||
// duplicated. This is to support suppressing duplicate offers from the same
|
||||
// sender but still differentiating different offers. Example: Invitation to
|
||||
// conference chat.
|
||||
std::vector<std::string> mUniqueContext;
|
||||
// If this notification expires automatically, this value will be
|
||||
// nonzero, and indicates the number of seconds for which the notification
|
||||
// will be valid (a teleport offer, for example, might be valid for
|
||||
// 300 seconds).
|
||||
U32 mExpireSeconds;
|
||||
// if the offer expires, one of the options is chosen automatically
|
||||
// based on its "value" parameter. This controls which one.
|
||||
// If expireSeconds is specified, expireOption should also be specified.
|
||||
U32 mExpireOption;
|
||||
// if the notification contains a url, it's stored here (and replaced
|
||||
// into the message where [_URL] is found)
|
||||
std::string mURL;
|
||||
// if there's a URL in the message, this controls which option visits
|
||||
// that URL. Obsolete this and eliminate the buttons for affected
|
||||
// messages when we allow clickable URLs in the UI
|
||||
U32 mURLOption;
|
||||
// does this notification persist across sessions? if so, it will be
|
||||
// serialized to disk on first receipt and read on startup
|
||||
bool mPersist;
|
||||
// This is the name of the default functor, if present, to be
|
||||
// used for the notification's callback. It is optional, and used only if
|
||||
// the notification is constructed without an identified functor.
|
||||
std::string mDefaultFunctor;
|
||||
// The form data associated with a given notification (buttons, text boxes, etc)
|
||||
LLNotificationFormPtr mForm;
|
||||
// default priority for notifications of this type
|
||||
ENotificationPriority mPriority;
|
||||
// UUID of the audio file to be played when this notification arrives
|
||||
// this is loaded as a name, but looked up to get the UUID upon template load.
|
||||
// If null, it wasn't specified.
|
||||
LLUUID mSoundEffect;
|
||||
};
|
||||
|
||||
// we want to keep a map of these by name, and it's best to manage them
|
||||
// with smart pointers
|
||||
typedef boost::shared_ptr<LLNotificationTemplate> LLNotificationTemplatePtr;
|
||||
|
||||
/**
|
||||
* @class LLNotification
|
||||
* @brief The object that expresses the details of a notification
|
||||
*
|
||||
* We make this noncopyable because
|
||||
* we want to manage these through LLNotificationPtr, and only
|
||||
* ever create one instance of any given notification.
|
||||
*
|
||||
* The enable_shared_from_this flag ensures that if we construct
|
||||
* a smart pointer from a notification, we'll always get the same
|
||||
* shared pointer.
|
||||
*/
|
||||
class LLNotification :
|
||||
boost::noncopyable,
|
||||
public boost::enable_shared_from_this<LLNotification>
|
||||
{
|
||||
LOG_CLASS(LLNotification);
|
||||
friend class LLNotifications;
|
||||
|
||||
public:
|
||||
// parameter object used to instantiate a new notification
|
||||
class Params : public LLParamBlock<Params>
|
||||
{
|
||||
friend class LLNotification;
|
||||
public:
|
||||
Params(const std::string& _name)
|
||||
: name(_name),
|
||||
mTemporaryResponder(false),
|
||||
functor_name(_name),
|
||||
priority(NOTIFICATION_PRIORITY_UNSPECIFIED),
|
||||
timestamp(LLDate::now())
|
||||
{
|
||||
}
|
||||
|
||||
// pseudo-param
|
||||
Params& functor(LLNotificationFunctorRegistry::ResponseFunctor f)
|
||||
{
|
||||
functor_name = LLUUID::generateNewID().asString();
|
||||
LLNotificationFunctorRegistry::instance().registerFunctor(functor_name, f);
|
||||
|
||||
mTemporaryResponder = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLMandatoryParam<std::string> name;
|
||||
|
||||
// optional
|
||||
LLOptionalParam<LLSD> substitutions;
|
||||
LLOptionalParam<LLSD> payload;
|
||||
LLOptionalParam<ENotificationPriority> priority;
|
||||
LLOptionalParam<LLSD> form_elements;
|
||||
LLOptionalParam<LLDate> timestamp;
|
||||
LLOptionalParam<LLNotificationContext*> context;
|
||||
LLOptionalParam<std::string> functor_name;
|
||||
|
||||
private:
|
||||
bool mTemporaryResponder;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
LLUUID mId;
|
||||
LLSD mPayload;
|
||||
LLSD mSubstitutions;
|
||||
LLDate mTimestamp;
|
||||
LLDate mExpiresAt;
|
||||
bool mCancelled;
|
||||
bool mRespondedTo; // once the notification has been responded to, this becomes true
|
||||
bool mIgnored;
|
||||
ENotificationPriority mPriority;
|
||||
LLNotificationFormPtr mForm;
|
||||
|
||||
// a reference to the template
|
||||
LLNotificationTemplatePtr mTemplatep;
|
||||
|
||||
/*
|
||||
We want to be able to store and reload notifications so that they can survive
|
||||
a shutdown/restart of the client. So we can't simply pass in callbacks;
|
||||
we have to specify a callback mechanism that can be used by name rather than
|
||||
by some arbitrary pointer -- and then people have to initialize callbacks
|
||||
in some useful location. So we use LLNotificationFunctorRegistry to manage them.
|
||||
*/
|
||||
std::string mResponseFunctorName;
|
||||
|
||||
/*
|
||||
In cases where we want to specify an explict, non-persisted callback,
|
||||
we store that in the callback registry under a dynamically generated
|
||||
key, and store the key in the notification, so we can still look it up
|
||||
using the same mechanism.
|
||||
*/
|
||||
bool mTemporaryResponder;
|
||||
|
||||
void init(const std::string& template_name, const LLSD& form_elements);
|
||||
|
||||
LLNotification(const Params& p);
|
||||
|
||||
// this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
|
||||
// for anything real!
|
||||
LLNotification(LLUUID uuid) : mId(uuid) {}
|
||||
|
||||
void cancel();
|
||||
|
||||
bool payloadContainsAll(const std::vector<std::string>& required_fields) const;
|
||||
|
||||
public:
|
||||
|
||||
// constructor from a saved notification
|
||||
LLNotification(const LLSD& sd);
|
||||
|
||||
// This is a string formatter for substituting into the message directly
|
||||
// from LLSD without going through the hopefully-to-be-obsoleted LLString
|
||||
static std::string format(const std::string& text, const LLSD& substitutions);
|
||||
|
||||
void setResponseFunctor(std::string const &responseFunctorName);
|
||||
|
||||
typedef enum e_response_template_type
|
||||
{
|
||||
WITHOUT_DEFAULT_BUTTON,
|
||||
WITH_DEFAULT_BUTTON
|
||||
} EResponseTemplateType;
|
||||
|
||||
// return response LLSD filled in with default form contents and (optionally) the default button selected
|
||||
LLSD getResponseTemplate(EResponseTemplateType type = WITHOUT_DEFAULT_BUTTON);
|
||||
|
||||
// returns index of first button with value==TRUE
|
||||
// usually this the button the user clicked on
|
||||
// returns -1 if no button clicked (e.g. form has not been displayed)
|
||||
static S32 getSelectedOption(const LLSD& notification, const LLSD& response);
|
||||
// returns name of first button with value==TRUE
|
||||
static std::string getSelectedOptionName(const LLSD& notification);
|
||||
|
||||
// after someone responds to a notification (usually by clicking a button,
|
||||
// but sometimes by filling out a little form and THEN clicking a button),
|
||||
// the result of the response (the name and value of the button clicked,
|
||||
// plus any other data) should be packaged up as LLSD, then passed as a
|
||||
// parameter to the notification's respond() method here. This will look up
|
||||
// and call the appropriate responder.
|
||||
//
|
||||
// response is notification serialized as LLSD:
|
||||
// ["name"] = notification name
|
||||
// ["form"] = LLSD tree that includes form description and any prefilled form data
|
||||
// ["response"] = form data filled in by user
|
||||
// (including, but not limited to which button they clicked on)
|
||||
// ["payload"] = transaction specific data, such as ["source_id"] (originator of notification),
|
||||
// ["item_id"] (attached inventory item), etc.
|
||||
// ["substitutions"] = string substitutions used to generate notification message
|
||||
// from the template
|
||||
// ["time"] = time at which notification was generated;
|
||||
// ["expiry"] = time at which notification expires;
|
||||
// ["responseFunctor"] = name of registered functor that handles responses to notification;
|
||||
LLSD asLLSD();
|
||||
|
||||
void respond(const LLSD& sd);
|
||||
|
||||
void setIgnored(bool ignore);
|
||||
|
||||
bool isCancelled() const
|
||||
{
|
||||
return mCancelled;
|
||||
}
|
||||
|
||||
bool isRespondedTo() const
|
||||
{
|
||||
return mRespondedTo;
|
||||
}
|
||||
|
||||
bool isIgnored() const
|
||||
{
|
||||
return mIgnored;
|
||||
}
|
||||
|
||||
const std::string& getName() const
|
||||
{
|
||||
return mTemplatep->mName;
|
||||
}
|
||||
|
||||
const LLUUID& id() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
const LLSD& getPayload() const
|
||||
{
|
||||
return mPayload;
|
||||
}
|
||||
|
||||
const LLSD& getSubstitutions() const
|
||||
{
|
||||
return mSubstitutions;
|
||||
}
|
||||
|
||||
const LLDate& getDate() const
|
||||
{
|
||||
return mTimestamp;
|
||||
}
|
||||
|
||||
std::string getType() const
|
||||
{
|
||||
return (mTemplatep ? mTemplatep->mType : "");
|
||||
}
|
||||
|
||||
std::string getMessage() const;
|
||||
std::string getLabel() const;
|
||||
|
||||
std::string getURL() const
|
||||
{
|
||||
return (mTemplatep ? mTemplatep->mURL : "");
|
||||
}
|
||||
|
||||
S32 getURLOption() const
|
||||
{
|
||||
return (mTemplatep ? mTemplatep->mURLOption : -1);
|
||||
}
|
||||
|
||||
const LLNotificationFormPtr getForm();
|
||||
|
||||
const LLDate getExpiration() const
|
||||
{
|
||||
return mExpiresAt;
|
||||
}
|
||||
|
||||
ENotificationPriority getPriority() const
|
||||
{
|
||||
return mPriority;
|
||||
}
|
||||
|
||||
const LLUUID getID() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
// comparing two notifications normally means comparing them by UUID (so we can look them
|
||||
// up quickly this way)
|
||||
bool operator<(const LLNotification& rhs) const
|
||||
{
|
||||
return mId < rhs.mId;
|
||||
}
|
||||
|
||||
bool operator==(const LLNotification& rhs) const
|
||||
{
|
||||
return mId == rhs.mId;
|
||||
}
|
||||
|
||||
bool operator!=(const LLNotification& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
bool isSameObjectAs(const LLNotification* rhs) const
|
||||
{
|
||||
return this == rhs;
|
||||
}
|
||||
|
||||
// this object has been updated, so tell all our clients
|
||||
void update();
|
||||
|
||||
void updateFrom(LLNotificationPtr other);
|
||||
|
||||
// A fuzzy equals comparator.
|
||||
// true only if both notifications have the same template and
|
||||
// 1) flagged as unique (there can be only one of these) OR
|
||||
// 2) all required payload fields of each also exist in the other.
|
||||
bool isEquivalentTo(LLNotificationPtr that) const;
|
||||
|
||||
// if the current time is greater than the expiration, the notification is expired
|
||||
bool isExpired() const
|
||||
{
|
||||
if (mExpiresAt.secondsSinceEpoch() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLDate rightnow = LLDate::now();
|
||||
return rightnow > mExpiresAt;
|
||||
}
|
||||
|
||||
std::string summarize() const;
|
||||
|
||||
bool hasUniquenessConstraints() const { return (mTemplatep ? mTemplatep->mUnique : false);}
|
||||
|
||||
virtual ~LLNotification() {}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLNotification& notification);
|
||||
|
||||
namespace LLNotificationFilters
|
||||
{
|
||||
// a sample filter
|
||||
bool includeEverything(LLNotificationPtr p);
|
||||
|
||||
typedef enum e_comparison
|
||||
{
|
||||
EQUAL,
|
||||
LESS,
|
||||
GREATER,
|
||||
LESS_EQUAL,
|
||||
GREATER_EQUAL
|
||||
} EComparison;
|
||||
|
||||
// generic filter functor that takes method or member variable reference
|
||||
template<typename T>
|
||||
struct filterBy
|
||||
{
|
||||
typedef boost::function<T (LLNotificationPtr)> field_t;
|
||||
typedef typename boost::remove_reference<T>::type value_t;
|
||||
|
||||
filterBy(field_t field, value_t value, EComparison comparison = EQUAL)
|
||||
: mField(field),
|
||||
mFilterValue(value),
|
||||
mComparison(comparison)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(LLNotificationPtr p)
|
||||
{
|
||||
switch(mComparison)
|
||||
{
|
||||
case EQUAL:
|
||||
return mField(p) == mFilterValue;
|
||||
case LESS:
|
||||
return mField(p) < mFilterValue;
|
||||
case GREATER:
|
||||
return mField(p) > mFilterValue;
|
||||
case LESS_EQUAL:
|
||||
return mField(p) <= mFilterValue;
|
||||
case GREATER_EQUAL:
|
||||
return mField(p) >= mFilterValue;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
field_t mField;
|
||||
value_t mFilterValue;
|
||||
EComparison mComparison;
|
||||
};
|
||||
};
|
||||
|
||||
namespace LLNotificationComparators
|
||||
{
|
||||
typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection;
|
||||
|
||||
// generic order functor that takes method or member variable reference
|
||||
template<typename T>
|
||||
struct orderBy
|
||||
{
|
||||
typedef boost::function<T (LLNotificationPtr)> field_t;
|
||||
orderBy(field_t field, EDirection = ORDER_INCREASING) : mField(field) {}
|
||||
bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
|
||||
{
|
||||
if (mDirection == ORDER_DECREASING)
|
||||
{
|
||||
return mField(lhs) > mField(rhs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mField(lhs) < mField(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
field_t mField;
|
||||
EDirection mDirection;
|
||||
};
|
||||
|
||||
struct orderByUUID : public orderBy<const LLUUID&>
|
||||
{
|
||||
orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {}
|
||||
};
|
||||
|
||||
struct orderByDate : public orderBy<const LLDate&>
|
||||
{
|
||||
orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {}
|
||||
};
|
||||
};
|
||||
|
||||
typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
|
||||
typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
|
||||
typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet;
|
||||
typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
|
||||
|
||||
// ========================================================
|
||||
// Abstract base class (interface) for a channel; also used for the master container.
|
||||
// This lets us arrange channels into a call hierarchy.
|
||||
|
||||
// We maintain a heirarchy of notification channels; events are always started at the top
|
||||
// and propagated through the hierarchy only if they pass a filter.
|
||||
// Any channel can be created with a parent. A null parent (empty string) means it's
|
||||
// tied to the root of the tree (the LLNotifications class itself).
|
||||
// The default hierarchy looks like this:
|
||||
//
|
||||
// LLNotifications --+-- Expiration --+-- Mute --+-- Ignore --+-- Visible --+-- History
|
||||
// +-- Alerts
|
||||
// +-- Notifications
|
||||
//
|
||||
// In general, new channels that want to only see notifications that pass through
|
||||
// all of the built-in tests should attach to the "Visible" channel
|
||||
//
|
||||
class LLNotificationChannelBase :
|
||||
public boost::signals::trackable
|
||||
{
|
||||
LOG_CLASS(LLNotificationChannelBase);
|
||||
public:
|
||||
LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) :
|
||||
mFilter(filter), mItems(comp)
|
||||
{}
|
||||
virtual ~LLNotificationChannelBase() {}
|
||||
// you can also connect to a Channel, so you can be notified of
|
||||
// changes to this channel
|
||||
virtual void connectChanged(const LLStandardSignal::slot_type& slot);
|
||||
virtual void connectPassedFilter(const LLStandardSignal::slot_type& slot);
|
||||
virtual void connectFailedFilter(const LLStandardSignal::slot_type& slot);
|
||||
|
||||
// use this when items change or to add a new one
|
||||
bool updateItem(const LLSD& payload);
|
||||
const LLNotificationFilter& getFilter() { return mFilter; }
|
||||
|
||||
protected:
|
||||
LLNotificationSet mItems;
|
||||
LLStandardSignal mChanged;
|
||||
LLStandardSignal mPassedFilter;
|
||||
LLStandardSignal mFailedFilter;
|
||||
|
||||
// these are action methods that subclasses can override to take action
|
||||
// on specific types of changes; the management of the mItems list is
|
||||
// still handled by the generic handler.
|
||||
virtual void onLoad(LLNotificationPtr p) {}
|
||||
virtual void onAdd(LLNotificationPtr p) {}
|
||||
virtual void onDelete(LLNotificationPtr p) {}
|
||||
virtual void onChange(LLNotificationPtr p) {}
|
||||
|
||||
bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
|
||||
LLNotificationFilter mFilter;
|
||||
};
|
||||
|
||||
// manages a list of notifications
|
||||
// Note that if this is ever copied around, we might find ourselves with multiple copies
|
||||
// of a queue with notifications being added to different nonequivalent copies. So we
|
||||
// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
|
||||
//
|
||||
// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to
|
||||
// do something like:
|
||||
// new LLNotificationChannel("name", "parent"...);
|
||||
// You can then retrieve the channel by using the registry:
|
||||
// LLNotifications::instance().getChannel("name")...
|
||||
//
|
||||
class LLNotificationChannel :
|
||||
boost::noncopyable,
|
||||
public LLNotificationChannelBase
|
||||
{
|
||||
LOG_CLASS(LLNotificationChannel);
|
||||
|
||||
public:
|
||||
virtual ~LLNotificationChannel() {}
|
||||
// Notification Channels have a filter, which determines which notifications
|
||||
// will be added to this channel.
|
||||
// Channel filters cannot change.
|
||||
LLNotificationChannel(const std::string& name, const std::string& parent,
|
||||
LLNotificationFilter filter=LLNotificationFilters::includeEverything,
|
||||
LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
|
||||
|
||||
typedef LLNotificationSet::iterator Iterator;
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
std::string getParentChannelName() { return mParent; }
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
Iterator begin();
|
||||
Iterator end();
|
||||
|
||||
// Channels have a comparator to control sort order;
|
||||
// the default sorts by arrival date
|
||||
void setComparator(LLNotificationComparator comparator);
|
||||
|
||||
std::string summarize();
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mParent;
|
||||
LLNotificationComparator mComparator;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// The type of the pointers that we're going to manage in the NotificationQueue system
|
||||
// Because LLNotifications is a singleton, we don't actually expect to ever
|
||||
// destroy it, but if it becomes necessary to do so, the shared_ptr model
|
||||
// will ensure that we don't leak resources.
|
||||
typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
|
||||
|
||||
class LLNotifications :
|
||||
public LLSingleton<LLNotifications>,
|
||||
public LLNotificationChannelBase
|
||||
{
|
||||
LOG_CLASS(LLNotifications);
|
||||
|
||||
friend class LLSingleton<LLNotifications>;
|
||||
public:
|
||||
// load notification descriptions from file;
|
||||
// OK to call more than once because it will reload
|
||||
bool loadTemplates();
|
||||
LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item);
|
||||
|
||||
// we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line
|
||||
LLNotificationPtr add(const std::string& name,
|
||||
const LLSD& substitutions = LLSD(),
|
||||
const LLSD& payload = LLSD());
|
||||
LLNotificationPtr add(const std::string& name,
|
||||
const LLSD& substitutions,
|
||||
const LLSD& payload,
|
||||
const std::string& functor_name);
|
||||
LLNotificationPtr add(const std::string& name,
|
||||
const LLSD& substitutions,
|
||||
const LLSD& payload,
|
||||
LLNotificationFunctorRegistry::ResponseFunctor functor);
|
||||
LLNotificationPtr add(const LLNotification::Params& p);
|
||||
|
||||
void add(const LLNotificationPtr pNotif);
|
||||
void cancel(LLNotificationPtr pNotif);
|
||||
void update(const LLNotificationPtr pNotif);
|
||||
|
||||
LLNotificationPtr find(LLUUID uuid);
|
||||
|
||||
typedef boost::function<void (LLNotificationPtr)> NotificationProcess;
|
||||
|
||||
void forEachNotification(NotificationProcess process);
|
||||
|
||||
// This is all stuff for managing the templates
|
||||
// take your template out
|
||||
LLNotificationTemplatePtr getTemplate(const std::string& name);
|
||||
|
||||
// get the whole collection
|
||||
typedef std::vector<std::string> TemplateNames;
|
||||
TemplateNames getTemplateNames() const; // returns a list of notification names
|
||||
|
||||
typedef std::map<std::string, LLNotificationTemplatePtr> TemplateMap;
|
||||
|
||||
TemplateMap::const_iterator templatesBegin() { return mTemplates.begin(); }
|
||||
TemplateMap::const_iterator templatesEnd() { return mTemplates.end(); }
|
||||
|
||||
// test for existence
|
||||
bool templateExists(const std::string& name);
|
||||
// useful if you're reloading the file
|
||||
void clearTemplates(); // erase all templates
|
||||
|
||||
void forceResponse(const LLNotification::Params& params, S32 option);
|
||||
|
||||
void createDefaultChannels();
|
||||
|
||||
typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
|
||||
ChannelMap mChannels;
|
||||
|
||||
void addChannel(LLNotificationChannelPtr pChan);
|
||||
LLNotificationChannelPtr getChannel(const std::string& channelName);
|
||||
|
||||
std::string getGlobalString(const std::string& key) const;
|
||||
|
||||
private:
|
||||
// we're a singleton, so we don't have a public constructor
|
||||
LLNotifications();
|
||||
/*virtual*/ void initSingleton();
|
||||
|
||||
void loadPersistentNotifications();
|
||||
|
||||
bool expirationFilter(LLNotificationPtr pNotification);
|
||||
bool expirationHandler(const LLSD& payload);
|
||||
bool uniqueFilter(LLNotificationPtr pNotification);
|
||||
bool uniqueHandler(const LLSD& payload);
|
||||
bool failedUniquenessTest(const LLSD& payload);
|
||||
LLNotificationChannelPtr pHistoryChannel;
|
||||
LLNotificationChannelPtr pExpirationChannel;
|
||||
|
||||
// put your template in
|
||||
bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
|
||||
TemplateMap mTemplates;
|
||||
|
||||
std::string mFileName;
|
||||
|
||||
typedef std::map<std::string, LLXMLNodePtr> XMLTemplateMap;
|
||||
XMLTemplateMap mXmlTemplates;
|
||||
|
||||
LLNotificationMap mUniqueNotifications;
|
||||
|
||||
typedef std::map<std::string, std::string> GlobalStringMap;
|
||||
GlobalStringMap mGlobalStrings;
|
||||
};
|
||||
|
||||
|
||||
#endif//LL_LLNOTIFICATIONS_H
|
||||
|
||||
|
|
@ -58,8 +58,6 @@
|
|||
#include "llresizebar.h"
|
||||
#include "llcriticaldamp.h"
|
||||
|
||||
LLPanel::alert_queue_t LLPanel::sAlertQueue;
|
||||
|
||||
const S32 RESIZE_BAR_OVERLAP = 1;
|
||||
const S32 RESIZE_BAR_HEIGHT = 3;
|
||||
|
||||
|
|
@ -344,14 +342,14 @@ BOOL LLPanel::checkRequirements()
|
|||
{
|
||||
if (!mRequirementsError.empty())
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[COMPONENTS]"] = mRequirementsError;
|
||||
args["[FLOATER]"] = getName();
|
||||
LLSD args;
|
||||
args["COMPONENTS"] = mRequirementsError;
|
||||
args["FLOATER"] = getName();
|
||||
|
||||
llwarns << getName() << " failed requirements check on: \n"
|
||||
<< mRequirementsError << llendl;
|
||||
|
||||
alertXml(std::string("FailedRequirementsCheck"), args);
|
||||
|
||||
LLNotifications::instance().add(LLNotification::Params("FailedRequirementsCheck").payload(args));
|
||||
mRequirementsError.clear();
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -359,25 +357,6 @@ BOOL LLPanel::checkRequirements()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLPanel::alertXml(const std::string& label, LLStringUtil::format_map_t args)
|
||||
{
|
||||
sAlertQueue.push(LLAlertInfo(label,args));
|
||||
}
|
||||
|
||||
//static
|
||||
BOOL LLPanel::nextAlert(LLAlertInfo &alert)
|
||||
{
|
||||
if (!sAlertQueue.empty())
|
||||
{
|
||||
alert = sAlertQueue.front();
|
||||
sAlertQueue.pop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLPanel::setFocus(BOOL b)
|
||||
{
|
||||
if( b )
|
||||
|
|
@ -1039,9 +1018,9 @@ void LLPanel::childDisplayNotFound()
|
|||
mExpectedMembers.insert(*itor);
|
||||
}
|
||||
mNewExpectedMembers.clear();
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[CONTROLS]"] = msg;
|
||||
LLAlertDialog::showXml("FloaterNotFound", args);
|
||||
LLSD args;
|
||||
args["CONTROLS"] = msg;
|
||||
LLNotifications::instance().add("FloaterNotFound", args);
|
||||
}
|
||||
|
||||
void LLPanel::storeRectControl()
|
||||
|
|
@ -1065,6 +1044,8 @@ struct LLLayoutStack::LLEmbeddedPanel
|
|||
mAutoResize(auto_resize),
|
||||
mUserResize(user_resize),
|
||||
mOrientation(orientation),
|
||||
mCollapsed(FALSE),
|
||||
mCollapseAmt(0.f),
|
||||
mVisibleAmt(1.f) // default to fully visible
|
||||
{
|
||||
LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
|
||||
|
|
@ -1095,14 +1076,28 @@ struct LLLayoutStack::LLEmbeddedPanel
|
|||
mResizeBar = NULL;
|
||||
}
|
||||
|
||||
F32 getCollapseFactor()
|
||||
{
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
return mVisibleAmt * clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinWidth / (F32)mPanel->getRect().getWidth());
|
||||
}
|
||||
else
|
||||
{
|
||||
return mVisibleAmt * clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinHeight / (F32)mPanel->getRect().getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
LLPanel* mPanel;
|
||||
S32 mMinWidth;
|
||||
S32 mMinHeight;
|
||||
BOOL mAutoResize;
|
||||
BOOL mUserResize;
|
||||
BOOL mCollapsed;
|
||||
LLResizeBar* mResizeBar;
|
||||
eLayoutOrientation mOrientation;
|
||||
F32 mVisibleAmt;
|
||||
F32 mCollapseAmt;
|
||||
};
|
||||
|
||||
static LLRegisterWidget<LLLayoutStack> r2("layout_stack");
|
||||
|
|
@ -1123,28 +1118,27 @@ LLLayoutStack::~LLLayoutStack()
|
|||
void LLLayoutStack::draw()
|
||||
{
|
||||
updateLayout();
|
||||
|
||||
e_panel_list_t::iterator panel_it;
|
||||
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
|
||||
{
|
||||
e_panel_list_t::iterator panel_it;
|
||||
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
|
||||
// clip to layout rectangle, not bounding rectangle
|
||||
LLRect clip_rect = (*panel_it)->mPanel->getRect();
|
||||
// scale clipping rectangle by visible amount
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
// clip to layout rectangle, not bounding rectangle
|
||||
LLRect clip_rect = (*panel_it)->mPanel->getRect();
|
||||
// scale clipping rectangle by visible amount
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->mVisibleAmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->mVisibleAmt);
|
||||
}
|
||||
|
||||
LLPanel* panelp = (*panel_it)->mPanel;
|
||||
|
||||
LLLocalClipRect clip(clip_rect);
|
||||
// only force drawing invisible children if visible amount is non-zero
|
||||
drawChild(panelp, 0, 0, !clip_rect.isNull());
|
||||
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
|
||||
}
|
||||
|
||||
LLPanel* panelp = (*panel_it)->mPanel;
|
||||
|
||||
LLLocalClipRect clip(clip_rect);
|
||||
// only force drawing invisible children if visible amount is non-zero
|
||||
drawChild(panelp, 0, 0, !clip_rect.isNull());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1276,8 +1270,13 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
|
|||
return cur_width;
|
||||
}
|
||||
|
||||
void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index)
|
||||
void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index)
|
||||
{
|
||||
// panel starts off invisible (collapsed)
|
||||
if (animate == ANIMATE)
|
||||
{
|
||||
panel->setVisible(FALSE);
|
||||
}
|
||||
LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize, user_resize);
|
||||
|
||||
mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
|
||||
|
|
@ -1293,6 +1292,11 @@ void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL
|
|||
sendChildToFront(resize_barp);
|
||||
}
|
||||
|
||||
// start expanding panel animation
|
||||
if (animate == ANIMATE)
|
||||
{
|
||||
panel->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLayoutStack::removePanel(LLPanel* panel)
|
||||
|
|
@ -1300,6 +1304,14 @@ void LLLayoutStack::removePanel(LLPanel* panel)
|
|||
removeChild(panel);
|
||||
}
|
||||
|
||||
void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
|
||||
{
|
||||
LLEmbeddedPanel* panel_container = findEmbeddedPanel(panel);
|
||||
if (!panel_container) return;
|
||||
|
||||
panel_container->mCollapsed = collapsed;
|
||||
}
|
||||
|
||||
void LLLayoutStack::updateLayout(BOOL force_resize)
|
||||
{
|
||||
calcMinExtents();
|
||||
|
|
@ -1332,6 +1344,15 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
}
|
||||
}
|
||||
|
||||
if ((*panel_it)->mCollapsed)
|
||||
{
|
||||
(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
|
||||
}
|
||||
else
|
||||
{
|
||||
(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
|
||||
}
|
||||
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
// enforce minimize size constraint by default
|
||||
|
|
@ -1339,7 +1360,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
{
|
||||
panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
|
||||
}
|
||||
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
|
||||
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor());
|
||||
// want n-1 panel gaps for n panels
|
||||
if (panel_it != mPanels.begin())
|
||||
{
|
||||
|
|
@ -1353,7 +1374,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
{
|
||||
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
|
||||
}
|
||||
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
|
||||
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor());
|
||||
if (panel_it != mPanels.begin())
|
||||
{
|
||||
total_height += mPanelSpacing;
|
||||
|
|
@ -1367,7 +1388,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
|
||||
{
|
||||
// panels that are not fully visible do not count towards shrink headroom
|
||||
if ((*panel_it)->mVisibleAmt < 1.f)
|
||||
if ((*panel_it)->getCollapseFactor() < 1.f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1431,7 +1452,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
S32 delta_size = 0;
|
||||
|
||||
// if panel can automatically resize (not animating, and resize flag set)...
|
||||
if ((*panel_it)->mVisibleAmt == 1.f
|
||||
if ((*panel_it)->getCollapseFactor() == 1.f
|
||||
&& (force_resize || (*panel_it)->mAutoResize)
|
||||
&& !(*panel_it)->mResizeBar->hasMouseCapture())
|
||||
{
|
||||
|
|
@ -1515,11 +1536,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + mPanelSpacing;
|
||||
cur_x += llround(new_width * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
|
||||
}
|
||||
else //VERTICAL
|
||||
{
|
||||
cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + mPanelSpacing;
|
||||
cur_y -= llround(new_height * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,23 +49,13 @@ const BOOL BORDER_YES = TRUE;
|
|||
const BOOL BORDER_NO = FALSE;
|
||||
|
||||
|
||||
struct LLAlertInfo
|
||||
{
|
||||
std::string mLabel;
|
||||
LLStringUtil::format_map_t mArgs;
|
||||
|
||||
LLAlertInfo(std::string label, LLStringUtil::format_map_t args) : mLabel(label), mArgs(args) { }
|
||||
LLAlertInfo(){}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* General purpose concrete view base class.
|
||||
* Transparent or opaque,
|
||||
* With or without border,
|
||||
* Can contain LLUICtrls.
|
||||
*/
|
||||
class LLPanel : public LLUICtrl
|
||||
class LLPanel : public LLUICtrl, public boost::signals::trackable
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
@ -227,8 +217,6 @@ public:
|
|||
void childNotFound(const std::string& id) const;
|
||||
void childDisplayNotFound();
|
||||
|
||||
static void alertXml(const std::string& label, LLStringUtil::format_map_t args = LLStringUtil::format_map_t());
|
||||
static BOOL nextAlert(LLAlertInfo &alert);
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
protected:
|
||||
|
|
@ -266,8 +254,6 @@ private:
|
|||
|
||||
std::string mRequirementsError;
|
||||
|
||||
typedef std::queue<LLAlertInfo> alert_queue_t;
|
||||
static alert_queue_t sAlertQueue;
|
||||
}; // end class LLPanel
|
||||
|
||||
|
||||
|
|
@ -292,8 +278,16 @@ public:
|
|||
S32 getMinWidth() const { return mMinWidth; }
|
||||
S32 getMinHeight() const { return mMinHeight; }
|
||||
|
||||
void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX);
|
||||
typedef enum e_animate
|
||||
{
|
||||
NO_ANIMATE,
|
||||
ANIMATE
|
||||
} EAnimate;
|
||||
|
||||
void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate = NO_ANIMATE, S32 index = S32_MAX);
|
||||
void removePanel(LLPanel* panel);
|
||||
void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
|
||||
S32 getNumPanels() { return mPanels.size(); }
|
||||
|
||||
private:
|
||||
struct LLEmbeddedPanel;
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ LLScrollbar::LLScrollbar(
|
|||
}
|
||||
line_up_btn->setHeldDownCallback( &LLScrollbar::onLineUpBtnPressed );
|
||||
line_up_btn->setTabStop(FALSE);
|
||||
line_up_btn->setScaleImage(TRUE);
|
||||
|
||||
addChild(line_up_btn);
|
||||
|
||||
LLButton* line_down_btn = new LLButton(std::string("Line Down"), line_down_rect,
|
||||
|
|
@ -136,6 +138,7 @@ LLScrollbar::LLScrollbar(
|
|||
line_down_btn->setFollowsBottom();
|
||||
line_down_btn->setHeldDownCallback( &LLScrollbar::onLineDownBtnPressed );
|
||||
line_down_btn->setTabStop(FALSE);
|
||||
line_down_btn->setScaleImage(TRUE);
|
||||
addChild(line_down_btn);
|
||||
}
|
||||
|
||||
|
|
@ -148,20 +151,29 @@ LLScrollbar::~LLScrollbar()
|
|||
void LLScrollbar::setDocParams( S32 size, S32 pos )
|
||||
{
|
||||
mDocSize = size;
|
||||
mDocPos = llclamp( pos, 0, getDocPosMax() );
|
||||
setDocPos(pos);
|
||||
mDocChanged = TRUE;
|
||||
|
||||
updateThumbRect();
|
||||
}
|
||||
|
||||
void LLScrollbar::setDocPos(S32 pos)
|
||||
void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
|
||||
{
|
||||
pos = llclamp(pos, 0, getDocPosMax());
|
||||
if (pos != mDocPos)
|
||||
{
|
||||
mDocPos = llclamp( pos, 0, getDocPosMax() );
|
||||
mDocPos = pos;
|
||||
mDocChanged = TRUE;
|
||||
|
||||
updateThumbRect();
|
||||
if( mChangeCallback )
|
||||
{
|
||||
mChangeCallback( mDocPos, this, mCallbackUserData );
|
||||
}
|
||||
|
||||
if( update_thumb )
|
||||
{
|
||||
updateThumbRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +182,7 @@ void LLScrollbar::setDocSize(S32 size)
|
|||
if (size != mDocSize)
|
||||
{
|
||||
mDocSize = size;
|
||||
mDocPos = llclamp( mDocPos, 0, getDocPosMax() );
|
||||
setDocPos(mDocPos);
|
||||
mDocChanged = TRUE;
|
||||
|
||||
updateThumbRect();
|
||||
|
|
@ -182,7 +194,7 @@ void LLScrollbar::setPageSize( S32 page_size )
|
|||
if (page_size != mPageSize)
|
||||
{
|
||||
mPageSize = page_size;
|
||||
mDocPos = llclamp( mDocPos, 0, getDocPosMax() );
|
||||
setDocPos(mDocPos);
|
||||
mDocChanged = TRUE;
|
||||
|
||||
updateThumbRect();
|
||||
|
|
@ -208,9 +220,9 @@ void LLScrollbar::updateThumbRect()
|
|||
const S32 THUMB_MIN_LENGTH = 16;
|
||||
|
||||
S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
|
||||
S32 thumb_bg_length = window_length - 2 * SCROLLBAR_SIZE;
|
||||
S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE);
|
||||
S32 visible_lines = llmin( mDocSize, mPageSize );
|
||||
S32 thumb_length = mDocSize ? llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH ) : thumb_bg_length;
|
||||
S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
|
||||
|
||||
S32 variable_lines = mDocSize - visible_lines;
|
||||
|
||||
|
|
@ -218,7 +230,7 @@ void LLScrollbar::updateThumbRect()
|
|||
{
|
||||
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE;
|
||||
S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH;
|
||||
S32 thumb_start = variable_lines ? llclamp( thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min, thumb_start_max ) : thumb_start_max;
|
||||
S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
|
||||
|
||||
mThumbRect.mLeft = 0;
|
||||
mThumbRect.mTop = thumb_start;
|
||||
|
|
@ -230,7 +242,7 @@ void LLScrollbar::updateThumbRect()
|
|||
// Horizontal
|
||||
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length;
|
||||
S32 thumb_start_min = SCROLLBAR_SIZE;
|
||||
S32 thumb_start = variable_lines ? llclamp( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min, thumb_start_max ) : thumb_start_min;
|
||||
S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
|
||||
|
||||
mThumbRect.mLeft = thumb_start;
|
||||
mThumbRect.mTop = SCROLLBAR_SIZE;
|
||||
|
|
@ -446,7 +458,7 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Opaque, so don't just check children
|
||||
// Opaque, so don't just check children
|
||||
handled = LLView::handleMouseUp( x, y, mask );
|
||||
}
|
||||
|
||||
|
|
@ -455,13 +467,31 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
|
|||
|
||||
void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
if (width == getRect().getWidth() && height == getRect().getHeight()) return;
|
||||
LLView::reshape( width, height, called_from_parent );
|
||||
LLButton* up_button = getChild<LLButton>("Line Up");
|
||||
LLButton* down_button = getChild<LLButton>("Line Down");
|
||||
|
||||
if (mOrientation == VERTICAL)
|
||||
{
|
||||
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
|
||||
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
|
||||
up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
up_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), up_button->getRect().getHeight());
|
||||
down_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), down_button->getRect().getHeight());
|
||||
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
|
||||
}
|
||||
updateThumbRect();
|
||||
}
|
||||
|
||||
|
||||
void LLScrollbar::draw()
|
||||
{
|
||||
if (!getRect().isValid()) return;
|
||||
|
||||
S32 local_mouse_x;
|
||||
S32 local_mouse_y;
|
||||
LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
|
||||
|
|
@ -531,21 +561,7 @@ void LLScrollbar::draw()
|
|||
|
||||
void LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
|
||||
{
|
||||
S32 new_pos = llclamp( mDocPos + delta, 0, getDocPosMax() );
|
||||
if( new_pos != mDocPos )
|
||||
{
|
||||
mDocPos = new_pos;
|
||||
}
|
||||
|
||||
if( mChangeCallback )
|
||||
{
|
||||
mChangeCallback( mDocPos, this, mCallbackUserData );
|
||||
}
|
||||
|
||||
if( update_thumb )
|
||||
{
|
||||
updateThumbRect();
|
||||
}
|
||||
setDocPos(mDocPos + delta, update_thumb);
|
||||
}
|
||||
|
||||
void LLScrollbar::setValue(const LLSD& value)
|
||||
|
|
@ -561,22 +577,22 @@ BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask)
|
|||
switch( key )
|
||||
{
|
||||
case KEY_HOME:
|
||||
changeLine( -mDocPos, TRUE );
|
||||
setDocPos( 0 );
|
||||
handled = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_END:
|
||||
changeLine( getDocPosMax() - mDocPos, TRUE );
|
||||
setDocPos( getDocPosMax() );
|
||||
handled = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
changeLine( mStepSize, TRUE );
|
||||
setDocPos( getDocPos() + mStepSize );
|
||||
handled = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
changeLine( - mStepSize, TRUE );
|
||||
setDocPos( getDocPos() - mStepSize );
|
||||
handled = TRUE;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public:
|
|||
|
||||
// How many "lines" the "document" has scrolled.
|
||||
// 0 <= DocPos <= DocSize - DocVisibile
|
||||
void setDocPos( S32 pos );
|
||||
void setDocPos( S32 pos, BOOL update_thumb = TRUE );
|
||||
S32 getDocPos() const { return mDocPos; }
|
||||
|
||||
BOOL isAtBeginning();
|
||||
|
|
|
|||
|
|
@ -378,6 +378,22 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
|
|||
TRUE);
|
||||
}
|
||||
|
||||
LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible)
|
||||
: LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible),
|
||||
mDate(date)
|
||||
{
|
||||
}
|
||||
|
||||
void LLScrollListDate::setValue(const LLSD& value)
|
||||
{
|
||||
mDate = value.asDate();
|
||||
LLScrollListText::setValue(mDate.asRFC1123());
|
||||
}
|
||||
|
||||
const LLSD LLScrollListDate::getValue() const
|
||||
{
|
||||
return mDate;
|
||||
}
|
||||
|
||||
LLScrollListItem::~LLScrollListItem()
|
||||
{
|
||||
|
|
@ -578,6 +594,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
|
|||
mSearchColumn(0),
|
||||
mNumDynamicWidthColumns(0),
|
||||
mTotalStaticColumnWidth(0),
|
||||
mTotalColumnPadding(0),
|
||||
mSorted(TRUE),
|
||||
mDirty(FALSE),
|
||||
mOriginalSelection(-1),
|
||||
|
|
@ -627,6 +644,28 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
|
|||
mLastSelected = NULL;
|
||||
}
|
||||
|
||||
S32 LLScrollListCtrl::getSearchColumn()
|
||||
{
|
||||
// search for proper search column
|
||||
if (mSearchColumn < 0)
|
||||
{
|
||||
LLScrollListItem* itemp = getFirstData();
|
||||
if (itemp)
|
||||
{
|
||||
for(S32 column = 0; column < getNumColumns(); column++)
|
||||
{
|
||||
LLScrollListCell* cell = itemp->getColumn(column);
|
||||
if (cell && cell->isText())
|
||||
{
|
||||
mSearchColumn = column;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return llclamp(mSearchColumn, 0, getNumColumns());
|
||||
}
|
||||
|
||||
LLScrollListCtrl::~LLScrollListCtrl()
|
||||
{
|
||||
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
|
||||
|
|
@ -890,8 +929,8 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
|
|||
// *TODO: Use bookkeeping to make this an incramental cost with item additions
|
||||
void LLScrollListCtrl::calcColumnWidths()
|
||||
{
|
||||
const S32 HEADING_TEXT_PADDING = 30;
|
||||
const S32 COLUMN_TEXT_PADDING = 20;
|
||||
const S32 HEADING_TEXT_PADDING = 25;
|
||||
const S32 COLUMN_TEXT_PADDING = 10;
|
||||
|
||||
mMaxContentWidth = 0;
|
||||
|
||||
|
|
@ -904,20 +943,17 @@ void LLScrollListCtrl::calcColumnWidths()
|
|||
if (!column) continue;
|
||||
|
||||
// update column width
|
||||
S32 new_width = column->mWidth;
|
||||
S32 new_width = column->getWidth();
|
||||
if (column->mRelWidth >= 0)
|
||||
{
|
||||
new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth());
|
||||
}
|
||||
else if (column->mDynamicWidth)
|
||||
{
|
||||
new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns;
|
||||
new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
|
||||
}
|
||||
|
||||
if (new_width != column->mWidth)
|
||||
{
|
||||
column->mWidth = new_width;
|
||||
}
|
||||
column->setWidth(new_width);
|
||||
|
||||
// update max content width for this column, by looking at all items
|
||||
column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
|
||||
|
|
@ -971,28 +1007,13 @@ void LLScrollListCtrl::updateColumns()
|
|||
{
|
||||
calcColumnWidths();
|
||||
|
||||
// propagate column widths to individual cells
|
||||
item_list::iterator iter;
|
||||
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
|
||||
{
|
||||
LLScrollListItem *itemp = *iter;
|
||||
S32 num_cols = itemp->getNumColumns();
|
||||
S32 i = 0;
|
||||
for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
|
||||
{
|
||||
if (i >= (S32)mColumnsIndexed.size()) break;
|
||||
|
||||
cell->setWidth(mColumnsIndexed[i]->mWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// update column headers
|
||||
std::vector<LLScrollListColumn*>::iterator column_ordered_it;
|
||||
S32 left = mItemListRect.mLeft;
|
||||
LLColumnHeader* last_header = NULL;
|
||||
for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)
|
||||
{
|
||||
if ((*column_ordered_it)->mWidth < 0)
|
||||
if ((*column_ordered_it)->getWidth() < 0)
|
||||
{
|
||||
// skip hidden columns
|
||||
continue;
|
||||
|
|
@ -1001,9 +1022,11 @@ void LLScrollListCtrl::updateColumns()
|
|||
|
||||
if (column->mHeader)
|
||||
{
|
||||
column->mHeader->updateResizeBars();
|
||||
|
||||
last_header = column->mHeader;
|
||||
S32 top = mItemListRect.mTop;
|
||||
S32 right = left + column->mWidth;
|
||||
S32 right = left + column->getWidth();
|
||||
|
||||
if (column->mIndex != (S32)mColumnsIndexed.size()-1)
|
||||
{
|
||||
|
|
@ -1021,14 +1044,30 @@ void LLScrollListCtrl::updateColumns()
|
|||
}
|
||||
}
|
||||
|
||||
//FIXME: stretch the entire last column if it is resizable (gestures windows shows truncated text in last column)
|
||||
// expand last column header we encountered to full list width
|
||||
if (last_header)
|
||||
if (last_header && last_header->canResize())
|
||||
{
|
||||
S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft);
|
||||
last_header->reshape(new_width, last_header->getRect().getHeight());
|
||||
last_header->setVisible(mDisplayColumnHeaders && new_width > 0);
|
||||
last_header->getColumn()->setWidth(new_width);
|
||||
}
|
||||
|
||||
// propagate column widths to individual cells
|
||||
item_list::iterator iter;
|
||||
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
|
||||
{
|
||||
LLScrollListItem *itemp = *iter;
|
||||
S32 num_cols = itemp->getNumColumns();
|
||||
S32 i = 0;
|
||||
for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
|
||||
{
|
||||
if (i >= (S32)mColumnsIndexed.size()) break;
|
||||
|
||||
cell->setWidth(mColumnsIndexed[i]->getWidth());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::setDisplayHeading(BOOL display)
|
||||
|
|
@ -1490,7 +1529,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
|
|||
{
|
||||
LLScrollListItem* item = *iter;
|
||||
// Only select enabled items with matching names
|
||||
LLScrollListCell* cellp = item->getColumn(mSearchColumn);
|
||||
LLScrollListCell* cellp = item->getColumn(getSearchColumn());
|
||||
BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
|
||||
if (select)
|
||||
{
|
||||
|
|
@ -1513,7 +1552,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
|
|||
LLScrollListItem* item = *iter;
|
||||
|
||||
// Only select enabled items with matching names
|
||||
LLScrollListCell* cellp = item->getColumn(mSearchColumn);
|
||||
LLScrollListCell* cellp = item->getColumn(getSearchColumn());
|
||||
if (!cellp)
|
||||
{
|
||||
continue;
|
||||
|
|
@ -1743,6 +1782,8 @@ void LLScrollListCtrl::drawItems()
|
|||
|
||||
void LLScrollListCtrl::draw()
|
||||
{
|
||||
LLLocalClipRect clip(getLocalRect());
|
||||
|
||||
// if user specifies sort, make sure it is maintained
|
||||
if (needsSorting() && !isSorted())
|
||||
{
|
||||
|
|
@ -1816,7 +1857,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti
|
|||
S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
|
||||
S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));
|
||||
LLRect cell_rect;
|
||||
cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->mWidth, mLineHeight);
|
||||
cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
|
||||
// Convert rect local to screen coordinates
|
||||
localPointToScreen(
|
||||
cell_rect.mLeft, cell_rect.mBottom,
|
||||
|
|
@ -2113,7 +2154,7 @@ S32 LLScrollListCtrl::getColumnIndexFromOffset(S32 x)
|
|||
ordered_columns_t::const_iterator end = mColumnsIndexed.end();
|
||||
for ( ; iter != end; ++iter)
|
||||
{
|
||||
width = (*iter)->mWidth + mColumnPadding;
|
||||
width = (*iter)->getWidth() + mColumnPadding;
|
||||
right += width;
|
||||
if (left <= x && x < right )
|
||||
{
|
||||
|
|
@ -2140,7 +2181,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index)
|
|||
{
|
||||
return column_offset;
|
||||
}
|
||||
column_offset += (*iter)->mWidth + mColumnPadding;
|
||||
column_offset += (*iter)->getWidth() + mColumnPadding;
|
||||
}
|
||||
|
||||
// when running off the end, return the rightmost pixel
|
||||
|
|
@ -2292,7 +2333,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
|
|||
{
|
||||
if (getFirstSelected())
|
||||
{
|
||||
LLScrollListCell* cellp = getFirstSelected()->getColumn(mSearchColumn);
|
||||
LLScrollListCell* cellp = getFirstSelected()->getColumn(getSearchColumn());
|
||||
if (cellp)
|
||||
{
|
||||
cellp->highlightText(0, 0);
|
||||
|
|
@ -2379,7 +2420,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
|
|||
{
|
||||
LLScrollListItem* item = *iter;
|
||||
|
||||
LLScrollListCell* cellp = item->getColumn(mSearchColumn);
|
||||
LLScrollListCell* cellp = item->getColumn(getSearchColumn());
|
||||
if (cellp)
|
||||
{
|
||||
// Only select enabled items with matching first characters
|
||||
|
|
@ -2446,7 +2487,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
|
|||
{
|
||||
if (mLastSelected)
|
||||
{
|
||||
LLScrollListCell* cellp = mLastSelected->getColumn(mSearchColumn);
|
||||
LLScrollListCell* cellp = mLastSelected->getColumn(getSearchColumn());
|
||||
if (cellp)
|
||||
{
|
||||
cellp->highlightText(0, 0);
|
||||
|
|
@ -2474,7 +2515,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp)
|
|||
}
|
||||
|
||||
itemp->setSelected(FALSE);
|
||||
LLScrollListCell* cellp = itemp->getColumn(mSearchColumn);
|
||||
LLScrollListCell* cellp = itemp->getColumn(getSearchColumn());
|
||||
if (cellp)
|
||||
{
|
||||
cellp->highlightText(0, 0);
|
||||
|
|
@ -2501,9 +2542,14 @@ struct SameSortColumn
|
|||
bool operator()(std::pair<S32, BOOL> sort_column) { return sort_column.first == mColumn; }
|
||||
};
|
||||
|
||||
BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending)
|
||||
BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
|
||||
{
|
||||
sort_column_t new_sort_column(column, ascending);
|
||||
LLScrollListColumn* sort_column = getColumn(column_idx);
|
||||
if (!sort_column) return FALSE;
|
||||
|
||||
sort_column->mSortAscending = ascending;
|
||||
|
||||
sort_column_t new_sort_column(column_idx, ascending);
|
||||
|
||||
if (mSortColumns.empty())
|
||||
{
|
||||
|
|
@ -2517,7 +2563,7 @@ BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending)
|
|||
|
||||
// remove any existing sort criterion referencing this column
|
||||
// and add the new one
|
||||
mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column)), mSortColumns.end());
|
||||
mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column_idx)), mSortColumns.end());
|
||||
mSortColumns.push_back(new_sort_column);
|
||||
|
||||
// did the sort criteria change?
|
||||
|
|
@ -2643,6 +2689,12 @@ void LLScrollListCtrl::scrollToShowSelected()
|
|||
}
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width)
|
||||
{
|
||||
mTotalStaticColumnWidth += llmax(0, new_width) - llmax(0, col->getWidth());
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
|
||||
{
|
||||
|
|
@ -2689,7 +2741,7 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
|
|||
|
||||
child_node->createChild("name", TRUE)->setStringValue(column->mName);
|
||||
child_node->createChild("label", TRUE)->setStringValue(column->mLabel);
|
||||
child_node->createChild("width", TRUE)->setIntValue(column->mWidth);
|
||||
child_node->createChild("width", TRUE)->setIntValue(column->getWidth());
|
||||
}
|
||||
|
||||
return node;
|
||||
|
|
@ -2813,15 +2865,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
|||
|
||||
scroll_list->setSearchColumn(search_column);
|
||||
|
||||
if (sort_column >= 0)
|
||||
{
|
||||
scroll_list->sortByColumnIndex(sort_column, sort_ascending);
|
||||
}
|
||||
|
||||
LLSD columns;
|
||||
S32 index = 0;
|
||||
LLXMLNodePtr child;
|
||||
S32 total_static = 0;
|
||||
for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
|
||||
{
|
||||
if (child->hasName("column"))
|
||||
|
|
@ -2850,8 +2896,6 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
|||
std::string tooltip;
|
||||
child->getAttributeString("tool_tip", tooltip);
|
||||
|
||||
if(!columndynamicwidth) total_static += llmax(0, columnwidth);
|
||||
|
||||
F32 columnrelwidth = 0.f;
|
||||
child->getAttributeF32("relwidth", columnrelwidth);
|
||||
|
||||
|
|
@ -2872,9 +2916,13 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
|||
index++;
|
||||
}
|
||||
}
|
||||
scroll_list->setTotalStaticColumnWidth(total_static);
|
||||
scroll_list->setColumnHeadings(columns);
|
||||
|
||||
if (sort_column >= 0)
|
||||
{
|
||||
scroll_list->sortByColumnIndex(sort_column, sort_ascending);
|
||||
}
|
||||
|
||||
for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
|
||||
{
|
||||
if (child->hasName("row"))
|
||||
|
|
@ -3019,22 +3067,26 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
|
|||
if (mColumns.find(name) == mColumns.end())
|
||||
{
|
||||
// Add column
|
||||
mColumns[name] = LLScrollListColumn(column);
|
||||
mColumns[name] = LLScrollListColumn(column, this);
|
||||
LLScrollListColumn* new_column = &mColumns[name];
|
||||
new_column->mParentCtrl = this;
|
||||
new_column->mIndex = mColumns.size()-1;
|
||||
|
||||
// Add button
|
||||
if (new_column->mWidth > 0 || new_column->mRelWidth > 0 || new_column->mDynamicWidth)
|
||||
if (new_column->getWidth() > 0 || new_column->mRelWidth > 0 || new_column->mDynamicWidth)
|
||||
{
|
||||
if (getNumColumns() > 0)
|
||||
{
|
||||
mTotalColumnPadding += mColumnPadding;
|
||||
}
|
||||
if (new_column->mRelWidth >= 0)
|
||||
{
|
||||
new_column->mWidth = (S32)llround(new_column->mRelWidth*mItemListRect.getWidth());
|
||||
new_column->setWidth((S32)llround(new_column->mRelWidth*mItemListRect.getWidth()));
|
||||
}
|
||||
else if(new_column->mDynamicWidth)
|
||||
{
|
||||
mNumDynamicWidthColumns++;
|
||||
new_column->mWidth = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns;
|
||||
new_column->setWidth((mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns);
|
||||
}
|
||||
S32 top = mItemListRect.mTop;
|
||||
S32 left = mItemListRect.mLeft;
|
||||
|
|
@ -3043,14 +3095,14 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
|
|||
for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
|
||||
{
|
||||
if (itor->second.mIndex < new_column->mIndex &&
|
||||
itor->second.mWidth > 0)
|
||||
itor->second.getWidth() > 0)
|
||||
{
|
||||
left += itor->second.mWidth + mColumnPadding;
|
||||
left += itor->second.getWidth() + mColumnPadding;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string button_name = "btn_" + name;
|
||||
S32 right = left+new_column->mWidth;
|
||||
S32 right = left+new_column->getWidth();
|
||||
if (new_column->mIndex != (S32)mColumns.size()-1)
|
||||
{
|
||||
right += mColumnPadding;
|
||||
|
|
@ -3145,6 +3197,8 @@ void LLScrollListCtrl::clearColumns()
|
|||
}
|
||||
mColumns.clear();
|
||||
mSortColumns.clear();
|
||||
mTotalStaticColumnWidth = 0;
|
||||
mTotalColumnPadding = 0;
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label)
|
||||
|
|
@ -3244,7 +3298,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
|
|||
}
|
||||
|
||||
S32 index = columnp->mIndex;
|
||||
S32 width = columnp->mWidth;
|
||||
S32 width = columnp->getWidth();
|
||||
LLFontGL::HAlign font_alignment = columnp->mFontAlignment;
|
||||
LLColor4 fcolor = LLColor4::black;
|
||||
|
||||
|
|
@ -3301,6 +3355,19 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
|
|||
}
|
||||
new_item->setColumn(index, cell);
|
||||
}
|
||||
else if (type == "date")
|
||||
{
|
||||
LLScrollListDate* cell = new LLScrollListDate(value.asDate(), font, width, font_style, font_alignment);
|
||||
if (has_color)
|
||||
{
|
||||
cell->setColor(color);
|
||||
}
|
||||
new_item->setColumn(index, cell);
|
||||
if (columnp->mHeader && !value.asString().empty())
|
||||
{
|
||||
columnp->mHeader->setHasResizableElement(TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE);
|
||||
|
|
@ -3325,7 +3392,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
|
|||
if (new_item->getColumn(column_idx) == NULL)
|
||||
{
|
||||
LLScrollListColumn* column_ptr = &column_it->second;
|
||||
new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL));
|
||||
new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3469,6 +3536,7 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS
|
|||
mButton->setMouseDownCallback(onMouseDown);
|
||||
|
||||
mButton->setCallbackUserData(this);
|
||||
mButton->setToolTip(label);
|
||||
|
||||
mAscendingText = std::string("[LOW]...[HIGH](Ascending)"); // *TODO: Translate
|
||||
mDescendingText = std::string("[HIGH]...[LOW](Descending)"); // *TODO: Translate
|
||||
|
|
@ -3556,7 +3624,7 @@ void LLColumnHeader::onClick(void* user_data)
|
|||
|
||||
LLScrollListCtrl::onClickColumn(column);
|
||||
|
||||
// propage new sort order to sort order list
|
||||
// propagate new sort order to sort order list
|
||||
headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1);
|
||||
}
|
||||
|
||||
|
|
@ -3646,7 +3714,7 @@ void LLColumnHeader::showList()
|
|||
text_width = llmax(text_width, LLFontGL::sSansSerifSmall->getWidth(descending_string)) + 10;
|
||||
text_width = llmax(text_width, getRect().getWidth() - 30);
|
||||
|
||||
mList->getColumn(0)->mWidth = text_width;
|
||||
mList->getColumn(0)->setWidth(text_width);
|
||||
((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string);
|
||||
((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string);
|
||||
|
||||
|
|
@ -3688,7 +3756,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d
|
|||
llassert(snap_edge == SNAP_RIGHT);
|
||||
|
||||
// use higher snap threshold for column headers
|
||||
threshold = llmin(threshold, 15);
|
||||
threshold = llmin(threshold, 10);
|
||||
|
||||
LLRect snap_rect = getSnapRect();
|
||||
|
||||
|
|
@ -3727,47 +3795,48 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
|
|||
|
||||
if (delta_width != 0)
|
||||
{
|
||||
S32 remaining_width = delta_width;
|
||||
S32 remaining_width = -delta_width;
|
||||
S32 col;
|
||||
for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++)
|
||||
{
|
||||
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
|
||||
if (!columnp) break;
|
||||
if (!columnp) continue;
|
||||
|
||||
if (columnp->mHeader && columnp->mHeader->canResize())
|
||||
{
|
||||
// how many pixels in width can this column afford to give up?
|
||||
S32 resize_buffer_amt = llmax(0, columnp->mWidth - MIN_COLUMN_WIDTH);
|
||||
S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH);
|
||||
|
||||
// user shrinking column, need to add width to other columns
|
||||
if (delta_width < 0)
|
||||
{
|
||||
if (!columnp->mDynamicWidth && columnp->mWidth > 0)
|
||||
if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
|
||||
{
|
||||
// statically sized column, give all remaining width to this column
|
||||
columnp->mWidth -= remaining_width;
|
||||
columnp->setWidth(columnp->getWidth() + remaining_width);
|
||||
if (columnp->mRelWidth > 0.f)
|
||||
{
|
||||
columnp->mRelWidth = (F32)columnp->mWidth / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
|
||||
columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
|
||||
}
|
||||
// all padding went to this widget, we're done
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// user growing column, need to take width from other columns
|
||||
remaining_width -= resize_buffer_amt;
|
||||
remaining_width += resize_buffer_amt;
|
||||
|
||||
if (!columnp->mDynamicWidth && columnp->mWidth > 0)
|
||||
if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
|
||||
{
|
||||
columnp->mWidth -= llmin(columnp->mWidth - MIN_COLUMN_WIDTH, delta_width);
|
||||
columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width));
|
||||
if (columnp->mRelWidth > 0.f)
|
||||
{
|
||||
columnp->mRelWidth = (F32)columnp->mWidth / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
|
||||
columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
if (remaining_width <= 0)
|
||||
if (remaining_width >= 0)
|
||||
{
|
||||
// width sucked up from neighboring columns, done
|
||||
break;
|
||||
|
|
@ -3779,14 +3848,14 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
|
|||
// clamp resize amount to maximum that can be absorbed by other columns
|
||||
if (delta_width > 0)
|
||||
{
|
||||
delta_width -= llmax(remaining_width, 0);
|
||||
delta_width += llmin(remaining_width, 0);
|
||||
}
|
||||
|
||||
// propagate constrained delta_width to new width for this column
|
||||
new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding();
|
||||
|
||||
// use requested width
|
||||
mColumn->mWidth = new_width;
|
||||
mColumn->setWidth(new_width);
|
||||
|
||||
// update proportional spacing
|
||||
if (mColumn->mRelWidth > 0.f)
|
||||
|
|
@ -3804,36 +3873,40 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
|
|||
void LLColumnHeader::setHasResizableElement(BOOL resizable)
|
||||
{
|
||||
// for now, dynamically spaced columns can't be resized
|
||||
if (mColumn->mDynamicWidth) return;
|
||||
// if (mColumn->mDynamicWidth) return;
|
||||
|
||||
if (resizable != mHasResizableElement)
|
||||
if (mHasResizableElement != resizable)
|
||||
{
|
||||
mColumn->mParentCtrl->dirtyColumns();
|
||||
mHasResizableElement = resizable;
|
||||
}
|
||||
}
|
||||
|
||||
S32 num_resizable_columns = 0;
|
||||
S32 col;
|
||||
for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
|
||||
void LLColumnHeader::updateResizeBars()
|
||||
{
|
||||
S32 num_resizable_columns = 0;
|
||||
S32 col;
|
||||
for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
|
||||
{
|
||||
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
|
||||
if (columnp->mHeader && columnp->mHeader->canResize())
|
||||
{
|
||||
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
|
||||
if (columnp->mHeader && columnp->mHeader->canResize())
|
||||
{
|
||||
num_resizable_columns++;
|
||||
}
|
||||
num_resizable_columns++;
|
||||
}
|
||||
}
|
||||
|
||||
S32 num_resizers_enabled = 0;
|
||||
S32 num_resizers_enabled = 0;
|
||||
|
||||
// now enable/disable resize handles on resizable columns if we have at least two
|
||||
for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
|
||||
// now enable/disable resize handles on resizable columns if we have at least two
|
||||
for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
|
||||
{
|
||||
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
|
||||
if (!columnp->mHeader) continue;
|
||||
BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
|
||||
columnp->mHeader->enableResizeBar(enable);
|
||||
if (enable)
|
||||
{
|
||||
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
|
||||
if (!columnp->mHeader) continue;
|
||||
BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
|
||||
columnp->mHeader->enableResizeBar(enable);
|
||||
if (enable)
|
||||
{
|
||||
num_resizers_enabled++;
|
||||
}
|
||||
num_resizers_enabled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3841,7 +3914,7 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable)
|
|||
void LLColumnHeader::enableResizeBar(BOOL enable)
|
||||
{
|
||||
// for now, dynamically spaced columns can't be resized
|
||||
if (!mColumn->mDynamicWidth)
|
||||
//if (!mColumn->mDynamicWidth)
|
||||
{
|
||||
mResizeBar->setEnabled(enable);
|
||||
}
|
||||
|
|
@ -3851,3 +3924,78 @@ BOOL LLColumnHeader::canResize()
|
|||
{
|
||||
return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth);
|
||||
}
|
||||
|
||||
void LLScrollListColumn::setWidth(S32 width)
|
||||
{
|
||||
if (!mDynamicWidth && mRelWidth <= 0.f)
|
||||
{
|
||||
mParentCtrl->updateStaticColumnWidth(this, width);
|
||||
}
|
||||
mWidth = width;
|
||||
}
|
||||
|
||||
// Default constructor
|
||||
LLScrollListColumn::LLScrollListColumn() :
|
||||
mName(),
|
||||
mSortingColumn(),
|
||||
mSortAscending(TRUE),
|
||||
mLabel(),
|
||||
mWidth(-1),
|
||||
mRelWidth(-1.0),
|
||||
mDynamicWidth(FALSE),
|
||||
mMaxContentWidth(0),
|
||||
mIndex(-1),
|
||||
mParentCtrl(NULL),
|
||||
mHeader(NULL),
|
||||
mFontAlignment(LLFontGL::LEFT)
|
||||
{ }
|
||||
|
||||
LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) :
|
||||
mWidth(0),
|
||||
mIndex (-1),
|
||||
mParentCtrl(parent),
|
||||
mHeader(NULL),
|
||||
mMaxContentWidth(0),
|
||||
mDynamicWidth(FALSE),
|
||||
mRelWidth(-1.f)
|
||||
{
|
||||
mName = sd.get("name").asString();
|
||||
mSortingColumn = mName;
|
||||
if (sd.has("sort"))
|
||||
{
|
||||
mSortingColumn = sd.get("sort").asString();
|
||||
}
|
||||
mSortAscending = TRUE;
|
||||
if (sd.has("sort_ascending"))
|
||||
{
|
||||
mSortAscending = sd.get("sort_ascending").asBoolean();
|
||||
}
|
||||
mLabel = sd.get("label").asString();
|
||||
if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
|
||||
{
|
||||
mRelWidth = (F32)sd.get("relwidth").asReal();
|
||||
if (mRelWidth < 0) mRelWidth = 0;
|
||||
if (mRelWidth > 1) mRelWidth = 1;
|
||||
mDynamicWidth = FALSE;
|
||||
}
|
||||
else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
|
||||
{
|
||||
mDynamicWidth = TRUE;
|
||||
mRelWidth = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
setWidth(sd.get("width").asInteger());
|
||||
}
|
||||
|
||||
if (sd.has("halign"))
|
||||
{
|
||||
mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFontAlignment = LLFontGL::LEFT;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "llcombobox.h"
|
||||
#include "llscrollbar.h"
|
||||
#include "llresizebar.h"
|
||||
#include "lldate.h"
|
||||
|
||||
/*
|
||||
* Represents a cell in a scrollable table.
|
||||
|
|
@ -133,6 +134,18 @@ private:
|
|||
static U32 sCount;
|
||||
};
|
||||
|
||||
|
||||
class LLScrollListDate : public LLScrollListText
|
||||
{
|
||||
public:
|
||||
LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
|
||||
virtual void setValue(const LLSD& value);
|
||||
virtual const LLSD getValue() const;
|
||||
|
||||
private:
|
||||
LLDate mDate;
|
||||
};
|
||||
|
||||
/*
|
||||
* Cell displaying an image.
|
||||
*/
|
||||
|
|
@ -185,88 +198,11 @@ private:
|
|||
class LLScrollListColumn
|
||||
{
|
||||
public:
|
||||
// Default constructor
|
||||
LLScrollListColumn() :
|
||||
mName(),
|
||||
mSortingColumn(),
|
||||
mSortAscending(TRUE),
|
||||
mLabel(),
|
||||
mWidth(-1),
|
||||
mRelWidth(-1.0),
|
||||
mDynamicWidth(FALSE),
|
||||
mMaxContentWidth(0),
|
||||
mIndex(-1),
|
||||
mParentCtrl(NULL),
|
||||
mHeader(NULL),
|
||||
mFontAlignment(LLFontGL::LEFT)
|
||||
{ }
|
||||
LLScrollListColumn();
|
||||
LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
|
||||
|
||||
LLScrollListColumn(std::string name, std::string label, S32 width, F32 relwidth) :
|
||||
mName(name),
|
||||
mSortingColumn(name),
|
||||
mSortAscending(TRUE),
|
||||
mLabel(label),
|
||||
mWidth(width),
|
||||
mRelWidth(relwidth),
|
||||
mDynamicWidth(FALSE),
|
||||
mMaxContentWidth(0),
|
||||
mIndex(-1),
|
||||
mParentCtrl(NULL),
|
||||
mHeader(NULL),
|
||||
mFontAlignment(LLFontGL::LEFT)
|
||||
{ }
|
||||
|
||||
LLScrollListColumn(const LLSD &sd)
|
||||
{
|
||||
mMaxContentWidth = 0;
|
||||
|
||||
mName = sd.get("name").asString();
|
||||
mSortingColumn = mName;
|
||||
if (sd.has("sort"))
|
||||
{
|
||||
mSortingColumn = sd.get("sort").asString();
|
||||
}
|
||||
mSortAscending = TRUE;
|
||||
if (sd.has("sort_ascending"))
|
||||
{
|
||||
mSortAscending = sd.get("sort_ascending").asBoolean();
|
||||
}
|
||||
mLabel = sd.get("label").asString();
|
||||
if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
|
||||
{
|
||||
mRelWidth = (F32)sd.get("relwidth").asReal();
|
||||
if (mRelWidth < 0) mRelWidth = 0;
|
||||
if (mRelWidth > 1) mRelWidth = 1;
|
||||
mDynamicWidth = FALSE;
|
||||
mWidth = 0;
|
||||
}
|
||||
else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
|
||||
{
|
||||
mDynamicWidth = TRUE;
|
||||
mRelWidth = -1;
|
||||
mWidth = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mWidth = sd.get("width").asInteger();
|
||||
mDynamicWidth = FALSE;
|
||||
mRelWidth = -1;
|
||||
}
|
||||
|
||||
if (sd.has("halign"))
|
||||
{
|
||||
mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFontAlignment = LLFontGL::LEFT;
|
||||
}
|
||||
|
||||
mIndex = -1;
|
||||
mParentCtrl = NULL;
|
||||
mHeader = NULL;
|
||||
mFontAlignment = LLFontGL::LEFT;
|
||||
}
|
||||
void setWidth(S32 width);
|
||||
S32 getWidth() const { return mWidth; }
|
||||
|
||||
// Public data is fine so long as this remains a simple struct-like data class.
|
||||
// If it ever gets any smarter than that, these should all become private
|
||||
|
|
@ -275,7 +211,6 @@ public:
|
|||
std::string mSortingColumn;
|
||||
BOOL mSortAscending;
|
||||
std::string mLabel;
|
||||
S32 mWidth;
|
||||
F32 mRelWidth;
|
||||
BOOL mDynamicWidth;
|
||||
S32 mMaxContentWidth;
|
||||
|
|
@ -283,6 +218,10 @@ public:
|
|||
LLScrollListCtrl* mParentCtrl;
|
||||
class LLColumnHeader* mHeader;
|
||||
LLFontGL::HAlign mFontAlignment;
|
||||
|
||||
private:
|
||||
S32 mWidth;
|
||||
|
||||
};
|
||||
|
||||
class LLColumnHeader : public LLComboBox
|
||||
|
|
@ -301,6 +240,7 @@ public:
|
|||
void setImage(const std::string &image_name);
|
||||
LLScrollListColumn* getColumn() { return mColumn; }
|
||||
void setHasResizableElement(BOOL resizable);
|
||||
void updateResizeBars();
|
||||
BOOL canResize();
|
||||
void enableResizeBar(BOOL enable);
|
||||
std::string getLabel() { return mOrigLabel; }
|
||||
|
|
@ -551,8 +491,7 @@ public:
|
|||
|
||||
virtual S32 getScrollPos() const;
|
||||
virtual void setScrollPos( S32 pos );
|
||||
|
||||
S32 getSearchColumn() { return mSearchColumn; }
|
||||
S32 getSearchColumn();
|
||||
void setSearchColumn(S32 column) { mSearchColumn = column; }
|
||||
S32 getColumnIndexFromOffset(S32 x);
|
||||
S32 getColumnOffsetFromIndex(S32 index);
|
||||
|
|
@ -613,8 +552,9 @@ public:
|
|||
virtual void deselect();
|
||||
virtual BOOL canDeselect() const;
|
||||
|
||||
void setNumDynamicColumns(int num) { mNumDynamicWidthColumns = num; }
|
||||
void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; }
|
||||
void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; }
|
||||
void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width);
|
||||
S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; }
|
||||
|
||||
std::string getSortColumnName();
|
||||
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
|
||||
|
|
@ -719,6 +659,7 @@ private:
|
|||
S32 mSearchColumn;
|
||||
S32 mNumDynamicWidthColumns;
|
||||
S32 mTotalStaticColumnWidth;
|
||||
S32 mTotalColumnPadding;
|
||||
|
||||
BOOL mSorted;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
|
||||
// Utilities functions the user interface needs
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -65,6 +66,7 @@ std::map<std::string, std::string> gTranslation;
|
|||
std::list<std::string> gUntranslated;
|
||||
|
||||
LLControlGroup* LLUI::sConfigGroup = NULL;
|
||||
LLControlGroup* LLUI::sIgnoresGroup = NULL;
|
||||
LLControlGroup* LLUI::sColorsGroup = NULL;
|
||||
LLImageProviderInterface* LLUI::sImageProvider = NULL;
|
||||
LLUIAudioCallback LLUI::sAudioCallback = NULL;
|
||||
|
|
@ -90,7 +92,7 @@ void make_ui_sound(const char* namep)
|
|||
LLUUID uuid(LLUI::sConfigGroup->getString(name));
|
||||
if (uuid.isNull())
|
||||
{
|
||||
if ("00000000-0000-0000-0000-000000000000" == LLUI::sConfigGroup->getString(name))
|
||||
if (LLUI::sConfigGroup->getString(name) == LLUUID::null.asString())
|
||||
{
|
||||
if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle"))
|
||||
{
|
||||
|
|
@ -1552,6 +1554,7 @@ bool handleShowXUINamesChanged(const LLSD& newvalue)
|
|||
}
|
||||
|
||||
void LLUI::initClass(LLControlGroup* config,
|
||||
LLControlGroup* ignores,
|
||||
LLControlGroup* colors,
|
||||
LLImageProviderInterface* image_provider,
|
||||
LLUIAudioCallback audio_callback,
|
||||
|
|
@ -1559,7 +1562,16 @@ void LLUI::initClass(LLControlGroup* config,
|
|||
const std::string& language)
|
||||
{
|
||||
sConfigGroup = config;
|
||||
sIgnoresGroup = ignores;
|
||||
sColorsGroup = colors;
|
||||
|
||||
if (sConfigGroup == NULL
|
||||
|| sIgnoresGroup == NULL
|
||||
|| sColorsGroup == NULL)
|
||||
{
|
||||
llerrs << "Failure to initialize configuration groups" << llendl;
|
||||
}
|
||||
|
||||
sImageProvider = image_provider;
|
||||
sAudioCallback = audio_callback;
|
||||
sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
|
||||
|
|
@ -1567,7 +1579,7 @@ void LLUI::initClass(LLControlGroup* config,
|
|||
LLFontGL::sShadowColor = colors->getColor("ColorDropShadow");
|
||||
|
||||
LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames");
|
||||
LLUI::sConfigGroup->getControl("ShowXUINames")->getSignal()->connect(boost::bind(&handleShowXUINamesChanged, _1));
|
||||
LLUI::sConfigGroup->getControl("ShowXUINames")->getSignal()->connect(&handleShowXUINamesChanged);
|
||||
}
|
||||
|
||||
void LLUI::cleanupClass()
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llgl.h" // *TODO: break this dependency
|
||||
#include <stack>
|
||||
//#include "llimagegl.h"
|
||||
#include <boost/signal.hpp>
|
||||
|
||||
// LLUIFactory
|
||||
#include "llsd.h"
|
||||
|
|
@ -150,11 +151,13 @@ typedef void (*LLUIAudioCallback)(const LLUUID& uuid);
|
|||
|
||||
class LLUI
|
||||
{
|
||||
LOG_CLASS(LLUI);
|
||||
public:
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
static void initClass(LLControlGroup* config,
|
||||
LLControlGroup* ignores,
|
||||
LLControlGroup* colors,
|
||||
LLImageProviderInterface* image_provider,
|
||||
LLUIAudioCallback audio_callback = NULL,
|
||||
|
|
@ -190,6 +193,7 @@ public:
|
|||
// Data
|
||||
//
|
||||
static LLControlGroup* sConfigGroup;
|
||||
static LLControlGroup* sIgnoresGroup;
|
||||
static LLControlGroup* sColorsGroup;
|
||||
static LLImageProviderInterface* sImageProvider;
|
||||
static LLUIAudioCallback sAudioCallback;
|
||||
|
|
@ -597,4 +601,237 @@ public:
|
|||
virtual void cleanUp() = 0;
|
||||
};
|
||||
|
||||
// This mix-in class adds support for tracking all instances of the specificed class parameter T
|
||||
// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
|
||||
// If KEY is not provided, then instances are stored in a simple list
|
||||
template<typename T, typename KEY = T*>
|
||||
class LLInstanceTracker : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
typedef typename std::map<KEY, T*>::iterator instance_iter;
|
||||
typedef typename std::map<KEY, T*>::const_iterator instance_const_iter;
|
||||
|
||||
static T* getInstance(KEY k) { instance_iter found = sInstances.find(k); return (found == sInstances.end()) ? NULL : found->second; }
|
||||
|
||||
static instance_iter beginInstances() { return sInstances.begin(); }
|
||||
static instance_iter endInstances() { return sInstances.end(); }
|
||||
static S32 instanceCount() { return sInstances.size(); }
|
||||
protected:
|
||||
LLInstanceTracker(KEY key) { add(key); }
|
||||
virtual ~LLInstanceTracker() { remove(); }
|
||||
virtual void setKey(KEY key) { remove(); add(key); }
|
||||
virtual const KEY& getKey() const { return mKey; }
|
||||
|
||||
private:
|
||||
void add(KEY key)
|
||||
{
|
||||
mKey = key;
|
||||
sInstances[key] = static_cast<T*>(this);
|
||||
}
|
||||
void remove() { sInstances.erase(mKey); }
|
||||
|
||||
private:
|
||||
|
||||
KEY mKey;
|
||||
static std::map<KEY, T*> sInstances;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class LLInstanceTracker<T, T*> : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
typedef typename std::set<T*>::iterator instance_iter;
|
||||
typedef typename std::set<T*>::const_iterator instance_const_iter;
|
||||
|
||||
static instance_iter instancesBegin() { return sInstances.begin(); }
|
||||
static instance_iter instancesEnd() { return sInstances.end(); }
|
||||
static S32 instanceCount() { return sInstances.size(); }
|
||||
|
||||
protected:
|
||||
LLInstanceTracker() { sInstances.insert(static_cast<T*>(this)); }
|
||||
virtual ~LLInstanceTracker() { sInstances.erase(static_cast<T*>(this)); }
|
||||
|
||||
static std::set<T*> sInstances;
|
||||
};
|
||||
|
||||
template <typename T, typename KEY> std::map<KEY, T*> LLInstanceTracker<T, KEY>::sInstances;
|
||||
template <typename T> std::set<T*> LLInstanceTracker<T, T*>::sInstances;
|
||||
|
||||
class LLCallbackRegistry
|
||||
{
|
||||
public:
|
||||
typedef boost::signal<void()> callback_signal_t;
|
||||
|
||||
void registerCallback(const callback_signal_t::slot_type& slot)
|
||||
{
|
||||
mCallbacks.connect(slot);
|
||||
}
|
||||
|
||||
void fireCallbacks()
|
||||
{
|
||||
mCallbacks();
|
||||
}
|
||||
|
||||
private:
|
||||
callback_signal_t mCallbacks;
|
||||
};
|
||||
|
||||
class LLInitClassList :
|
||||
public LLCallbackRegistry,
|
||||
public LLSingleton<LLInitClassList>
|
||||
{
|
||||
friend class LLSingleton<LLInitClassList>;
|
||||
private:
|
||||
LLInitClassList() {}
|
||||
};
|
||||
|
||||
class LLDestroyClassList :
|
||||
public LLCallbackRegistry,
|
||||
public LLSingleton<LLDestroyClassList>
|
||||
{
|
||||
friend class LLSingleton<LLDestroyClassList>;
|
||||
private:
|
||||
LLDestroyClassList() {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class LLRegisterWith
|
||||
{
|
||||
public:
|
||||
LLRegisterWith(boost::function<void ()> func)
|
||||
{
|
||||
T::instance().registerCallback(func);
|
||||
}
|
||||
|
||||
// this avoids a MSVC bug where non-referenced static members are "optimized" away
|
||||
// even if their constructors have side effects
|
||||
void reference()
|
||||
{
|
||||
S32 dummy;
|
||||
dummy = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class LLInitClass
|
||||
{
|
||||
public:
|
||||
LLInitClass() { sRegister.reference(); }
|
||||
|
||||
static LLRegisterWith<LLInitClassList> sRegister;
|
||||
private:
|
||||
|
||||
static void initClass()
|
||||
{
|
||||
llerrs << "No static initClass() method defined for " << typeid(T).name() << llendl;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class LLDestroyClass
|
||||
{
|
||||
public:
|
||||
LLDestroyClass() { sRegister.reference(); }
|
||||
|
||||
static LLRegisterWith<LLDestroyClassList> sRegister;
|
||||
private:
|
||||
|
||||
static void destroyClass()
|
||||
{
|
||||
llerrs << "No static destroyClass() method defined for " << typeid(T).name() << llendl;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
|
||||
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
|
||||
|
||||
|
||||
template <typename DERIVED>
|
||||
class LLParamBlock
|
||||
{
|
||||
protected:
|
||||
LLParamBlock() { sBlock = (DERIVED*)this; }
|
||||
|
||||
typedef typename boost::add_const<DERIVED>::type Tconst;
|
||||
|
||||
template <typename T>
|
||||
class LLMandatoryParam
|
||||
{
|
||||
public:
|
||||
typedef typename boost::add_const<T>::type T_const;
|
||||
|
||||
LLMandatoryParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
|
||||
LLMandatoryParam(const LLMandatoryParam<T>& other) : mVal(other.mVal) {}
|
||||
|
||||
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
|
||||
operator T() const { return mVal; }
|
||||
T operator=(T_const set_value) { mVal = set_value; return mVal; }
|
||||
|
||||
private:
|
||||
T mVal;
|
||||
DERIVED* mBlock;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LLOptionalParam
|
||||
{
|
||||
public:
|
||||
typedef typename boost::add_const<T>::type T_const;
|
||||
|
||||
LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
|
||||
LLOptionalParam() : mBlock(sBlock) {}
|
||||
LLOptionalParam(const LLOptionalParam<T>& other) : mVal(other.mVal) {}
|
||||
|
||||
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
|
||||
operator T() const { return mVal; }
|
||||
T operator=(T_const set_value) { mVal = set_value; return mVal; }
|
||||
|
||||
private:
|
||||
T mVal;
|
||||
DERIVED* mBlock;
|
||||
};
|
||||
|
||||
// specialization that requires initialization for reference types
|
||||
template <typename T>
|
||||
class LLOptionalParam <T&>
|
||||
{
|
||||
public:
|
||||
typedef typename boost::add_const<T&>::type T_const;
|
||||
|
||||
LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
|
||||
LLOptionalParam(const LLOptionalParam<T&>& other) : mVal(other.mVal) {}
|
||||
|
||||
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
|
||||
operator T&() const { return mVal; }
|
||||
T& operator=(T_const set_value) { mVal = set_value; return mVal; }
|
||||
|
||||
private:
|
||||
T& mVal;
|
||||
DERIVED* mBlock;
|
||||
};
|
||||
|
||||
// specialization that initializes pointer params to NULL
|
||||
template<typename T>
|
||||
class LLOptionalParam<T*>
|
||||
{
|
||||
public:
|
||||
typedef typename boost::add_const<T*>::type T_const;
|
||||
|
||||
LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
|
||||
LLOptionalParam() : mVal((T*)NULL), mBlock(sBlock) {}
|
||||
LLOptionalParam(const LLOptionalParam<T*>& other) : mVal(other.mVal) {}
|
||||
|
||||
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
|
||||
operator T*() const { return mVal; }
|
||||
T* operator=(T_const set_value) { mVal = set_value; return mVal; }
|
||||
private:
|
||||
T* mVal;
|
||||
DERIVED* mBlock;
|
||||
};
|
||||
|
||||
static DERIVED* sBlock;
|
||||
};
|
||||
|
||||
template <typename T> T* LLParamBlock<T>::sBlock = NULL;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -475,10 +475,10 @@ BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only)
|
|||
return focusPrev(result);
|
||||
}
|
||||
|
||||
LLUICtrl* LLUICtrl::findRootMostFocusRoot() const
|
||||
LLUICtrl* LLUICtrl::findRootMostFocusRoot()
|
||||
{
|
||||
const LLUICtrl* focus_root = NULL;
|
||||
const LLUICtrl* next_view = this;
|
||||
LLUICtrl* focus_root = NULL;
|
||||
LLUICtrl* next_view = this;
|
||||
while(next_view)
|
||||
{
|
||||
if (next_view->isFocusRoot())
|
||||
|
|
@ -487,9 +487,8 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot() const
|
|||
}
|
||||
next_view = next_view->getParentUICtrl();
|
||||
}
|
||||
// since focus_root could be this, need to cast away const to return
|
||||
// a non-const result
|
||||
return const_cast<LLUICtrl*>(focus_root);
|
||||
|
||||
return focus_root;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
|
||||
|
||||
LLUICtrl* findRootMostFocusRoot() const;
|
||||
LLUICtrl* findRootMostFocusRoot();
|
||||
|
||||
class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public:
|
|||
static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
|
||||
|
||||
private:
|
||||
bool getLayeredXMLNodeImpl(const std::string &filename, LLXMLNodePtr& root);
|
||||
|
||||
typedef std::map<LLHandle<LLPanel>, std::string> built_panel_t;
|
||||
built_panel_t mBuiltPanels;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
#include "lluistring.h"
|
||||
#include "llsd.h"
|
||||
|
||||
const LLStringUtil::format_map_t LLUIString::sNullArgs;
|
||||
|
||||
|
|
@ -54,6 +55,18 @@ void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
|
|||
format();
|
||||
}
|
||||
|
||||
void LLUIString::setArgs(const LLSD& sd)
|
||||
{
|
||||
if (!sd.isMap()) return;
|
||||
for(LLSD::map_const_iterator sd_it = sd.beginMap();
|
||||
sd_it != sd.endMap();
|
||||
++sd_it)
|
||||
{
|
||||
setArg(sd_it->first, sd_it->second.asString());
|
||||
}
|
||||
format();
|
||||
}
|
||||
|
||||
void LLUIString::setArg(const std::string& key, const std::string& replacement)
|
||||
{
|
||||
mArgs[key] = replacement;
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@
|
|||
// llinfos << mMessage.getString() << llendl; // outputs "Welcome Steve to Second Life"
|
||||
// mMessage.setArg("[USERNAME]", "Joe");
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Welcome Joe to Second Life"
|
||||
// mMessage = "Recepción a la [SECONDLIFE] [USERNAME]"
|
||||
// mMessage = "Recepcin a la [SECONDLIFE] [USERNAME]"
|
||||
// mMessage.setArg("[SECONDLIFE]", "Segunda Vida");
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Recepción a la Segunda Vida Joe"
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Recepcin a la Segunda Vida Joe"
|
||||
|
||||
// Implementation Notes:
|
||||
// Attempting to have operator[](const std::string& s) return mArgs[s] fails because we have
|
||||
|
|
@ -71,6 +71,8 @@ public:
|
|||
LLUIString& operator=(const std::string& s) { assign(s); return *this; }
|
||||
|
||||
void setArgList(const LLStringUtil::format_map_t& args);
|
||||
void setArgs(const LLStringUtil::format_map_t& args) { setArgList(args); }
|
||||
void setArgs(const class LLSD& sd);
|
||||
void setArg(const std::string& key, const std::string& replacement);
|
||||
|
||||
const std::string& getString() const { return mResult; }
|
||||
|
|
|
|||
|
|
@ -1260,7 +1260,7 @@ void LLView::draw()
|
|||
{
|
||||
LLView *viewp = *child_iter;
|
||||
|
||||
if (viewp->getVisible() && viewp != focus_view)
|
||||
if (viewp->getVisible() && viewp != focus_view && viewp->getRect().isValid())
|
||||
{
|
||||
// Only draw views that are within the root view
|
||||
localRectToScreen(viewp->getRect(),&screenRect);
|
||||
|
|
@ -1357,7 +1357,8 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr
|
|||
{
|
||||
++sDepth;
|
||||
|
||||
if (childp->getVisible() || force_draw)
|
||||
if ((childp->getVisible() && childp->getRect().isValid())
|
||||
|| force_draw)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
LLUI::pushMatrix();
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ public:
|
|||
// did we find *something* with that name?
|
||||
if (child)
|
||||
{
|
||||
llwarns << "Found child named " << name << " but of wrong type" << llendl;
|
||||
llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T).name() << llendl;
|
||||
}
|
||||
if (create_if_missing)
|
||||
{
|
||||
|
|
@ -496,6 +496,11 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
template <class T> T& getChildRef(const std::string& name, BOOL recurse = TRUE) const
|
||||
{
|
||||
return *getChild<T>(name, recurse, TRUE);
|
||||
}
|
||||
|
||||
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
|
||||
|
||||
template <class T> T* createDummyWidget(const std::string& name) const
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ LLXMLNode::LLXMLNode() :
|
|||
mEncoding(ENCODING_DEFAULT),
|
||||
mParent(NULL),
|
||||
mChildren(NULL),
|
||||
mAttributes(),
|
||||
mPrev(NULL),
|
||||
mNext(NULL),
|
||||
mName(NULL),
|
||||
mValue(""),
|
||||
mDefault(NULL)
|
||||
|
|
@ -83,6 +86,9 @@ LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) :
|
|||
mEncoding(ENCODING_DEFAULT),
|
||||
mParent(NULL),
|
||||
mChildren(NULL),
|
||||
mAttributes(),
|
||||
mPrev(NULL),
|
||||
mNext(NULL),
|
||||
mValue(""),
|
||||
mDefault(NULL)
|
||||
{
|
||||
|
|
@ -101,17 +107,65 @@ LLXMLNode::LLXMLNode(LLStringTableEntry* name, BOOL is_attribute) :
|
|||
mEncoding(ENCODING_DEFAULT),
|
||||
mParent(NULL),
|
||||
mChildren(NULL),
|
||||
mAttributes(),
|
||||
mPrev(NULL),
|
||||
mNext(NULL),
|
||||
mName(name),
|
||||
mValue(""),
|
||||
mDefault(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// copy constructor (except for the children)
|
||||
LLXMLNode::LLXMLNode(const LLXMLNode& rhs) :
|
||||
mID(rhs.mID),
|
||||
mIsAttribute(rhs.mIsAttribute),
|
||||
mVersionMajor(rhs.mVersionMajor),
|
||||
mVersionMinor(rhs.mVersionMinor),
|
||||
mLength(rhs.mLength),
|
||||
mPrecision(rhs.mPrecision),
|
||||
mType(rhs.mType),
|
||||
mEncoding(rhs.mEncoding),
|
||||
mParent(NULL),
|
||||
mChildren(NULL),
|
||||
mAttributes(),
|
||||
mPrev(NULL),
|
||||
mNext(NULL),
|
||||
mName(rhs.mName),
|
||||
mValue(rhs.mValue),
|
||||
mDefault(rhs.mDefault)
|
||||
{
|
||||
}
|
||||
|
||||
// returns a new copy of this node and all its children
|
||||
LLXMLNodePtr LLXMLNode::deepCopy()
|
||||
{
|
||||
LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this));
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
for (LLXMLChildList::iterator iter = mChildren->map.begin();
|
||||
iter != mChildren->map.end(); ++iter)
|
||||
{
|
||||
newnode->addChild(iter->second->deepCopy());
|
||||
}
|
||||
}
|
||||
for (LLXMLAttribList::iterator iter = mAttributes.begin();
|
||||
iter != mAttributes.end(); ++iter)
|
||||
{
|
||||
newnode->addChild(iter->second->deepCopy());
|
||||
}
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLXMLNode::~LLXMLNode()
|
||||
{
|
||||
// Strictly speaking none of this should be required execept 'delete mChildren'...
|
||||
if (mChildren)
|
||||
// Sadly, that's only true if we hadn't had reference-counted smart pointers linked
|
||||
// in three different directions. This entire class is a frightening, hard-to-maintain
|
||||
// mess.
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
for (LLXMLChildList::iterator iter = mChildren->map.begin();
|
||||
iter != mChildren->map.end(); ++iter)
|
||||
|
|
@ -124,7 +178,7 @@ LLXMLNode::~LLXMLNode()
|
|||
mChildren->map.clear();
|
||||
mChildren->head = NULL;
|
||||
mChildren->tail = NULL;
|
||||
delete mChildren;
|
||||
mChildren = NULL;
|
||||
}
|
||||
for (LLXMLAttribList::iterator iter = mAttributes.begin();
|
||||
iter != mAttributes.end(); ++iter)
|
||||
|
|
@ -160,7 +214,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (mChildren)
|
||||
else if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName);
|
||||
while (children_itr != mChildren->map.end())
|
||||
|
|
@ -183,7 +237,6 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
|
|||
mChildren->map.erase(children_itr);
|
||||
if (mChildren->map.empty())
|
||||
{
|
||||
delete mChildren;
|
||||
mChildren = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
|
|
@ -201,7 +254,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void LLXMLNode::addChild(LLXMLNodePtr new_child)
|
||||
void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
|
||||
{
|
||||
if (new_child->mParent != NULL)
|
||||
{
|
||||
|
|
@ -219,7 +272,7 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!mChildren)
|
||||
if (mChildren.isNull())
|
||||
{
|
||||
mChildren = new LLXMLChildren();
|
||||
mChildren->head = new_child;
|
||||
|
|
@ -227,11 +280,33 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child)
|
|||
}
|
||||
mChildren->map.insert(std::make_pair(new_child->mName, new_child));
|
||||
|
||||
if (mChildren->tail != new_child)
|
||||
// if after_child is specified, it damn well better be in the list of children
|
||||
// for this node. I'm not going to assert that, because it would be expensive,
|
||||
// but don't specify that parameter if you didn't get the value for it from the
|
||||
// list of children of this node!
|
||||
if (after_child.isNull())
|
||||
{
|
||||
mChildren->tail->mNext = new_child;
|
||||
new_child->mPrev = mChildren->tail;
|
||||
mChildren->tail = new_child;
|
||||
if (mChildren->tail != new_child)
|
||||
{
|
||||
mChildren->tail->mNext = new_child;
|
||||
new_child->mPrev = mChildren->tail;
|
||||
mChildren->tail = new_child;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (after_child->mNext.notNull())
|
||||
{
|
||||
// if after_child was not the last item, fix up some pointers
|
||||
after_child->mNext->mPrev = new_child;
|
||||
new_child->mNext = after_child->mNext;
|
||||
}
|
||||
new_child->mPrev = after_child;
|
||||
after_child->mNext = new_child;
|
||||
if (mChildren->tail == after_child)
|
||||
{
|
||||
mChildren->tail = new_child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +368,7 @@ void LLXMLNode::updateDefault()
|
|||
}
|
||||
}
|
||||
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator children_itr;
|
||||
LLXMLChildList::const_iterator children_end = mChildren->map.end();
|
||||
|
|
@ -566,6 +641,24 @@ bool LLXMLNode::updateNode(
|
|||
}
|
||||
|
||||
|
||||
// static
|
||||
LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node)
|
||||
{
|
||||
if (!node || !update_node)
|
||||
{
|
||||
llwarns << "Node invalid" << llendl;
|
||||
return node;
|
||||
}
|
||||
|
||||
LLXMLNodePtr cloned_node = update_node->deepCopy();
|
||||
node->mParent->addChild(cloned_node, node); // add after node
|
||||
LLXMLNodePtr parent = node->mParent;
|
||||
parent->removeChild(node);
|
||||
parent->updateDefault();
|
||||
|
||||
return cloned_node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static
|
||||
|
|
@ -618,7 +711,7 @@ bool LLXMLNode::parseBuffer(
|
|||
{
|
||||
llwarns << "Error parsing xml error code: "
|
||||
<< XML_ErrorString(XML_GetErrorCode(my_parser))
|
||||
<< " on lne " << XML_GetCurrentLineNumber(my_parser)
|
||||
<< " on line " << XML_GetCurrentLineNumber(my_parser)
|
||||
<< llendl;
|
||||
}
|
||||
|
||||
|
|
@ -722,7 +815,7 @@ BOOL LLXMLNode::isFullyDefault()
|
|||
&& has_default_length
|
||||
&& has_default_attribute)
|
||||
{
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator children_itr;
|
||||
LLXMLChildList::const_iterator children_end = mChildren->map.end();
|
||||
|
|
@ -888,7 +981,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
|
|||
}
|
||||
}
|
||||
|
||||
if (!mChildren && mValue == "")
|
||||
if (mChildren.isNull() && mValue == "")
|
||||
{
|
||||
output_stream << " />\n";
|
||||
return;
|
||||
|
|
@ -896,7 +989,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
|
|||
else
|
||||
{
|
||||
output_stream << ">\n";
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
// stream non-attributes
|
||||
std::string next_indent = indent + "\t";
|
||||
|
|
@ -922,7 +1015,7 @@ void LLXMLNode::findName(const std::string& name, LLXMLNodeList &results)
|
|||
results.insert(std::make_pair(this->mName->mString, this));
|
||||
return;
|
||||
}
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator children_itr;
|
||||
LLXMLChildList::const_iterator children_end = mChildren->map.end();
|
||||
|
|
@ -941,7 +1034,7 @@ void LLXMLNode::findName(LLStringTableEntry* name, LLXMLNodeList &results)
|
|||
results.insert(std::make_pair(this->mName->mString, this));
|
||||
return;
|
||||
}
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator children_itr;
|
||||
LLXMLChildList::const_iterator children_end = mChildren->map.end();
|
||||
|
|
@ -960,7 +1053,7 @@ void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results)
|
|||
results.insert(std::make_pair(this->mName->mString, this));
|
||||
return;
|
||||
}
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator children_itr;
|
||||
LLXMLChildList::const_iterator children_end = mChildren->map.end();
|
||||
|
|
@ -974,11 +1067,11 @@ void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results)
|
|||
|
||||
void LLXMLNode::scrubToTree(LLXMLNode *tree)
|
||||
{
|
||||
if (!tree || !tree->mChildren)
|
||||
if (!tree || tree->mChildren.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
std::vector<LLXMLNodePtr> to_delete_list;
|
||||
LLXMLChildList::iterator itor = mChildren->map.begin();
|
||||
|
|
@ -1023,7 +1116,7 @@ bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_
|
|||
|
||||
bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
|
||||
{
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator child_itr = mChildren->map.find(name);
|
||||
if (child_itr != mChildren->map.end())
|
||||
|
|
@ -1047,7 +1140,7 @@ void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, BOOL use_
|
|||
|
||||
void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing) const
|
||||
{
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
LLXMLChildList::const_iterator child_itr = mChildren->map.find(name);
|
||||
if (child_itr != mChildren->map.end())
|
||||
|
|
@ -1071,6 +1164,25 @@ void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &child
|
|||
}
|
||||
}
|
||||
|
||||
// recursively walks the tree and returns all children at all nesting levels matching the name
|
||||
void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const
|
||||
{
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
for (LLXMLChildList::const_iterator child_itr = mChildren->map.begin();
|
||||
child_itr != mChildren->map.end(); ++child_itr)
|
||||
{
|
||||
LLXMLNodePtr child = (*child_itr).second;
|
||||
if (name == child->mName)
|
||||
{
|
||||
children.insert(std::make_pair(child->mName->mString, child));
|
||||
}
|
||||
// and check each child as well
|
||||
child->getDescendants(name, children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
|
||||
{
|
||||
return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing);
|
||||
|
|
@ -1111,6 +1223,23 @@ BOOL LLXMLNode::hasAttribute(const char* name )
|
|||
return getAttribute(name, node);
|
||||
}
|
||||
|
||||
// the structure of these getAttribute_ functions is ugly, but it's because the
|
||||
// underlying system is based on BOOL and LLString; if we change
|
||||
// so that they're based on more generic mechanisms, these will be
|
||||
// simplified.
|
||||
bool LLXMLNode::getAttribute_bool(const char* name, bool& value )
|
||||
{
|
||||
LLXMLNodePtr node;
|
||||
if (!getAttribute(name, node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BOOL temp;
|
||||
bool retval = node->getBoolValue(1, &temp);
|
||||
value = temp;
|
||||
return retval;
|
||||
}
|
||||
|
||||
BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value )
|
||||
{
|
||||
LLXMLNodePtr node;
|
||||
|
|
@ -2521,7 +2650,7 @@ void LLXMLNode::setName(LLStringTableEntry* name)
|
|||
|
||||
U32 LLXMLNode::getChildCount() const
|
||||
{
|
||||
if (mChildren)
|
||||
if (mChildren.notNull())
|
||||
{
|
||||
return mChildren->map.size();
|
||||
}
|
||||
|
|
@ -2540,7 +2669,7 @@ U32 get_rand(U32 max_value)
|
|||
|
||||
LLXMLNode *get_rand_node(LLXMLNode *node)
|
||||
{
|
||||
if (node->mChildren)
|
||||
if (node->mChildren.notNull())
|
||||
{
|
||||
U32 num_children = node->mChildren->map.size();
|
||||
if (get_rand(2) == 0)
|
||||
|
|
@ -2748,7 +2877,7 @@ void LLXMLNode::createUnitTest(S32 max_num_children)
|
|||
|
||||
BOOL LLXMLNode::performUnitTest(std::string &error_buffer)
|
||||
{
|
||||
if (!mChildren)
|
||||
if (mChildren.isNull())
|
||||
{
|
||||
error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString));
|
||||
return FALSE;
|
||||
|
|
@ -3007,14 +3136,14 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
LLXMLNodePtr LLXMLNode::getFirstChild()
|
||||
LLXMLNodePtr LLXMLNode::getFirstChild() const
|
||||
{
|
||||
if (!mChildren) return NULL;
|
||||
if (mChildren.isNull()) return NULL;
|
||||
LLXMLNodePtr ret = mChildren->head;
|
||||
return ret;
|
||||
}
|
||||
|
||||
LLXMLNodePtr LLXMLNode::getNextSibling()
|
||||
LLXMLNodePtr LLXMLNode::getNextSibling() const
|
||||
{
|
||||
LLXMLNodePtr ret = mNext;
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -87,12 +87,13 @@ class LLVector3d;
|
|||
class LLVector4;
|
||||
class LLVector4U;
|
||||
|
||||
struct LLXMLChildren
|
||||
struct LLXMLChildren : public LLThreadSafeRefCount
|
||||
{
|
||||
LLXMLChildList map; // Map of children names->pointers
|
||||
LLXMLNodePtr head; // Head of the double-linked list
|
||||
LLXMLNodePtr tail; // Tail of the double-linked list
|
||||
};
|
||||
typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr;
|
||||
|
||||
class LLXMLNode : public LLThreadSafeRefCount
|
||||
{
|
||||
|
|
@ -124,11 +125,13 @@ public:
|
|||
LLXMLNode();
|
||||
LLXMLNode(const char* name, BOOL is_attribute);
|
||||
LLXMLNode(LLStringTableEntry* name, BOOL is_attribute);
|
||||
LLXMLNode(const LLXMLNode& rhs);
|
||||
LLXMLNodePtr deepCopy();
|
||||
|
||||
BOOL isNull();
|
||||
|
||||
BOOL deleteChild(LLXMLNode* child);
|
||||
void addChild(LLXMLNodePtr new_parent);
|
||||
void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL));
|
||||
void setParent(LLXMLNodePtr new_parent); // reparent if necessary
|
||||
|
||||
// Serialization
|
||||
|
|
@ -146,8 +149,9 @@ public:
|
|||
LLXMLNodePtr& node,
|
||||
LLXMLNode* defaults);
|
||||
static bool updateNode(
|
||||
LLXMLNodePtr& node,
|
||||
LLXMLNodePtr& update_node);
|
||||
LLXMLNodePtr& node,
|
||||
LLXMLNodePtr& update_node);
|
||||
static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
|
||||
static void writeHeaderToFile(LLFILE *fOut);
|
||||
void writeToFile(LLFILE *fOut, const std::string& indent = std::string());
|
||||
void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string());
|
||||
|
|
@ -176,6 +180,10 @@ public:
|
|||
|
||||
BOOL hasAttribute(const char* name );
|
||||
|
||||
// these are designed to be more generic versions of the functions
|
||||
// rather than relying on LL-types
|
||||
bool getAttribute_bool(const char* name, bool& value );
|
||||
|
||||
BOOL getAttributeBOOL(const char* name, BOOL& value );
|
||||
BOOL getAttributeU8(const char* name, U8& value );
|
||||
BOOL getAttributeS8(const char* name, S8& value );
|
||||
|
|
@ -211,13 +219,16 @@ public:
|
|||
bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
|
||||
void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
|
||||
void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
|
||||
|
||||
// recursively finds all children at any level matching name
|
||||
void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const;
|
||||
|
||||
bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
|
||||
bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
|
||||
|
||||
// The following skip over attributes
|
||||
LLXMLNodePtr getFirstChild();
|
||||
LLXMLNodePtr getNextSibling();
|
||||
LLXMLNodePtr getFirstChild() const;
|
||||
LLXMLNodePtr getNextSibling() const;
|
||||
|
||||
LLXMLNodePtr getRoot();
|
||||
|
||||
|
|
@ -251,7 +262,6 @@ public:
|
|||
void setName(LLStringTableEntry* name);
|
||||
|
||||
// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
|
||||
// TomY TODO: Make this private
|
||||
static std::string escapeXML(const std::string& xml);
|
||||
|
||||
// Set the default node corresponding to this default node
|
||||
|
|
@ -291,7 +301,7 @@ public:
|
|||
Encoding mEncoding; // The value encoding
|
||||
|
||||
LLXMLNode* mParent; // The parent node
|
||||
LLXMLChildren* mChildren; // The child nodes
|
||||
LLXMLChildrenPtr mChildren; // The child nodes
|
||||
LLXMLAttribList mAttributes; // The attribute nodes
|
||||
LLXMLNodePtr mPrev; // Double-linked list previous node
|
||||
LLXMLNodePtr mNext; // Double-linked list next node
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloatermute.cpp
|
||||
llfloaternamedesc.cpp
|
||||
llfloaternewim.cpp
|
||||
llfloaternotificationsconsole.cpp
|
||||
llfloaterobjectiminfo.cpp
|
||||
llfloateropenobject.cpp
|
||||
llfloaterparcel.cpp
|
||||
|
|
@ -570,6 +571,7 @@ set(viewer_HEADER_FILES
|
|||
llfloatermute.h
|
||||
llfloaternamedesc.h
|
||||
llfloaternewim.h
|
||||
llfloaternotificationsconsole.h
|
||||
llfloaterobjectiminfo.h
|
||||
llfloateropenobject.h
|
||||
llfloaterparcel.h
|
||||
|
|
@ -1091,6 +1093,8 @@ set(viewer_XUI_FILES
|
|||
skins/default/xui/en-us/floater_name_description.xml
|
||||
skins/default/xui/en-us/floater_new_im.xml
|
||||
skins/default/xui/en-us/floater_new_outfit_dialog.xml
|
||||
skins/default/xui/en-us/floater_notifications_console.xml
|
||||
skins/default/xui/en-us/floater_notification.xml
|
||||
skins/default/xui/en-us/floater_object_im_info.xml
|
||||
skins/default/xui/en-us/floater_openobject.xml
|
||||
skins/default/xui/en-us/floater_pay_object.xml
|
||||
|
|
@ -1149,6 +1153,7 @@ set(viewer_XUI_FILES
|
|||
skins/default/xui/en-us/menu_slurl.xml
|
||||
skins/default/xui/en-us/menu_viewer.xml
|
||||
skins/default/xui/en-us/mime_types.xml
|
||||
skins/default/xui/en-us/notifications.xml
|
||||
skins/default/xui/en-us/notify.xml
|
||||
skins/default/xui/en-us/panel_audio_device.xml
|
||||
skins/default/xui/en-us/panel_audio.xml
|
||||
|
|
@ -1177,6 +1182,7 @@ set(viewer_XUI_FILES
|
|||
skins/default/xui/en-us/panel_media_controls.xml
|
||||
skins/default/xui/en-us/panel_media_remote_expanded.xml
|
||||
skins/default/xui/en-us/panel_media_remote.xml
|
||||
skins/default/xui/en-us/panel_notifications_channel.xml
|
||||
skins/default/xui/en-us/panel_overlaybar.xml
|
||||
skins/default/xui/en-us/panel_place_small.xml
|
||||
skins/default/xui/en-us/panel_place.xml
|
||||
|
|
|
|||
|
|
@ -55,6 +55,17 @@
|
|||
<real>1.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>AlertedUnsupportedHardware</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Set if there's unsupported hardware and we've already done a notification.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AllowIdleAFK</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ void LLAgent::onAppFocusGained()
|
|||
|
||||
void LLAgent::ageChat()
|
||||
{
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
// get amount of time since I last chatted
|
||||
F64 elapsed_time = (F64)mAvatarObject->mChatTimer.getElapsedTimeF32();
|
||||
|
|
@ -600,7 +600,7 @@ void LLAgent::unlockView()
|
|||
{
|
||||
if (getFocusOnAvatar())
|
||||
{
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
setFocusGlobal( LLVector3d::zero, mAvatarObject->mID );
|
||||
}
|
||||
|
|
@ -1017,7 +1017,7 @@ void LLAgent::sendReliableMessage()
|
|||
//-----------------------------------------------------------------------------
|
||||
LLVector3 LLAgent::getVelocity() const
|
||||
{
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
return mAvatarObject->getVelocity();
|
||||
}
|
||||
|
|
@ -1038,7 +1038,7 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
|
|||
llerrs << "setPositionAgent is not a number" << llendl;
|
||||
}
|
||||
|
||||
if (!mAvatarObject.isNull() && mAvatarObject->getParent())
|
||||
if (mAvatarObject.notNull() && mAvatarObject->getParent())
|
||||
{
|
||||
LLVector3 pos_agent_sitting;
|
||||
LLVector3d pos_agent_d;
|
||||
|
|
@ -1076,7 +1076,7 @@ void LLAgent::slamLookAt(const LLVector3 &look_at)
|
|||
//-----------------------------------------------------------------------------
|
||||
const LLVector3d &LLAgent::getPositionGlobal() const
|
||||
{
|
||||
if (!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull())
|
||||
if (mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
|
||||
{
|
||||
mPositionGlobal = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());
|
||||
}
|
||||
|
|
@ -1093,7 +1093,7 @@ const LLVector3d &LLAgent::getPositionGlobal() const
|
|||
//-----------------------------------------------------------------------------
|
||||
const LLVector3 &LLAgent::getPositionAgent()
|
||||
{
|
||||
if(!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull())
|
||||
if(mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
|
||||
{
|
||||
mFrameAgent.setOrigin(mAvatarObject->getRenderPosition());
|
||||
}
|
||||
|
|
@ -2345,11 +2345,11 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)
|
|||
if (user_cancel && !mAutoPilotBehaviorName.empty())
|
||||
{
|
||||
if (mAutoPilotBehaviorName == "Sit")
|
||||
LLNotifyBox::showXml("CancelledSit");
|
||||
LLNotifications::instance().add("CancelledSit");
|
||||
else if (mAutoPilotBehaviorName == "Attach")
|
||||
LLNotifyBox::showXml("CancelledAttach");
|
||||
LLNotifications::instance().add("CancelledAttach");
|
||||
else
|
||||
LLNotifyBox::showXml("Cancelled");
|
||||
LLNotifications::instance().add("Cancelled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2374,7 +2374,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
|
|||
mAutoPilotTargetGlobal = object->getPositionGlobal();
|
||||
}
|
||||
|
||||
if (!mAvatarObject)
|
||||
if (mAvatarObject.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -2455,7 +2455,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
|
|||
// If we're flying, handle autopilot points above or below you.
|
||||
if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE)
|
||||
{
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
F64 current_height = mAvatarObject->getPositionGlobal().mdV[VZ];
|
||||
F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height);
|
||||
|
|
@ -2540,7 +2540,7 @@ void LLAgent::propagate(const F32 dt)
|
|||
pitch(PITCH_RATE * (F32) mPitchKey * dt);
|
||||
|
||||
// handle auto-land behavior
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
BOOL in_air = mAvatarObject->mInAir;
|
||||
LLVector3 land_vel = getVelocity();
|
||||
|
|
@ -2591,7 +2591,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
|
|||
static LLVector3 last_at_axis;
|
||||
|
||||
|
||||
if ( mAvatarObject.isNull() )
|
||||
if (mAvatarObject.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -2864,7 +2864,7 @@ void LLAgent::endAnimationUpdateUI()
|
|||
}
|
||||
|
||||
// Disable mouselook-specific animations
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
|
||||
{
|
||||
|
|
@ -2910,7 +2910,7 @@ void LLAgent::endAnimationUpdateUI()
|
|||
gMorphView->setVisible( FALSE );
|
||||
}
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
if(mCustomAnim)
|
||||
{
|
||||
|
|
@ -2953,7 +2953,7 @@ void LLAgent::endAnimationUpdateUI()
|
|||
gIMMgr->setFloaterOpen( FALSE );
|
||||
gConsole->setVisible( TRUE );
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
// Trigger mouselook-specific animations
|
||||
if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_HOLD_ANIMS, NUM_AGENT_GUN_HOLD_ANIMS) )
|
||||
|
|
@ -3014,7 +3014,7 @@ void LLAgent::endAnimationUpdateUI()
|
|||
}
|
||||
|
||||
// freeze avatar
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
mPauseRequest = mAvatarObject->requestPause();
|
||||
}
|
||||
|
|
@ -3048,7 +3048,7 @@ void LLAgent::updateCamera()
|
|||
|
||||
validateFocusObject();
|
||||
|
||||
if (!mAvatarObject.isNull() &&
|
||||
if (mAvatarObject.notNull() &&
|
||||
mAvatarObject->mIsSitting &&
|
||||
camera_mode == CAMERA_MODE_MOUSELOOK)
|
||||
{
|
||||
|
|
@ -3162,7 +3162,7 @@ void LLAgent::updateCamera()
|
|||
//Ventrella
|
||||
if ( mCameraMode == CAMERA_MODE_FOLLOW )
|
||||
{
|
||||
if ( !mAvatarObject.isNull() )
|
||||
if ( mAvatarObject.notNull() )
|
||||
{
|
||||
//--------------------------------------------------------------------------------
|
||||
// this is where the avatar's position and rotation are given to followCam, and
|
||||
|
|
@ -3472,7 +3472,7 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal()
|
|||
{
|
||||
LLVector3d at_axis(1.0, 0.0, 0.0);
|
||||
LLQuaternion agent_rot = mFrameAgent.getQuaternion();
|
||||
if (!mAvatarObject.isNull() && mAvatarObject->getParent())
|
||||
if (mAvatarObject.notNull() && mAvatarObject->getParent())
|
||||
{
|
||||
LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
|
||||
if (!root_object->flagCameraDecoupled())
|
||||
|
|
@ -3770,7 +3770,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
camera_offset.setVec( local_camera_offset );
|
||||
camera_position_global = frame_center_global + head_offset + camera_offset;
|
||||
|
||||
if (!mAvatarObject.isNull())
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
LLVector3d camera_lag_d;
|
||||
F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
|
||||
|
|
@ -4001,7 +4001,7 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
|
|||
gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE);
|
||||
gSavedSettings.setBOOL("BuildBtnState", FALSE);
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
|
||||
mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
|
||||
|
|
@ -4089,7 +4089,7 @@ void LLAgent::changeCameraToFollow(BOOL animate)
|
|||
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
|
||||
}
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
|
||||
mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
|
||||
|
|
@ -4137,7 +4137,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
|
|||
|
||||
mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
if (!mAvatarObject->mIsSitting)
|
||||
{
|
||||
|
|
@ -4183,7 +4183,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
|
|||
}
|
||||
|
||||
// Remove any pitch from the avatar
|
||||
if (!mAvatarObject.isNull() && mAvatarObject->getParent())
|
||||
if (mAvatarObject.notNull() && mAvatarObject->getParent())
|
||||
{
|
||||
LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
|
||||
at_axis = LLViewerCamera::getInstance()->getAtAxis();
|
||||
|
|
@ -4262,7 +4262,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
|
|||
LLVOAvatar::onCustomizeStart();
|
||||
}
|
||||
|
||||
if (!mAvatarObject.isNull())
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
if(avatar_animate)
|
||||
{
|
||||
|
|
@ -4362,7 +4362,7 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
|
|||
{
|
||||
if (focus.isExactlyZero())
|
||||
{
|
||||
if (!mAvatarObject.isNull())
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
|
||||
}
|
||||
|
|
@ -4407,7 +4407,7 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
|
|||
{
|
||||
if (focus.isExactlyZero())
|
||||
{
|
||||
if (!mAvatarObject.isNull())
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
|
||||
}
|
||||
|
|
@ -4544,7 +4544,7 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
|
|||
if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
|
||||
{
|
||||
LLVector3 at_axis;
|
||||
if (!mAvatarObject.isNull() && mAvatarObject->getParent())
|
||||
if (mAvatarObject.notNull() && mAvatarObject->getParent())
|
||||
{
|
||||
LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
|
||||
at_axis = LLViewerCamera::getInstance()->getAtAxis();
|
||||
|
|
@ -4611,7 +4611,7 @@ void LLAgent::lookAtLastChat()
|
|||
if (chatter->isAvatar())
|
||||
{
|
||||
LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
|
||||
if (!mAvatarObject.isNull() && chatter_av->mHeadp)
|
||||
if (mAvatarObject.notNull() && chatter_av->mHeadp)
|
||||
{
|
||||
delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
|
||||
}
|
||||
|
|
@ -4692,7 +4692,7 @@ void LLAgent::setStartPosition( U32 location_id )
|
|||
LLVector3 agent_pos = getPositionAgent();
|
||||
LLVector3 agent_look_at = mFrameAgent.getAtAxis();
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
// the z height is at the agent's feet
|
||||
agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ];
|
||||
|
|
@ -4853,7 +4853,7 @@ void LLAgent::setTeen(bool teen)
|
|||
|
||||
void LLAgent::buildFullname(std::string& name) const
|
||||
{
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
name = mAvatarObject->getFullname();
|
||||
}
|
||||
|
|
@ -4871,7 +4871,7 @@ void LLAgent::buildFullnameAndTitle(std::string& name) const
|
|||
name.erase(0, name.length());
|
||||
}
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
name += mAvatarObject->getFullname();
|
||||
}
|
||||
|
|
@ -5226,7 +5226,7 @@ void LLAgent::getName(std::string& name)
|
|||
{
|
||||
name.clear();
|
||||
|
||||
if (mAvatarObject)
|
||||
if (mAvatarObject.notNull())
|
||||
{
|
||||
LLNameValue *first_nv = mAvatarObject->getNVPair("FirstName");
|
||||
LLNameValue *last_nv = mAvatarObject->getNVPair("LastName");
|
||||
|
|
@ -6726,7 +6726,7 @@ void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdat
|
|||
void LLAgent::recoverMissingWearable( EWearableType type )
|
||||
{
|
||||
// Try to recover by replacing missing wearable with a new one.
|
||||
LLNotifyBox::showXml("ReplacedMissingWearable");
|
||||
LLNotifications::instance().add("ReplacedMissingWearable");
|
||||
lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
|
||||
LLWearable* new_wearable = gWearableList.createNewWearable(type);
|
||||
|
||||
|
|
@ -7157,8 +7157,10 @@ void LLAgent::removeWearable( EWearableType type )
|
|||
{
|
||||
if( old_wearable->isDirty() )
|
||||
{
|
||||
LLSD payload;
|
||||
payload["wearable_type"] = (S32)type;
|
||||
// Bring up view-modal dialog: Save changes? Yes, No, Cancel
|
||||
gViewerWindow->alertXml("WearableSave", LLAgent::onRemoveWearableDialog, (void*)type );
|
||||
LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgent::onRemoveWearableDialog);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
|
@ -7169,9 +7171,10 @@ void LLAgent::removeWearable( EWearableType type )
|
|||
}
|
||||
|
||||
// static
|
||||
void LLAgent::onRemoveWearableDialog( S32 option, void* userdata )
|
||||
bool LLAgent::onRemoveWearableDialog(const LLSD& notification, const LLSD& response )
|
||||
{
|
||||
EWearableType type = (EWearableType)(intptr_t)userdata;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
|
||||
switch( option )
|
||||
{
|
||||
case 0: // "Save"
|
||||
|
|
@ -7190,6 +7193,7 @@ void LLAgent::onRemoveWearableDialog( S32 option, void* userdata )
|
|||
llassert(0);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
|
||||
|
|
@ -7388,8 +7392,9 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
|
|||
if( old_wearable->isDirty() )
|
||||
{
|
||||
// Bring up modal dialog: Save changes? Yes, No, Cancel
|
||||
gViewerWindow->alertXml( "WearableSave", LLAgent::onSetWearableDialog,
|
||||
new LLSetWearableData( new_item->getUUID(), new_wearable ));
|
||||
LLSD payload;
|
||||
payload["item_id"] = new_item->getUUID();
|
||||
LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgent::onSetWearableDialog, _1, _2, new_wearable));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -7398,25 +7403,25 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
|
|||
}
|
||||
|
||||
// static
|
||||
void LLAgent::onSetWearableDialog( S32 option, void* userdata )
|
||||
bool LLAgent::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable )
|
||||
{
|
||||
LLSetWearableData* data = (LLSetWearableData*)userdata;
|
||||
LLInventoryItem* new_item = gInventory.getItem( data->mNewItemID );
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID());
|
||||
if( !new_item )
|
||||
{
|
||||
delete data;
|
||||
return;
|
||||
delete wearable;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( option )
|
||||
{
|
||||
case 0: // "Save"
|
||||
gAgent.saveWearable( data->mNewWearable->getType() );
|
||||
gAgent.setWearableFinal( new_item, data->mNewWearable );
|
||||
gAgent.saveWearable( wearable->getType() );
|
||||
gAgent.setWearableFinal( new_item, wearable );
|
||||
break;
|
||||
|
||||
case 1: // "Don't Save"
|
||||
gAgent.setWearableFinal( new_item, data->mNewWearable );
|
||||
gAgent.setWearableFinal( new_item, wearable );
|
||||
break;
|
||||
|
||||
case 2: // "Cancel"
|
||||
|
|
@ -7427,7 +7432,8 @@ void LLAgent::onSetWearableDialog( S32 option, void* userdata )
|
|||
break;
|
||||
}
|
||||
|
||||
delete data;
|
||||
delete wearable;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called from setWearable() and onSetWearableDialog() to actually set the wearable.
|
||||
|
|
|
|||
|
|
@ -591,10 +591,8 @@ public:
|
|||
//--------------------------------------------------------------------
|
||||
// Wearables
|
||||
//--------------------------------------------------------------------
|
||||
BOOL getWearablesLoaded() const { return mWearablesLoaded; }
|
||||
|
||||
void setWearable( LLInventoryItem* new_item, LLWearable* wearable );
|
||||
static void onSetWearableDialog( S32 option, void* userdata );
|
||||
static bool onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable );
|
||||
void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable );
|
||||
void setWearableOutfit( const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove );
|
||||
void queryWearableCache();
|
||||
|
|
@ -624,7 +622,7 @@ public:
|
|||
void makeNewOutfitDone(S32 index);
|
||||
|
||||
void removeWearable( EWearableType type );
|
||||
static void onRemoveWearableDialog( S32 option, void* userdata );
|
||||
static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response );
|
||||
void removeWearableFinal( EWearableType type );
|
||||
|
||||
void sendAgentWearablesUpdate();
|
||||
|
|
|
|||
|
|
@ -652,6 +652,7 @@ bool LLAppViewer::init()
|
|||
|
||||
// Widget construction depends on LLUI being initialized
|
||||
LLUI::initClass(&gSavedSettings,
|
||||
&gSavedSettings,
|
||||
&gColors,
|
||||
LLUIImageList::getInstance(),
|
||||
ui_audio_callback,
|
||||
|
|
@ -663,7 +664,7 @@ bool LLAppViewer::init()
|
|||
&LLURLDispatcher::dispatchFromTextEditor);
|
||||
|
||||
LLUICtrlFactory::getInstance()->setupPaths(); // update paths with correct language set
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// Load settings files
|
||||
|
|
@ -736,7 +737,10 @@ bool LLAppViewer::init()
|
|||
//
|
||||
initWindow();
|
||||
|
||||
#if LL_LCD_COMPILE
|
||||
// call all self-registered classes
|
||||
LLInitClassList::instance().fireCallbacks();
|
||||
|
||||
#if LL_LCD_COMPILE
|
||||
// start up an LCD window on a logitech keyboard, if there is one
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
gLcdScreen = new LLLCD(hInstance);
|
||||
|
|
@ -762,64 +766,67 @@ bool LLAppViewer::init()
|
|||
// If we don't have the right GL requirements, exit.
|
||||
if (!gGLManager.mHasRequirements && !gNoRender)
|
||||
{
|
||||
// can't use an alert here since we're existing and
|
||||
// can't use an alert here since we're exiting and
|
||||
// all hell breaks lose.
|
||||
OSMessageBox(
|
||||
LLAlertDialog::getTemplateMessage("UnsupportedGLRequirements"),
|
||||
LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"),
|
||||
LLStringUtil::null,
|
||||
OSMB_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool unsupported = false;
|
||||
LLStringUtil::format_map_t args;
|
||||
std::string minSpecs;
|
||||
// alert the user if they are using unsupported hardware
|
||||
if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
|
||||
{
|
||||
bool unsupported = false;
|
||||
LLSD args;
|
||||
std::string minSpecs;
|
||||
|
||||
// get cpu data from xml
|
||||
std::stringstream minCPUString(LLAlertDialog::getTemplateMessage("UnsupportedCPUAmount"));
|
||||
S32 minCPU = 0;
|
||||
minCPUString >> minCPU;
|
||||
// get cpu data from xml
|
||||
std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount"));
|
||||
S32 minCPU = 0;
|
||||
minCPUString >> minCPU;
|
||||
|
||||
// get RAM data from XML
|
||||
std::stringstream minRAMString(LLAlertDialog::getTemplateMessage("UnsupportedRAMAmount"));
|
||||
U64 minRAM = 0;
|
||||
minRAMString >> minRAM;
|
||||
minRAM = minRAM * 1024 * 1024;
|
||||
// get RAM data from XML
|
||||
std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount"));
|
||||
U64 minRAM = 0;
|
||||
minRAMString >> minRAM;
|
||||
minRAM = minRAM * 1024 * 1024;
|
||||
|
||||
if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
|
||||
{
|
||||
minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedGPU");
|
||||
minSpecs += "\n";
|
||||
unsupported = true;
|
||||
}
|
||||
if(gSysCPU.getMhz() < minCPU)
|
||||
{
|
||||
minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedCPU");
|
||||
minSpecs += "\n";
|
||||
unsupported = true;
|
||||
}
|
||||
if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
|
||||
{
|
||||
minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedRAM");
|
||||
minSpecs += "\n";
|
||||
unsupported = true;
|
||||
}
|
||||
|
||||
if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
|
||||
{
|
||||
gViewerWindow->alertXml("UnknownGPU");
|
||||
}
|
||||
|
||||
if(unsupported)
|
||||
{
|
||||
if(!gSavedSettings.controlExists("WarnUnsupportedHardware")
|
||||
|| gSavedSettings.getBOOL("WarnUnsupportedHardware"))
|
||||
if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
|
||||
{
|
||||
args["MINSPECS"] = minSpecs;
|
||||
gViewerWindow->alertXml("UnsupportedHardware", args );
|
||||
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU");
|
||||
minSpecs += "\n";
|
||||
unsupported = true;
|
||||
}
|
||||
if(gSysCPU.getMhz() < minCPU)
|
||||
{
|
||||
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
|
||||
minSpecs += "\n";
|
||||
unsupported = true;
|
||||
}
|
||||
if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
|
||||
{
|
||||
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
|
||||
minSpecs += "\n";
|
||||
unsupported = true;
|
||||
}
|
||||
|
||||
if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
|
||||
{
|
||||
LLNotifications::instance().add("UnknownGPU");
|
||||
}
|
||||
|
||||
if(unsupported)
|
||||
{
|
||||
if(!gSavedSettings.controlExists("WarnUnsupportedHardware")
|
||||
|| gSavedSettings.getBOOL("WarnUnsupportedHardware"))
|
||||
{
|
||||
args["MINSPECS"] = minSpecs;
|
||||
LLNotifications::instance().add("UnsupportedHardware", args );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// save the graphics card
|
||||
|
|
@ -1153,8 +1160,6 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
|
||||
|
||||
LLNotifyBox::cleanup();
|
||||
|
||||
LLWorldMap::getInstance()->reset(); // release any images
|
||||
|
||||
llinfos << "Global stuff deleted" << llendflush;
|
||||
|
|
@ -1705,25 +1710,6 @@ bool LLAppViewer::initConfiguration()
|
|||
LLFirstUse::addConfigVariable("FirstVoice");
|
||||
LLFirstUse::addConfigVariable("FirstMedia");
|
||||
|
||||
//////
|
||||
// *FIX:Mani - Find a way to remove the gUICtrlFactory and
|
||||
// LLAlertDialog::parseAlerts dependecies on the being loaded
|
||||
// *before* the user settings. Having to do this init here
|
||||
// seems odd.
|
||||
|
||||
// This is where gUICtrlFactory used to be instantiated with a new LLUICtrlFactory
|
||||
// which needed to happen before calling parseAlerts below.
|
||||
// TODO: That method is still dependant upon the base LLUICtrlFactory constructor being called
|
||||
// which registers some callbacks so I'm leaving in a call to getInstance here to cause that to
|
||||
// still happen. This needs to be cleaned up later when the base and derived classes
|
||||
// are planned to be combined. -MG
|
||||
LLUICtrlFactory::getInstance();
|
||||
|
||||
|
||||
// Pre-load alerts.xml to define the warnings settings (always loads from skins/xui/en-us/)
|
||||
// Do this *before* loading the settings file
|
||||
LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE);
|
||||
|
||||
// - read command line settings.
|
||||
LLControlGroupCLP clp;
|
||||
std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
|
||||
|
|
@ -2151,8 +2137,6 @@ bool LLAppViewer::initWindow()
|
|||
|
||||
LLUI::sWindow = gViewerWindow->getWindow();
|
||||
|
||||
LLAlertDialog::parseAlerts("alerts.xml");
|
||||
LLNotifyBox::parseNotify("notify.xml");
|
||||
LLTrans::parseStrings("strings.xml");
|
||||
|
||||
// Show watch cursor
|
||||
|
|
@ -2614,32 +2598,34 @@ void LLAppViewer::requestQuit()
|
|||
mQuitRequested = true;
|
||||
}
|
||||
|
||||
static void finish_quit(S32 option, void *userdata)
|
||||
static bool finish_quit(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
if (option == 0)
|
||||
{
|
||||
LLAppViewer::instance()->requestQuit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_quit);
|
||||
|
||||
void LLAppViewer::userQuit()
|
||||
{
|
||||
gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL);
|
||||
LLNotifications::instance().add("ConfirmQuit");
|
||||
}
|
||||
|
||||
static void finish_early_exit(S32 option, void* userdata)
|
||||
static bool finish_early_exit(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLAppViewer::instance()->forceQuit();
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLAppViewer::earlyExit(const std::string& msg)
|
||||
void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
|
||||
{
|
||||
llwarns << "app_early_exit: " << msg << llendl;
|
||||
llwarns << "app_early_exit: " << name << llendl;
|
||||
gDoDisconnect = TRUE;
|
||||
// LLStringUtil::format_map_t args;
|
||||
// args["[MESSAGE]"] = mesg;
|
||||
// gViewerWindow->alertXml("AppEarlyExit", args, finish_early_exit);
|
||||
LLAlertDialog::showCritical(msg, finish_early_exit, NULL);
|
||||
LLNotifications::instance().add(name, substitutions, LLSD(), finish_early_exit);
|
||||
}
|
||||
|
||||
void LLAppViewer::forceExit(S32 arg)
|
||||
|
|
@ -2953,18 +2939,22 @@ const std::string& LLAppViewer::getWindowTitle() const
|
|||
}
|
||||
|
||||
// Callback from a dialog indicating user was logged out.
|
||||
void finish_disconnect(S32 option, void* userdata)
|
||||
bool finish_disconnect(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
if (1 == option)
|
||||
{
|
||||
LLAppViewer::instance()->forceQuit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Callback from an early disconnect dialog, force an exit
|
||||
void finish_forced_disconnect(S32 /* option */, void* /* userdata */)
|
||||
bool finish_forced_disconnect(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLAppViewer::instance()->forceQuit();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2984,19 +2974,19 @@ void LLAppViewer::forceDisconnect(const std::string& mesg)
|
|||
big_reason = mesg;
|
||||
}
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
gDoDisconnect = TRUE;
|
||||
|
||||
if (LLStartUp::getStartupState() < STATE_STARTED)
|
||||
{
|
||||
// Tell users what happened
|
||||
args["[ERROR_MESSAGE]"] = big_reason;
|
||||
gViewerWindow->alertXml("ErrorMessage", args, finish_forced_disconnect);
|
||||
args["ERROR_MESSAGE"] = big_reason;
|
||||
LLNotifications::instance().add("ErrorMessage", args, LLSD(), &finish_forced_disconnect);
|
||||
}
|
||||
else
|
||||
{
|
||||
args["[MESSAGE]"] = big_reason;
|
||||
gViewerWindow->alertXml("YouHaveBeenLoggedOut", args, finish_disconnect );
|
||||
args["MESSAGE"] = big_reason;
|
||||
LLNotifications::instance().add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3763,6 +3753,9 @@ void LLAppViewer::disconnectViewer()
|
|||
// Now we just ask the LLWorld singleton to cleanly shut down.
|
||||
LLWorld::getInstance()->destroyClass();
|
||||
|
||||
// call all self-registered classes
|
||||
LLDestroyClassList::instance().fireCallbacks();
|
||||
|
||||
cleanup_xfer_manager();
|
||||
gDisconnected = TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ public:
|
|||
void forceQuit(); // Puts the viewer into 'shutting down without error' mode.
|
||||
void requestQuit(); // Request a quit. A kinder, gentler quit.
|
||||
void userQuit(); // The users asks to quit. Confirm, then requestQuit()
|
||||
void earlyExit(const std::string& msg); // Display an error dialog and forcibly quit.
|
||||
void earlyExit(const std::string& name,
|
||||
const LLSD& substitutions = LLSD()); // Display an error dialog and forcibly quit.
|
||||
void forceExit(S32 arg); // exit() immediately (after some cleanup).
|
||||
void abortQuit(); // Called to abort a quit request.
|
||||
|
||||
|
|
|
|||
|
|
@ -102,21 +102,21 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
|
|||
{
|
||||
llinfos << "LLAssetUploadResponder::error " << statusNum
|
||||
<< " reason: " << reason << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
switch(statusNum)
|
||||
{
|
||||
case 400:
|
||||
args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["[REASON]"] = "Error in upload request. Please visit "
|
||||
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["REASON"] = "Error in upload request. Please visit "
|
||||
"http://secondlife.com/support for help fixing this problem.";
|
||||
gViewerWindow->alertXml("CannotUploadReason", args);
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
break;
|
||||
case 500:
|
||||
default:
|
||||
args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["[REASON]"] = "The server is experiencing unexpected "
|
||||
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["REASON"] = "The server is experiencing unexpected "
|
||||
"difficulties.";
|
||||
gViewerWindow->alertXml("CannotUploadReason", args);
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
break;
|
||||
}
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
|
|
@ -171,10 +171,10 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content)
|
|||
}
|
||||
else
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["[REASON]"] = content["message"].asString();
|
||||
gViewerWindow->alertXml("CannotUploadReason", args);
|
||||
LLSD args;
|
||||
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["REASON"] = content["message"].asString();
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,9 +220,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
|
|||
gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
|
||||
LLNotifyBox::showXml("UploadPayment", args);
|
||||
LLSD args;
|
||||
args["AMOUNT"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
|
||||
LLNotifications::instance().add("UploadPayment", args);
|
||||
}
|
||||
|
||||
// Actually add the upload to viewer inventory
|
||||
|
|
|
|||
|
|
@ -592,19 +592,19 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
|
|||
if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
|
||||
{
|
||||
std::string first, last;
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
if(gCacheName->getName(agent_id, first, last))
|
||||
{
|
||||
args["[FIRST_NAME]"] = first;
|
||||
args["[LAST_NAME]"] = last;
|
||||
args["FIRST_NAME"] = first;
|
||||
args["LAST_NAME"] = last;
|
||||
}
|
||||
if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)
|
||||
{
|
||||
gViewerWindow->alertXml("GrantedModifyRights",args);
|
||||
LLNotifications::instance().add("GrantedModifyRights",args);
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("RevokedModifyRights",args);
|
||||
LLNotifications::instance().add("RevokedModifyRights",args);
|
||||
}
|
||||
}
|
||||
(mBuddyInfo[agent_id])->setRightsFrom(new_rights);
|
||||
|
|
@ -638,7 +638,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
|
|||
tracking_id = mTrackingData->mAvatarID;
|
||||
}
|
||||
BOOL notify = FALSE;
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i);
|
||||
|
|
@ -652,8 +652,8 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
|
|||
if(gCacheName->getName(agent_id, first, last))
|
||||
{
|
||||
notify = TRUE;
|
||||
args["[FIRST]"] = first;
|
||||
args["[LAST]"] = last;
|
||||
args["FIRST"] = first;
|
||||
args["LAST"] = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -674,14 +674,14 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
|
|||
if(notify)
|
||||
{
|
||||
// Popup a notify box with online status of this agent
|
||||
LLNotifyBox::showXml(online ? "FriendOnline" : "FriendOffline", args);
|
||||
LLNotificationPtr notification = LLNotifications::instance().add(online ? "FriendOnline" : "FriendOffline", args);
|
||||
|
||||
// If there's an open IM session with this agent, send a notification there too.
|
||||
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id);
|
||||
LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
|
||||
if (floater)
|
||||
{
|
||||
LLUIString notifyMsg = LLNotifyBox::getTemplateMessage((online ? "FriendOnline" : "FriendOffline"),args);
|
||||
std::string notifyMsg = notification->getMessage();
|
||||
if (!notifyMsg.empty())
|
||||
floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -524,9 +524,9 @@ void LLFloaterCompileQueue::onSaveTextComplete(const LLUUID& asset_id, void* use
|
|||
if (status)
|
||||
{
|
||||
llwarns << "Unable to save text for script." << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("CompileQueueSaveText", args);
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotifications::instance().add("CompileQueueSaveText", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -545,9 +545,9 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void*
|
|||
else
|
||||
{
|
||||
llwarns << "Unable to save bytecode for script." << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("CompileQueueSaveBytecode", args);
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotifications::instance().add("CompileQueueSaveBytecode", args);
|
||||
}
|
||||
delete data;
|
||||
data = NULL;
|
||||
|
|
|
|||
|
|
@ -45,24 +45,22 @@ LLConfirmationManager::ListenerBase::~ListenerBase()
|
|||
}
|
||||
|
||||
|
||||
static void onConfirmAlert(S32 option, void* data)
|
||||
static bool onConfirmAlert(const LLSD& notification, const LLSD& response, LLConfirmationManager::ListenerBase* listener)
|
||||
{
|
||||
LLConfirmationManager::ListenerBase* listener
|
||||
= (LLConfirmationManager::ListenerBase*)data;
|
||||
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
listener->confirmed("");
|
||||
}
|
||||
|
||||
delete listener;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void onConfirmAlertPassword(
|
||||
S32 option, const std::string& text, void* data)
|
||||
static bool onConfirmAlertPassword(const LLSD& notification, const LLSD& response, LLConfirmationManager::ListenerBase* listener)
|
||||
{
|
||||
LLConfirmationManager::ListenerBase* listener
|
||||
= (LLConfirmationManager::ListenerBase*)data;
|
||||
std::string text = response["message"].asString();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
if (option == 0)
|
||||
{
|
||||
|
|
@ -70,6 +68,7 @@ static void onConfirmAlertPassword(
|
|||
}
|
||||
|
||||
delete listener;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -77,22 +76,17 @@ void LLConfirmationManager::confirm(Type type,
|
|||
const std::string& action,
|
||||
ListenerBase* listener)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[ACTION]"] = action;
|
||||
LLSD args;
|
||||
args["ACTION"] = action;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_CLICK:
|
||||
gViewerWindow->alertXml("ConfirmPurchase", args,
|
||||
onConfirmAlert, listener);
|
||||
LLNotifications::instance().add("ConfirmPurchase", args, LLSD(), boost::bind(onConfirmAlert, _1, _2, listener));
|
||||
break;
|
||||
|
||||
case TYPE_PASSWORD:
|
||||
gViewerWindow->alertXmlEditText("ConfirmPurchasePassword", args,
|
||||
NULL, NULL,
|
||||
onConfirmAlertPassword, listener,
|
||||
LLStringUtil::format_map_t(),
|
||||
TRUE);
|
||||
LLNotifications::instance().add("ConfirmPurchasePassword", args, LLSD(), boost::bind(onConfirmAlertPassword, _1, _2, listener));
|
||||
break;
|
||||
case TYPE_NONE:
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -98,18 +98,18 @@ void LLDelayedGestureError::onIdle(void *userdata)
|
|||
//static
|
||||
bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
LLInventoryItem *item = gInventory.getItem( ent.mItemID );
|
||||
|
||||
if ( item )
|
||||
{
|
||||
args["[NAME]"] = item->getName();
|
||||
args["NAME"] = item->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( uuid_ok || ent.mTimer.getElapsedTimeF32() > MAX_NAME_WAIT_TIME )
|
||||
{
|
||||
args["[NAME]"] = std::string( ent.mItemID.asString() );
|
||||
args["NAME"] = ent.mItemID.asString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -118,7 +118,7 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
|
|||
}
|
||||
|
||||
|
||||
LLNotifyBox::showXml(ent.mNotifyName, args);
|
||||
LLNotifications::instance().add(ent.mNotifyName, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ void LLEventNotifier::update()
|
|||
|
||||
if (np->getEventDate() < (alert_time))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = np->getEventName();
|
||||
args["[DATE]"] = np->getEventDateStr();
|
||||
LLNotifyBox::showXml("EventNotification", args,
|
||||
notifyCallback, np);
|
||||
LLSD args;
|
||||
args["NAME"] = np->getEventName();
|
||||
args["DATE"] = np->getEventDateStr();
|
||||
LLNotifications::instance().add("EventNotification", args, LLSD(),
|
||||
boost::bind(&LLEventNotification::handleResponse, np, _1, _2));
|
||||
mEventNotifications.erase(iter++);
|
||||
}
|
||||
else
|
||||
|
|
@ -173,38 +173,9 @@ void LLEventNotifier::remove(const U32 event_id)
|
|||
mEventNotifications.erase(iter);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLEventNotifier::notifyCallback(S32 option, void *user_data)
|
||||
{
|
||||
LLEventNotification *np = (LLEventNotification *)user_data;
|
||||
if (!np)
|
||||
{
|
||||
llwarns << "Event notification callback without data!" << llendl;
|
||||
return;
|
||||
}
|
||||
switch (option)
|
||||
{
|
||||
case 0:
|
||||
gAgent.teleportViaLocation(np->getEventPosGlobal());
|
||||
gFloaterWorldMap->trackLocation(np->getEventPosGlobal());
|
||||
break;
|
||||
case 1:
|
||||
gDisplayEventHack = TRUE;
|
||||
LLFloaterDirectory::showEvents(np->getEventID());
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
|
||||
// We could clean up the notification on the server now if we really wanted to.
|
||||
}
|
||||
|
||||
|
||||
|
||||
LLEventNotification::LLEventNotification() :
|
||||
mEventID(0),
|
||||
mEventName(""),
|
||||
mEventDate(0)
|
||||
mEventName("")
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +184,26 @@ LLEventNotification::~LLEventNotification()
|
|||
{
|
||||
}
|
||||
|
||||
bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
switch (option)
|
||||
{
|
||||
case 0:
|
||||
gAgent.teleportViaLocation(getEventPosGlobal());
|
||||
gFloaterWorldMap->trackLocation(getEventPosGlobal());
|
||||
break;
|
||||
case 1:
|
||||
gDisplayEventHack = TRUE;
|
||||
LLFloaterDirectory::showEvents(getEventID());
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
|
||||
// We could clean up the notification on the server now if we really wanted to.
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL LLEventNotification::load(const LLUserAuth::response_t &response)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ public:
|
|||
|
||||
typedef std::map<U32, LLEventNotification *> en_map;
|
||||
|
||||
static void notifyCallback(S32 option, void *user_data);
|
||||
protected:
|
||||
en_map mEventNotifications;
|
||||
LLFrameTimer mNotificationTimer;
|
||||
|
|
@ -78,6 +77,7 @@ public:
|
|||
time_t getEventDate() const { return mEventDate; }
|
||||
const std::string &getEventDateStr() const { return mEventDateStr; }
|
||||
LLVector3d getEventPosGlobal() const { return mEventPosGlobal; }
|
||||
bool handleResponse(const LLSD& notification, const LLSD& payload);
|
||||
protected:
|
||||
U32 mEventID; // EventID for this event
|
||||
std::string mEventName;
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ void LLFirstUse::useBalanceIncrease(S32 delta)
|
|||
{
|
||||
gSavedSettings.setWarning("FirstBalanceIncrease", FALSE);
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AMOUNT]"] = llformat("%d",delta);
|
||||
LLNotifyBox::showXml("FirstBalanceIncrease", args);
|
||||
LLSD args;
|
||||
args["AMOUNT"] = llformat("%d",delta);
|
||||
LLNotifications::instance().add("FirstBalanceIncrease", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,9 +99,9 @@ void LLFirstUse::useBalanceDecrease(S32 delta)
|
|||
{
|
||||
gSavedSettings.setWarning("FirstBalanceDecrease", FALSE);
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AMOUNT]"] = llformat("%d",-delta);
|
||||
LLNotifyBox::showXml("FirstBalanceDecrease", args);
|
||||
LLSD args;
|
||||
args["AMOUNT"] = llformat("%d",-delta);
|
||||
LLNotifications::instance().add("FirstBalanceDecrease", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,8 +114,8 @@ void LLFirstUse::useSit()
|
|||
//if (gSavedSettings.getWarning("FirstSit"))
|
||||
//{
|
||||
// gSavedSettings.setWarning("FirstSit", FALSE);
|
||||
|
||||
// LLNotifyBox::showXml("FirstSit");
|
||||
//
|
||||
// LLNotifications::instance().add("FirstSit");
|
||||
//}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ void LLFirstUse::useMap()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstMap", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstMap");
|
||||
LLNotifications::instance().add("FirstMap");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ void LLFirstUse::useBuild()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstBuild", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstBuild");
|
||||
LLNotifications::instance().add("FirstBuild");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ void LLFirstUse::useLeftClickNoHit()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstLeftClickNoHit", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstLeftClickNoHit");
|
||||
LLNotifications::instance().add("FirstLeftClickNoHit");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ void LLFirstUse::useTeleport()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstTeleport", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstTeleport");
|
||||
LLNotifications::instance().add("FirstTeleport");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -184,7 +184,7 @@ void LLFirstUse::useOverrideKeys()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstOverrideKeys", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstOverrideKeys");
|
||||
LLNotifications::instance().add("FirstOverrideKeys");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -202,7 +202,7 @@ void LLFirstUse::useAppearance()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstAppearance", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstAppearance");
|
||||
LLNotifications::instance().add("FirstAppearance");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ void LLFirstUse::useInventory()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstInventory", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstInventory");
|
||||
LLNotifications::instance().add("FirstInventory");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,10 +225,10 @@ void LLFirstUse::useSandbox()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstSandbox", FALSE);
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[HOURS]"] = llformat("%d",SANDBOX_CLEAN_FREQ);
|
||||
args["[TIME]"] = llformat("%d",SANDBOX_FIRST_CLEAN_HOUR);
|
||||
LLNotifyBox::showXml("FirstSandbox", args);
|
||||
LLSD args;
|
||||
args["HOURS"] = llformat("%d",SANDBOX_CLEAN_FREQ);
|
||||
args["TIME"] = llformat("%d",SANDBOX_FIRST_CLEAN_HOUR);
|
||||
LLNotifications::instance().add("FirstSandbox", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ void LLFirstUse::useFlexible()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstFlexible", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstFlexible");
|
||||
LLNotifications::instance().add("FirstFlexible");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -250,7 +250,7 @@ void LLFirstUse::useDebugMenus()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstDebugMenus", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstDebugMenus");
|
||||
LLNotifications::instance().add("FirstDebugMenus");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +261,7 @@ void LLFirstUse::useSculptedPrim()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstSculptedPrim", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstSculptedPrim");
|
||||
LLNotifications::instance().add("FirstSculptedPrim");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -273,6 +273,6 @@ void LLFirstUse::useMedia()
|
|||
{
|
||||
gSavedSettings.setWarning("FirstMedia", FALSE);
|
||||
|
||||
LLNotifyBox::showXml("FirstMedia");
|
||||
LLNotifications::instance().add("FirstMedia");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1001,7 +1001,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
|
|||
else
|
||||
{
|
||||
llwarns << "Failure writing animation data." << llendl;
|
||||
gViewerWindow->alertXml("WriteAnimationFail");
|
||||
LLNotifications::instance().add("WriteAnimationFail");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ void LLFloaterAuction::onClickOK(void* data)
|
|||
FALSE);
|
||||
self->getWindow()->incBusyCount();
|
||||
|
||||
LLNotifyBox::showXml("UploadingAuctionSnapshot");
|
||||
LLNotifications::instance().add("UploadingAuctionSnapshot");
|
||||
|
||||
}
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
|
@ -277,13 +277,13 @@ void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status
|
|||
|
||||
if (0 == status)
|
||||
{
|
||||
LLNotifyBox::showXml("UploadWebSnapshotDone");
|
||||
LLNotifications::instance().add("UploadWebSnapshotDone");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("UploadAuctionSnapshotFail", args);
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotifications::instance().add("UploadAuctionSnapshotFail", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -298,12 +298,12 @@ void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status
|
|||
|
||||
if (0 == status)
|
||||
{
|
||||
LLNotifyBox::showXml("UploadSnapshotDone");
|
||||
LLNotifications::instance().add("UploadSnapshotDone");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("UploadAuctionSnapshotFail", args);
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotifications::instance().add("UploadAuctionSnapshotFail", args);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
|
|||
|
||||
if (selection->getRootObjectCount() != 1)
|
||||
{
|
||||
gViewerWindow->alertXml("BuyOneObjectOnly");
|
||||
LLNotifications::instance().add("BuyOneObjectOnly");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
|
|||
BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
|
||||
if (!owners_identical)
|
||||
{
|
||||
gViewerWindow->alertXml("BuyObjectOneOwner");
|
||||
LLNotifications::instance().add("BuyObjectOneOwner");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
|||
|
||||
if (selection->getRootObjectCount() != 1)
|
||||
{
|
||||
gViewerWindow->alertXml("BuyContentsOneOnly");
|
||||
LLNotifications::instance().add("BuyContentsOneOnly");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
|||
BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
|
||||
if (!owners_identical)
|
||||
{
|
||||
gViewerWindow->alertXml("BuyContentsOneOwner");
|
||||
LLNotifications::instance().add("BuyContentsOneOwner");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ void LLFloaterBuyLand::buyLand(
|
|||
{
|
||||
if(is_for_group && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
|
||||
{
|
||||
gViewerWindow->alertXml("OnlyOfficerCanBuyLand");
|
||||
LLNotifications::instance().add("OnlyOfficerCanBuyLand");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -976,7 +976,7 @@ BOOL LLFloaterBuyLandUI::canClose()
|
|||
if (!can_close)
|
||||
{
|
||||
// explain to user why they can't do this, see DEV-9605
|
||||
gViewerWindow->alertXml("CannotCloseFloaterBuyLand");
|
||||
LLNotifications::instance().add("CannotCloseFloaterBuyLand");
|
||||
}
|
||||
return can_close;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,17 +98,9 @@ LLFloaterDayCycle::~LLFloaterDayCycle()
|
|||
void LLFloaterDayCycle::onClickHelp(void* data)
|
||||
{
|
||||
LLFloaterDayCycle* self = LLFloaterDayCycle::instance();
|
||||
const std::string* xml_alert = (std::string*)data;
|
||||
|
||||
LLAlertDialog* dialogp = gViewerWindow->alertXml(*xml_alert);
|
||||
if (dialogp)
|
||||
{
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(self);
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(dialogp);
|
||||
}
|
||||
}
|
||||
std::string xml_alert = *(std::string *) data;
|
||||
LLNotifications::instance().add(self->contextualNotification(xml_alert));
|
||||
}
|
||||
|
||||
void LLFloaterDayCycle::initHelpBtn(const std::string& name, const std::string& xml_alert)
|
||||
|
|
|
|||
|
|
@ -67,18 +67,8 @@ LLFloaterEnvSettings::~LLFloaterEnvSettings()
|
|||
|
||||
void LLFloaterEnvSettings::onClickHelp(void* data)
|
||||
{
|
||||
LLFloaterEnvSettings* self = static_cast<LLFloaterEnvSettings*>(data);
|
||||
|
||||
const char* xml_alert = "EnvSettingsHelpButton";
|
||||
LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert);
|
||||
if (dialogp)
|
||||
{
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(self);
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(dialogp);
|
||||
}
|
||||
}
|
||||
LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data;
|
||||
LLNotifications::instance().add(self->contextualNotification("EnvSettingsHelpButton"));
|
||||
}
|
||||
|
||||
void LLFloaterEnvSettings::initCallbacks(void)
|
||||
|
|
|
|||
|
|
@ -523,9 +523,9 @@ void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
|
|||
//static
|
||||
void LLPanelFriends::onMaximumSelect(void* user_data)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT);
|
||||
LLNotifyBox::showXml("MaxListSelectMessage", args);
|
||||
LLSD args;
|
||||
args["MAX_SELECT"] = llformat("%d", MAX_FRIEND_SELECT);
|
||||
LLNotifications::instance().add("MaxListSelectMessage", args);
|
||||
};
|
||||
|
||||
// static
|
||||
|
|
@ -585,27 +585,22 @@ void LLPanelFriends::requestFriendship(const LLUUID& target_id, const std::strin
|
|||
calling_card_folder_id);
|
||||
}
|
||||
|
||||
struct LLAddFriendData
|
||||
{
|
||||
LLUUID mID;
|
||||
std::string mName;
|
||||
};
|
||||
|
||||
// static
|
||||
void LLPanelFriends::callbackAddFriendWithMessage(S32 option, const std::string& text, void* data)
|
||||
bool LLPanelFriends::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLAddFriendData* add = (LLAddFriendData*)data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
requestFriendship(add->mID, add->mName, text);
|
||||
requestFriendship(notification["payload"]["id"].asUUID(),
|
||||
notification["payload"]["name"].asString(),
|
||||
response["message"].asString());
|
||||
}
|
||||
delete add;
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelFriends::callbackAddFriend(S32 option, void* data)
|
||||
bool LLPanelFriends::callbackAddFriend(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLAddFriendData* add = (LLAddFriendData*)data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
// Servers older than 1.25 require the text of the message to be the
|
||||
|
|
@ -613,9 +608,11 @@ void LLPanelFriends::callbackAddFriend(S32 option, void* data)
|
|||
LLUUID calling_card_folder_id =
|
||||
gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
|
||||
std::string message = calling_card_folder_id.asString();
|
||||
requestFriendship(add->mID, add->mName, message);
|
||||
requestFriendship(notification["payload"]["id"].asUUID(),
|
||||
notification["payload"]["name"].asString(),
|
||||
message);
|
||||
}
|
||||
delete add;
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -634,27 +631,25 @@ void LLPanelFriends::requestFriendshipDialog(const LLUUID& id,
|
|||
{
|
||||
if(id == gAgentID)
|
||||
{
|
||||
LLNotifyBox::showXml("AddSelfFriend");
|
||||
LLNotifications::instance().add("AddSelfFriend");
|
||||
return;
|
||||
}
|
||||
|
||||
LLAddFriendData* data = new LLAddFriendData();
|
||||
data->mID = id;
|
||||
data->mName = name;
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = name;
|
||||
|
||||
// Look for server versions like: Second Life Server 1.24.4.95600
|
||||
LLSD args;
|
||||
args["NAME"] = name;
|
||||
LLSD payload;
|
||||
payload["id"] = id;
|
||||
payload["name"] = name;
|
||||
// Look for server versions like: Second Life Server 1.24.4.95600
|
||||
if (gLastVersionChannel.find(" 1.24.") != std::string::npos)
|
||||
{
|
||||
// Old and busted server version, doesn't support friend
|
||||
// requests with messages.
|
||||
gViewerWindow->alertXml("AddFriend", args, callbackAddFriend, data);
|
||||
LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend);
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXmlEditText("AddFriendWithMessage", args, NULL, NULL, callbackAddFriendWithMessage, data);
|
||||
LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -677,7 +672,7 @@ void LLPanelFriends::onClickRemove(void* user_data)
|
|||
|
||||
//llinfos << "LLPanelFriends::onClickRemove()" << llendl;
|
||||
LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
if(ids.size() > 0)
|
||||
{
|
||||
std::string msgType = "RemoveFromFriends";
|
||||
|
|
@ -687,18 +682,27 @@ void LLPanelFriends::onClickRemove(void* user_data)
|
|||
std::string first, last;
|
||||
if(gCacheName->getName(agent_id, first, last))
|
||||
{
|
||||
args["[FIRST_NAME]"] = first;
|
||||
args["[LAST_NAME]"] = last;
|
||||
args["FIRST_NAME"] = first;
|
||||
args["LAST_NAME"] = last;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msgType = "RemoveMultipleFromFriends";
|
||||
}
|
||||
gViewerWindow->alertXml(msgType,
|
||||
LLSD payload;
|
||||
|
||||
for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
|
||||
it != ids.end();
|
||||
++it)
|
||||
{
|
||||
payload["ids"].append(*it);
|
||||
}
|
||||
|
||||
LLNotifications::instance().add(msgType,
|
||||
args,
|
||||
&handleRemove,
|
||||
(void*)new LLDynamicArray<LLUUID>(ids));
|
||||
payload,
|
||||
&handleRemove);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -730,13 +734,10 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command
|
|||
{
|
||||
if (ids.empty()) return;
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
if(ids.size() > 0)
|
||||
{
|
||||
// copy map of ids onto heap
|
||||
rights_map_t* rights = new rights_map_t(ids);
|
||||
// package with panel pointer
|
||||
std::pair<LLPanelFriends*, rights_map_t*>* user_data = new std::pair<LLPanelFriends*, rights_map_t*>(this, rights);
|
||||
rights_map_t* rights = new rights_map_t(ids);
|
||||
|
||||
// for single friend, show their name
|
||||
if(ids.size() == 1)
|
||||
|
|
@ -745,62 +746,65 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command
|
|||
std::string first, last;
|
||||
if(gCacheName->getName(agent_id, first, last))
|
||||
{
|
||||
args["[FIRST_NAME]"] = first;
|
||||
args["[LAST_NAME]"] = last;
|
||||
args["FIRST_NAME"] = first;
|
||||
args["LAST_NAME"] = last;
|
||||
}
|
||||
if (command == GRANT)
|
||||
{
|
||||
gViewerWindow->alertXml("GrantModifyRights", args, modifyRightsConfirmation, user_data);
|
||||
LLNotifications::instance().add("GrantModifyRights",
|
||||
args,
|
||||
LLSD(),
|
||||
boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("RevokeModifyRights", args, modifyRightsConfirmation, user_data);
|
||||
LLNotifications::instance().add("RevokeModifyRights",
|
||||
args,
|
||||
LLSD(),
|
||||
boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (command == GRANT)
|
||||
{
|
||||
gViewerWindow->alertXml("GrantModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
|
||||
LLNotifications::instance().add("GrantModifyRightsMultiple",
|
||||
args,
|
||||
LLSD(),
|
||||
boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("RevokeModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
|
||||
LLNotifications::instance().add("RevokeModifyRightsMultiple",
|
||||
args,
|
||||
LLSD(),
|
||||
boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelFriends::modifyRightsConfirmation(S32 option, void* user_data)
|
||||
bool LLPanelFriends::modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights)
|
||||
{
|
||||
std::pair<LLPanelFriends*, rights_map_t*>* data = (std::pair<LLPanelFriends*, rights_map_t*>*)user_data;
|
||||
LLPanelFriends* panelp = data->first;
|
||||
|
||||
if(panelp)
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if(0 == option)
|
||||
{
|
||||
if(0 == option)
|
||||
{
|
||||
panelp->sendRightsGrant(*(data->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to resync view with model, since user cancelled operation
|
||||
rights_map_t* rights = data->second;
|
||||
rights_map_t::iterator rights_it;
|
||||
for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it)
|
||||
{
|
||||
const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
|
||||
panelp->updateFriendItem(rights_it->first, info);
|
||||
// Might have changed the column the user is sorted on.
|
||||
panelp->mFriendsList->sortItems();
|
||||
}
|
||||
}
|
||||
panelp->refreshUI();
|
||||
sendRightsGrant(*rights);
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to resync view with model, since user cancelled operation
|
||||
rights_map_t::iterator rights_it;
|
||||
for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it)
|
||||
{
|
||||
const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
|
||||
updateFriendItem(rights_it->first, info);
|
||||
}
|
||||
}
|
||||
refreshUI();
|
||||
|
||||
delete data->second;
|
||||
delete data;
|
||||
delete rights;
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelFriends::applyRightsToFriends()
|
||||
|
|
@ -924,12 +928,14 @@ void LLPanelFriends::sendRightsGrant(rights_map_t& ids)
|
|||
|
||||
|
||||
// static
|
||||
void LLPanelFriends::handleRemove(S32 option, void* user_data)
|
||||
bool LLPanelFriends::handleRemove(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data);
|
||||
for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr)
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
const LLSD& ids = notification["payload"]["ids"];
|
||||
for(LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr)
|
||||
{
|
||||
LLUUID id = (*itr);
|
||||
LLUUID id = itr->asUUID();
|
||||
const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
|
||||
if(ip)
|
||||
{
|
||||
|
|
@ -955,5 +961,5 @@ void LLPanelFriends::handleRemove(S32 option, void* user_data)
|
|||
}
|
||||
|
||||
}
|
||||
delete ids;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ private:
|
|||
|
||||
// callback methods
|
||||
static void onSelectName(LLUICtrl* ctrl, void* user_data);
|
||||
static void callbackAddFriendWithMessage(S32 option, const std::string& text, void* user_data);
|
||||
static void callbackAddFriend(S32 option, void* user_data);
|
||||
static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
|
||||
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
|
||||
static void onPickAvatar(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data);
|
||||
static void onMaximumSelect(void* user_data);
|
||||
|
||||
|
|
@ -134,8 +134,8 @@ private:
|
|||
|
||||
static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data);
|
||||
|
||||
static void handleRemove(S32 option, void* user_data);
|
||||
static void modifyRightsConfirmation(S32 option, void* user_data);
|
||||
static bool handleRemove(const LLSD& notification, const LLSD& response);
|
||||
bool modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights);
|
||||
|
||||
private:
|
||||
// member data
|
||||
|
|
|
|||
|
|
@ -918,34 +918,31 @@ void LLPanelGridTools::refresh()
|
|||
// static
|
||||
void LLPanelGridTools::onClickKickAll(void* userdata)
|
||||
{
|
||||
LLPanelGridTools* self = (LLPanelGridTools*) userdata;
|
||||
|
||||
S32 left, top;
|
||||
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||
LLRect rect(left, top, left+400, top-300);
|
||||
|
||||
gViewerWindow->alertXmlEditText("KickAllUsers", LLStringUtil::format_map_t(),
|
||||
NULL, NULL,
|
||||
LLPanelGridTools::confirmKick, self);
|
||||
LLNotifications::instance().add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick);
|
||||
}
|
||||
|
||||
|
||||
void LLPanelGridTools::confirmKick(S32 option, const std::string& text, void* userdata)
|
||||
bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelGridTools* self = (LLPanelGridTools*) userdata;
|
||||
|
||||
if (option == 0)
|
||||
if (LLNotification::getSelectedOption(notification, response) == 0)
|
||||
{
|
||||
self->mKickMessage = text;
|
||||
gViewerWindow->alertXml("ConfirmKick",LLPanelGridTools::finishKick, self);
|
||||
LLSD payload;
|
||||
payload["kick_message"] = response["message"].asString();
|
||||
LLNotifications::instance().add("ConfirmKick", LLSD(), payload, LLPanelGridTools::finishKick);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLPanelGridTools::finishKick(S32 option, void* userdata)
|
||||
bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelGridTools* self = (LLPanelGridTools*) userdata;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
|
||||
if (option == 0)
|
||||
{
|
||||
|
|
@ -957,26 +954,24 @@ void LLPanelGridTools::finishKick(S32 option, void* userdata)
|
|||
msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
|
||||
msg->addUUIDFast(_PREHASH_AgentID, LL_UUID_ALL_AGENTS );
|
||||
msg->addU32("KickFlags", KICK_FLAGS_DEFAULT );
|
||||
msg->addStringFast(_PREHASH_Reason, self->mKickMessage );
|
||||
msg->addStringFast(_PREHASH_Reason, notification["payload"]["kick_message"].asString());
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data)
|
||||
{
|
||||
gViewerWindow->alertXml("FlushMapVisibilityCaches",
|
||||
flushMapVisibilityCachesConfirm, data);
|
||||
LLNotifications::instance().add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelGridTools::flushMapVisibilityCachesConfirm(S32 option, void* data)
|
||||
bool LLPanelGridTools::flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if (option != 0) return;
|
||||
|
||||
LLPanelGridTools* self = (LLPanelGridTools*)data;
|
||||
if (!self) return;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0) return false;
|
||||
|
||||
// HACK: Send this as an EstateOwnerRequest so it gets routed
|
||||
// correctly by the spaceserver. JC
|
||||
|
|
@ -992,6 +987,7 @@ void LLPanelGridTools::flushMapVisibilityCachesConfirm(S32 option, void* data)
|
|||
msg->nextBlock("ParamList");
|
||||
msg->addString("Parameter", gAgent.getID().asString());
|
||||
gAgent.sendReliableMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1182,13 +1178,16 @@ void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata)
|
|||
panelp->mSimWideDeletesFlags =
|
||||
SWD_SCRIPTED_ONLY | SWD_OTHERS_LAND_ONLY;
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AVATAR_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD args;
|
||||
args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD payload;
|
||||
payload["avatar_id"] = panelp->mTargetAvatar;
|
||||
payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
|
||||
|
||||
gViewerWindow->alertXml( "GodDeleteAllScriptedPublicObjectsByUser",
|
||||
LLNotifications::instance().add( "GodDeleteAllScriptedPublicObjectsByUser",
|
||||
args,
|
||||
callbackSimWideDeletes,
|
||||
userdata);
|
||||
payload,
|
||||
callbackSimWideDeletes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1201,13 +1200,16 @@ void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata)
|
|||
{
|
||||
panelp->mSimWideDeletesFlags = SWD_SCRIPTED_ONLY;
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AVATAR_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD args;
|
||||
args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD payload;
|
||||
payload["avatar_id"] = panelp->mTargetAvatar;
|
||||
payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
|
||||
|
||||
gViewerWindow->alertXml( "GodDeleteAllScriptedObjectsByUser",
|
||||
LLNotifications::instance().add( "GodDeleteAllScriptedObjectsByUser",
|
||||
args,
|
||||
callbackSimWideDeletes,
|
||||
userdata);
|
||||
payload,
|
||||
callbackSimWideDeletes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1220,28 +1222,32 @@ void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata)
|
|||
{
|
||||
panelp->mSimWideDeletesFlags = 0;
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AVATAR_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD args;
|
||||
args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD payload;
|
||||
payload["avatar_id"] = panelp->mTargetAvatar;
|
||||
payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
|
||||
|
||||
gViewerWindow->alertXml( "GodDeleteAllObjectsByUser",
|
||||
LLNotifications::instance().add( "GodDeleteAllObjectsByUser",
|
||||
args,
|
||||
callbackSimWideDeletes,
|
||||
userdata);
|
||||
payload,
|
||||
callbackSimWideDeletes);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelObjectTools::callbackSimWideDeletes( S32 option, void* userdata )
|
||||
bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const LLSD& response )
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata;
|
||||
if (!object_tools->mTargetAvatar.isNull())
|
||||
if (!notification["payload"]["avatar_id"].asUUID().isNull())
|
||||
{
|
||||
send_sim_wide_deletes(object_tools->mTargetAvatar,
|
||||
object_tools->mSimWideDeletesFlags);
|
||||
send_sim_wide_deletes(notification["payload"]["avatar_id"].asUUID(),
|
||||
notification["payload"]["flags"].asInteger());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelObjectTools::onClickSet(void* data)
|
||||
|
|
@ -1420,7 +1426,7 @@ void LLPanelRequestTools::onClickRequest(void* data)
|
|||
|
||||
void terrain_download_done(void** data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLNotifyBox::showXml("TerrainDownloaded");
|
||||
LLNotifications::instance().add("TerrainDownloaded");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -201,11 +201,11 @@ public:
|
|||
void refresh();
|
||||
|
||||
static void onClickKickAll(void *data);
|
||||
static void confirmKick(S32 option, const std::string& text, void* userdata);
|
||||
static void finishKick(S32 option, void* userdata);
|
||||
static bool confirmKick(const LLSD& notification, const LLSD& response);
|
||||
static bool finishKick(const LLSD& notification, const LLSD& response);
|
||||
static void onDragSunPhase(LLUICtrl *ctrl, void *userdata);
|
||||
static void onClickFlushMapVisibilityCaches(void* data);
|
||||
static void flushMapVisibilityCachesConfirm(S32 option, void* data);
|
||||
static bool flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response);
|
||||
|
||||
protected:
|
||||
std::string mKickMessage; // Message to send on kick
|
||||
|
|
@ -240,7 +240,7 @@ public:
|
|||
static void onClickDeletePublicOwnedBy(void* data);
|
||||
static void onClickDeleteAllScriptedOwnedBy(void* data);
|
||||
static void onClickDeleteAllOwnedBy(void* data);
|
||||
static void callbackSimWideDeletes(S32 option, void* userdata);
|
||||
static bool callbackSimWideDeletes(const LLSD& notification, const LLSD& response);
|
||||
static void onGetTopColliders(void* data);
|
||||
static void onGetTopScripts(void* data);
|
||||
static void onGetScriptDigest(void* data);
|
||||
|
|
|
|||
|
|
@ -388,10 +388,11 @@ void LLPanelGroups::leave()
|
|||
}
|
||||
if(i < count)
|
||||
{
|
||||
LLUUID* cb_data = new LLUUID((const LLUUID&)group_id);
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[GROUP]"] = gAgent.mGroups.get(i).mName;
|
||||
gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callbackLeaveGroup, (void*)cb_data);
|
||||
LLSD args;
|
||||
args["GROUP"] = gAgent.mGroups.get(i).mName;
|
||||
LLSD payload;
|
||||
payload["group_id"] = group_id;
|
||||
LLNotifications::instance().add("GroupLeaveConfirmMember", args, payload, callbackLeaveGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -402,10 +403,11 @@ void LLPanelGroups::search()
|
|||
}
|
||||
|
||||
// static
|
||||
void LLPanelGroups::callbackLeaveGroup(S32 option, void* userdata)
|
||||
bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLUUID* group_id = (LLUUID*)userdata;
|
||||
if(option == 0 && group_id)
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLUUID group_id = notification["payload"]["group_id"].asUUID();
|
||||
if(option == 0)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_LeaveGroupRequest);
|
||||
|
|
@ -413,10 +415,10 @@ void LLPanelGroups::callbackLeaveGroup(S32 option, void* userdata)
|
|||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_GroupData);
|
||||
msg->addUUIDFast(_PREHASH_GroupID, *group_id);
|
||||
msg->addUUIDFast(_PREHASH_GroupID, group_id);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
delete group_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata)
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ protected:
|
|||
void search();
|
||||
void callVote();
|
||||
|
||||
static void callbackLeaveGroup(S32 option, void* userdata);
|
||||
static bool callbackLeaveGroup(const LLSD& notification, const LLSD& response);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ LLFloaterHardwareSettings::~LLFloaterHardwareSettings()
|
|||
void LLFloaterHardwareSettings::onClickHelp(void* data)
|
||||
{
|
||||
const char* xml_alert = "HardwareSettingsHelpButton";
|
||||
gViewerWindow->alertXml(xml_alert);
|
||||
LLNotifications::instance().add(xml_alert);
|
||||
}
|
||||
|
||||
void LLFloaterHardwareSettings::initCallbacks(void)
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void LLFloaterHUD::showHUD()
|
|||
// do not build the floater if there the url is empty
|
||||
if (gSavedSettings.getString("TutorialURL") == "")
|
||||
{
|
||||
LLAlertDialog::showXml("TutorialNotFound");
|
||||
LLNotifications::instance().add("TutorialNotFound");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,6 @@ static const BOOL BUY_PERSONAL_LAND = FALSE;
|
|||
LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL;
|
||||
S32 LLFloaterLand::sLastTab = 0;
|
||||
|
||||
LLHandle<LLFloater> LLPanelLandGeneral::sBuyPassDialogHandle;
|
||||
|
||||
// Local classes
|
||||
class LLParcelSelectionObserver : public LLParcelObserver
|
||||
{
|
||||
|
|
@ -872,12 +870,12 @@ void LLPanelLandGeneral::onClickBuyPass(void* data)
|
|||
cost = llformat("%d", pass_price);
|
||||
time = llformat("%.2f", pass_hours);
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[COST]"] = cost;
|
||||
args["[PARCEL_NAME]"] = parcel_name;
|
||||
args["[TIME]"] = time;
|
||||
LLSD args;
|
||||
args["COST"] = cost;
|
||||
args["PARCEL_NAME"] = parcel_name;
|
||||
args["TIME"] = time;
|
||||
|
||||
sBuyPassDialogHandle = gViewerWindow->alertXml("LandBuyPass", args, cbBuyPass)->getHandle();
|
||||
LLNotifications::instance().add("LandBuyPass", args, LLSD(), cbBuyPass);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -889,7 +887,7 @@ void LLPanelLandGeneral::onClickStartAuction(void* data)
|
|||
{
|
||||
if(parcelp->getForSale())
|
||||
{
|
||||
gViewerWindow->alertXml("CannotStartAuctionAlreadForSale");
|
||||
LLNotifications::instance().add("CannotStartAuctionAlreadForSale");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -899,19 +897,15 @@ void LLPanelLandGeneral::onClickStartAuction(void* data)
|
|||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandGeneral::cbBuyPass(S32 option, void* data)
|
||||
bool LLPanelLandGeneral::cbBuyPass(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (0 == option)
|
||||
{
|
||||
// User clicked OK
|
||||
LLViewerParcelMgr::getInstance()->buyPass();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
BOOL LLPanelLandGeneral::buyPassDialogVisible()
|
||||
{
|
||||
return sBuyPassDialogHandle.get() != NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1249,28 +1243,27 @@ void send_return_objects_message(S32 parcel_local_id, S32 return_type,
|
|||
msg->sendReliable(region->getHost());
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandObjects::callbackReturnOwnerObjects(S32 option, void* userdata)
|
||||
bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelLandObjects *lop = (LLPanelLandObjects *)userdata;
|
||||
LLParcel *parcel = lop->mParcel->getParcel();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLParcel *parcel = mParcel->getParcel();
|
||||
if (0 == option)
|
||||
{
|
||||
if (parcel)
|
||||
{
|
||||
LLUUID owner_id = parcel->getOwnerID();
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
if (owner_id == gAgentID)
|
||||
{
|
||||
LLNotifyBox::showXml("OwnedObjectsReturned");
|
||||
LLNotifications::instance().add("OwnedObjectsReturned");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string first, last;
|
||||
gCacheName->getName(owner_id, first, last);
|
||||
args["[FIRST]"] = first;
|
||||
args["[LAST]"] = last;
|
||||
LLNotifyBox::showXml("OtherObjectsReturned", args);
|
||||
args["FIRST"] = first;
|
||||
args["LAST"] = last;
|
||||
LLNotifications::instance().add("OtherObjectsReturned", args);
|
||||
}
|
||||
send_return_objects_message(parcel->getLocalID(), RT_OWNER);
|
||||
}
|
||||
|
|
@ -1278,81 +1271,82 @@ void LLPanelLandObjects::callbackReturnOwnerObjects(S32 option, void* userdata)
|
|||
|
||||
LLSelectMgr::getInstance()->unhighlightAll();
|
||||
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
|
||||
lop->refresh();
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandObjects::callbackReturnGroupObjects(S32 option, void* userdata)
|
||||
bool LLPanelLandObjects::callbackReturnGroupObjects(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelLandObjects *lop = (LLPanelLandObjects *)userdata;
|
||||
LLParcel *parcel = lop->mParcel->getParcel();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLParcel *parcel = mParcel->getParcel();
|
||||
if (0 == option)
|
||||
{
|
||||
if (parcel)
|
||||
{
|
||||
std::string group_name;
|
||||
gCacheName->getGroupName(parcel->getGroupID(), group_name);
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[GROUPNAME]"] = group_name;
|
||||
LLNotifyBox::showXml("GroupObjectsReturned", args);
|
||||
LLSD args;
|
||||
args["GROUPNAME"] = group_name;
|
||||
LLNotifications::instance().add("GroupObjectsReturned", args);
|
||||
send_return_objects_message(parcel->getLocalID(), RT_GROUP);
|
||||
}
|
||||
}
|
||||
LLSelectMgr::getInstance()->unhighlightAll();
|
||||
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
|
||||
lop->refresh();
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandObjects::callbackReturnOtherObjects(S32 option, void* userdata)
|
||||
bool LLPanelLandObjects::callbackReturnOtherObjects(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelLandObjects *lop = (LLPanelLandObjects *)userdata;
|
||||
LLParcel *parcel = lop->mParcel->getParcel();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLParcel *parcel = mParcel->getParcel();
|
||||
if (0 == option)
|
||||
{
|
||||
if (parcel)
|
||||
{
|
||||
LLNotifyBox::showXml("UnOwnedObjectsReturned");
|
||||
LLNotifications::instance().add("UnOwnedObjectsReturned");
|
||||
send_return_objects_message(parcel->getLocalID(), RT_OTHER);
|
||||
}
|
||||
}
|
||||
LLSelectMgr::getInstance()->unhighlightAll();
|
||||
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
|
||||
lop->refresh();
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandObjects::callbackReturnOwnerList(S32 option, void* userdata)
|
||||
bool LLPanelLandObjects::callbackReturnOwnerList(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelLandObjects *self = (LLPanelLandObjects *)userdata;
|
||||
LLParcel *parcel = self->mParcel->getParcel();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLParcel *parcel = mParcel->getParcel();
|
||||
if (0 == option)
|
||||
{
|
||||
if (parcel)
|
||||
{
|
||||
// Make sure we have something selected.
|
||||
uuid_list_t::iterator selected = self->mSelectedOwners.begin();
|
||||
if (selected != self->mSelectedOwners.end())
|
||||
uuid_list_t::iterator selected = mSelectedOwners.begin();
|
||||
if (selected != mSelectedOwners.end())
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
if (self->mSelectedIsGroup)
|
||||
LLSD args;
|
||||
if (mSelectedIsGroup)
|
||||
{
|
||||
args["[GROUPNAME]"] = self->mSelectedName;
|
||||
LLNotifyBox::showXml("GroupObjectsReturned", args);
|
||||
args["GROUPNAME"] = mSelectedName;
|
||||
LLNotifications::instance().add("GroupObjectsReturned", args);
|
||||
}
|
||||
else
|
||||
{
|
||||
args["[NAME]"] = self->mSelectedName;
|
||||
LLNotifyBox::showXml("OtherObjectsReturned2", args);
|
||||
args["NAME"] = mSelectedName;
|
||||
LLNotifications::instance().add("OtherObjectsReturned2", args);
|
||||
}
|
||||
|
||||
send_return_objects_message(parcel->getLocalID(), RT_LIST, &(self->mSelectedOwners));
|
||||
send_return_objects_message(parcel->getLocalID(), RT_LIST, &(mSelectedOwners));
|
||||
}
|
||||
}
|
||||
}
|
||||
LLSelectMgr::getInstance()->unhighlightAll();
|
||||
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
|
||||
self->refresh();
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1374,16 +1368,16 @@ void LLPanelLandObjects::onClickReturnOwnerList(void* userdata)
|
|||
|
||||
send_parcel_select_objects(parcelp->getLocalID(), RT_LIST, &(self->mSelectedOwners));
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = self->mSelectedName;
|
||||
args["[N]"] = llformat("%d",self->mSelectedCount);
|
||||
LLSD args;
|
||||
args["NAME"] = self->mSelectedName;
|
||||
args["N"] = llformat("%d",self->mSelectedCount);
|
||||
if (self->mSelectedIsGroup)
|
||||
{
|
||||
gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnOwnerList, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerList, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1591,19 +1585,19 @@ void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
|
|||
|
||||
LLUUID owner_id = parcel->getOwnerID();
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[N]"] = llformat("%d",owned);
|
||||
LLSD args;
|
||||
args["N"] = llformat("%d",owned);
|
||||
|
||||
if (owner_id == gAgent.getID())
|
||||
{
|
||||
gViewerWindow->alertXml("ReturnObjectsOwnedBySelf", args, callbackReturnOwnerObjects, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsOwnedBySelf", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name;
|
||||
gCacheName->getFullName(owner_id, name);
|
||||
args["[NAME]"] = name;
|
||||
gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerObjects, userdata);
|
||||
args["NAME"] = name;
|
||||
LLNotifications::instance().add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1619,12 +1613,12 @@ void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
|
|||
std::string group_name;
|
||||
gCacheName->getGroupName(parcel->getGroupID(), group_name);
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = group_name;
|
||||
args["[N]"] = llformat("%d", parcel->getGroupPrimCount());
|
||||
LLSD args;
|
||||
args["NAME"] = group_name;
|
||||
args["N"] = llformat("%d", parcel->getGroupPrimCount());
|
||||
|
||||
// create and show confirmation textbox
|
||||
gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnGroupObjects, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnGroupObjects, panelp, _1, _2));
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1640,16 +1634,16 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
|
|||
|
||||
send_parcel_select_objects(parcel->getLocalID(), RT_OTHER);
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[N]"] = llformat("%d", other);
|
||||
LLSD args;
|
||||
args["N"] = llformat("%d", other);
|
||||
|
||||
if (parcel->getIsGroupOwned())
|
||||
{
|
||||
std::string group_name;
|
||||
gCacheName->getGroupName(parcel->getGroupID(), group_name);
|
||||
args["[NAME]"] = group_name;
|
||||
args["NAME"] = group_name;
|
||||
|
||||
gViewerWindow->alertXml("ReturnObjectsNotOwnedByGroup", args, callbackReturnOtherObjects, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsNotOwnedByGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1657,15 +1651,15 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
|
|||
|
||||
if (owner_id == gAgent.getID())
|
||||
{
|
||||
gViewerWindow->alertXml("ReturnObjectsNotOwnedBySelf", args, callbackReturnOtherObjects, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsNotOwnedBySelf", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name;
|
||||
gCacheName->getFullName(owner_id, name);
|
||||
args["[NAME]"] = name;
|
||||
args["NAME"] = name;
|
||||
|
||||
gViewerWindow->alertXml("ReturnObjectsNotOwnedByUser", args, callbackReturnOtherObjects, userdata);
|
||||
LLNotifications::instance().add("ReturnObjectsNotOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2073,7 +2067,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
|||
if (!allow_other_scripts && region && region->getAllowDamage())
|
||||
{
|
||||
|
||||
gViewerWindow->alertXml("UnableToDisableOutsideScripts");
|
||||
LLNotifications::instance().add("UnableToDisableOutsideScripts");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2117,7 +2111,7 @@ void LLPanelLandOptions::onClickSet(void* userdata)
|
|||
|
||||
if (agent_parcel->getLocalID() != selected_parcel->getLocalID())
|
||||
{
|
||||
gViewerWindow->alertXml("MustBeInParcel");
|
||||
LLNotifications::instance().add("MustBeInParcel");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2160,11 +2154,11 @@ void LLPanelLandOptions::onClickPublishHelp(void*)
|
|||
|
||||
if(! can_change_identity)
|
||||
{
|
||||
gViewerWindow->alertXml("ClickPublishHelpLandDisabled");
|
||||
LLNotifications::instance().add("ClickPublishHelpLandDisabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ClickPublishHelpLand");
|
||||
LLNotifications::instance().add("ClickPublishHelpLand");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,8 +151,7 @@ public:
|
|||
static void finalizeSetSellChange(void * userdata);
|
||||
static void onSalePriceChange(LLUICtrl *ctrl, void * userdata);
|
||||
|
||||
static void cbBuyPass(S32 option, void*);
|
||||
static BOOL buyPassDialogVisible();
|
||||
static bool cbBuyPass(const LLSD& notification, const LLSD& response);
|
||||
|
||||
static void onClickSellLand(void* data);
|
||||
static void onClickStopSellLand(void* data);
|
||||
|
|
@ -234,10 +233,10 @@ public:
|
|||
void refresh();
|
||||
virtual void draw();
|
||||
|
||||
static void callbackReturnOwnerObjects(S32, void*);
|
||||
static void callbackReturnGroupObjects(S32, void*);
|
||||
static void callbackReturnOtherObjects(S32, void*);
|
||||
static void callbackReturnOwnerList(S32, void*);
|
||||
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*);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,292 @@
|
|||
/**
|
||||
* @file llnotificationsconsole.cpp
|
||||
* @brief Debugging console for unified notifications.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-2007, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llfloaternotificationsconsole.h"
|
||||
#include "llnotifications.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llbutton.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llpanel.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llviewertexteditor.h"
|
||||
|
||||
const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
|
||||
const S32 HEADER_PADDING = 38;
|
||||
|
||||
class LLNotificationChannelPanel : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLNotificationChannelPanel(const std::string& channel_name);
|
||||
BOOL postBuild();
|
||||
|
||||
private:
|
||||
bool update(const LLSD& payload, bool passed_filter);
|
||||
static void toggleClick(void* user_data);
|
||||
static void onClickNotification(void* user_data);
|
||||
static void onClickNotificationReject(void* user_data);
|
||||
LLNotificationChannelPtr mChannelPtr;
|
||||
LLNotificationChannelPtr mChannelRejectsPtr;
|
||||
};
|
||||
|
||||
LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name)
|
||||
: LLPanel(channel_name)
|
||||
{
|
||||
mChannelPtr = LLNotifications::instance().getChannel(channel_name);
|
||||
mChannelRejectsPtr = LLNotificationChannelPtr(
|
||||
new LLNotificationChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(), !boost::bind(mChannelPtr->getFilter(), _1)));
|
||||
LLUICtrlFactory::instance().buildPanel(this, "panel_notifications_channel.xml");
|
||||
}
|
||||
|
||||
BOOL LLNotificationChannelPanel::postBuild()
|
||||
{
|
||||
LLButton* header_button = getChild<LLButton>("header");
|
||||
header_button->setLabel(mChannelPtr->getName());
|
||||
header_button->setClickedCallback(toggleClick, this);
|
||||
|
||||
mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
|
||||
mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
|
||||
|
||||
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
|
||||
scroll->setDoubleClickCallback(onClickNotification);
|
||||
scroll->setCallbackUserData(this);
|
||||
|
||||
scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
|
||||
scroll->setDoubleClickCallback(onClickNotificationReject);
|
||||
scroll->setCallbackUserData(this);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLNotificationChannelPanel::toggleClick(void *user_data)
|
||||
{
|
||||
LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
|
||||
if (!self) return;
|
||||
|
||||
LLButton* header_button = self->getChild<LLButton>("header");
|
||||
|
||||
LLLayoutStack* stack = dynamic_cast<LLLayoutStack*>(self->getParent());
|
||||
if (stack)
|
||||
{
|
||||
stack->collapsePanel(self, header_button->getToggleState());
|
||||
}
|
||||
|
||||
// turn off tab stop for collapsed panel
|
||||
self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
|
||||
self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
|
||||
self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
|
||||
self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLNotificationChannelPanel::onClickNotification(void* user_data)
|
||||
{
|
||||
LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
|
||||
if (!self) return;
|
||||
void* data = self->getChild<LLScrollListCtrl>("notifications_list")->getFirstSelected()->getUserdata();
|
||||
if (data)
|
||||
{
|
||||
gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
|
||||
{
|
||||
LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
|
||||
if (!self) return;
|
||||
void* data = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected()->getUserdata();
|
||||
if (data)
|
||||
{
|
||||
gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
|
||||
{
|
||||
LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
|
||||
if (notification)
|
||||
{
|
||||
LLSD row;
|
||||
row["columns"][0]["value"] = notification->getName();
|
||||
row["columns"][0]["column"] = "name";
|
||||
|
||||
row["columns"][1]["value"] = notification->getMessage();
|
||||
row["columns"][1]["column"] = "content";
|
||||
|
||||
row["columns"][2]["value"] = notification->getDate();
|
||||
row["columns"][2]["column"] = "date";
|
||||
row["columns"][2]["type"] = "date";
|
||||
|
||||
LLScrollListItem* sli = passed_filter ?
|
||||
getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
|
||||
getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
|
||||
sli->setUserdata(&(*notification));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// LLFloaterNotificationConsole
|
||||
//
|
||||
LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
|
||||
{
|
||||
LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml");
|
||||
}
|
||||
|
||||
void LLFloaterNotificationConsole::onClose(bool app_quitting)
|
||||
{
|
||||
setVisible(FALSE);
|
||||
//destroy();
|
||||
}
|
||||
|
||||
|
||||
BOOL LLFloaterNotificationConsole::postBuild()
|
||||
{
|
||||
// these are in the order of processing
|
||||
addChannel("Unexpired");
|
||||
addChannel("Ignore");
|
||||
addChannel("Visible", true);
|
||||
// all the ones below attach to the Visible channel
|
||||
addChannel("History");
|
||||
addChannel("Alerts");
|
||||
addChannel("AlertModal");
|
||||
addChannel("Group Notifications");
|
||||
addChannel("Notifications");
|
||||
addChannel("NotificationTips");
|
||||
|
||||
getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);
|
||||
|
||||
LLComboBox* notifications = getChild<LLComboBox>("notification_types");
|
||||
LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
|
||||
for (LLNotifications::TemplateNames::iterator template_it = names.begin();
|
||||
template_it != names.end();
|
||||
++template_it)
|
||||
{
|
||||
notifications->add(*template_it);
|
||||
}
|
||||
notifications->sortByName();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open)
|
||||
{
|
||||
LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
|
||||
LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(name);
|
||||
stack.addPanel(panelp, 0, NOTIFICATION_PANEL_HEADER_HEIGHT, TRUE, TRUE, LLLayoutStack::ANIMATE);
|
||||
|
||||
LLButton& header_button = panelp->getChildRef<LLButton>("header");
|
||||
header_button.setToggleState(!open);
|
||||
stack.collapsePanel(panelp, !open);
|
||||
|
||||
updateResizeLimits();
|
||||
}
|
||||
|
||||
void LLFloaterNotificationConsole::removeChannel(const std::string& name)
|
||||
{
|
||||
LLPanel* panelp = getChild<LLPanel>(name, TRUE, FALSE);
|
||||
if (panelp)
|
||||
{
|
||||
getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
|
||||
delete panelp;
|
||||
}
|
||||
|
||||
updateResizeLimits();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterNotificationConsole::updateResizeLimits()
|
||||
{
|
||||
LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
|
||||
setResizeLimits(getMinWidth(), LLFLOATER_HEADER_SIZE + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
|
||||
}
|
||||
|
||||
void LLFloaterNotificationConsole::onClickAdd(void* user_data)
|
||||
{
|
||||
LLFloaterNotificationConsole* floater = (LLFloaterNotificationConsole*)user_data;
|
||||
|
||||
std::string message_name = floater->getChild<LLComboBox>("notification_types")->getValue().asString();
|
||||
if (!message_name.empty())
|
||||
{
|
||||
LLNotifications::instance().add(message_name, LLSD());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============== LLFloaterNotification ================
|
||||
|
||||
LLFloaterNotification::LLFloaterNotification(LLNotification* note) : mNote(note)
|
||||
{
|
||||
LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml");
|
||||
}
|
||||
|
||||
BOOL LLFloaterNotification::postBuild()
|
||||
{
|
||||
setTitle(mNote->getName());
|
||||
getChild<LLViewerTextEditor>("payload")->setText(mNote->getMessage());
|
||||
|
||||
LLComboBox* responses_combo = getChild<LLComboBox>("response");
|
||||
LLCtrlListInterface* response_list = responses_combo->getListInterface();
|
||||
LLNotificationFormPtr form(mNote->getForm());
|
||||
if(!form)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
responses_combo->setCommitCallback(onCommitResponse);
|
||||
responses_combo->setCallbackUserData(this);
|
||||
|
||||
LLSD form_sd = form->asLLSD();
|
||||
|
||||
for (LLSD::array_const_iterator form_item = form_sd.beginArray(); form_item != form_sd.endArray(); ++form_item)
|
||||
{
|
||||
if ( (*form_item)["type"].asString() != "button") continue;
|
||||
std::string text = (*form_item)["text"].asString();
|
||||
response_list->addSimpleElement(text);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterNotification::respond()
|
||||
{
|
||||
LLComboBox* responses_combo = getChild<LLComboBox>("response");
|
||||
LLCtrlListInterface* response_list = responses_combo->getListInterface();
|
||||
const std::string& trigger = response_list->getSelectedValue().asString();
|
||||
//llinfos << trigger << llendl;
|
||||
|
||||
LLSD response = mNote->getResponseTemplate();
|
||||
response[trigger] = true;
|
||||
mNote->respond(response);
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* @file llfloaternotificationsconsole.h
|
||||
* @brief Debugging console for unified notifications.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-2007, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATER_NOTIFICATIONS_CONSOLE_H
|
||||
#define LL_LLFLOATER_NOTIFICATIONS_CONSOLE_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llnotifications.h"
|
||||
|
||||
class LLFloaterNotificationConsole :
|
||||
public LLFloater,
|
||||
public LLFloaterSingleton<LLFloaterNotificationConsole>
|
||||
{
|
||||
public:
|
||||
LLFloaterNotificationConsole(const LLSD& key);
|
||||
|
||||
// LLPanel
|
||||
BOOL postBuild();
|
||||
void onClose(bool app_quitting);
|
||||
|
||||
void addChannel(const std::string& type, bool open = false);
|
||||
void updateResizeLimits(LLLayoutStack &stack);
|
||||
|
||||
void removeChannel(const std::string& type);
|
||||
void updateResizeLimits();
|
||||
|
||||
private:
|
||||
static void onClickAdd(void* user_data);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @brief Pop-up debugging view of a generic new notification.
|
||||
*/
|
||||
class LLFloaterNotification : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterNotification(LLNotification* note);
|
||||
|
||||
// LLPanel
|
||||
BOOL postBuild();
|
||||
void respond();
|
||||
void onClose(bool app_quitting) { setVisible(FALSE); }
|
||||
|
||||
private:
|
||||
static void onCommitResponse(LLUICtrl* ctrl, void* data) { ((LLFloaterNotification*)data)->respond(); }
|
||||
LLNotification* mNote;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ void LLFloaterOpenObject::show()
|
|||
LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection();
|
||||
if (object_selection->getRootObjectCount() != 1)
|
||||
{
|
||||
gViewerWindow->alertXml("UnableToViewContentsMoreThanOne");
|
||||
LLNotifications::instance().add("UnableToViewContentsMoreThanOne");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
|
|||
{
|
||||
if (mObjectSelection->getRootObjectCount() != 1)
|
||||
{
|
||||
gViewerWindow->alertXml("OnlyCopyContentsOfSingleItem");
|
||||
LLNotifications::instance().add("OnlyCopyContentsOfSingleItem");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
|
|||
delete data;
|
||||
data = NULL;
|
||||
|
||||
gViewerWindow->alertXml("OpenObjectCannotCopy");
|
||||
LLNotifications::instance().add("OpenObjectCannotCopy");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,5 +153,5 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
|
|||
//static
|
||||
void LLFloaterPerms::onClickHelp(void* data)
|
||||
{
|
||||
gViewerWindow->alertXml("ClickUploadHelpPermissions");
|
||||
LLNotifications::instance().add("ClickUploadHelpPermissions");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,20 +249,20 @@ void LLFloaterPostcard::onClickSend(void* data)
|
|||
|
||||
if (to.empty() || !boost::regex_match(to, emailFormat))
|
||||
{
|
||||
gViewerWindow->alertXml("PromptRecipientEmail");
|
||||
LLNotifications::instance().add("PromptRecipientEmail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.empty() || !boost::regex_match(from, emailFormat))
|
||||
{
|
||||
gViewerWindow->alertXml("PromptSelfEmail");
|
||||
LLNotifications::instance().add("PromptSelfEmail");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string subject(self->childGetValue("subject_form").asString());
|
||||
if(subject.empty() || !self->mHasFirstMsgFocus)
|
||||
{
|
||||
gViewerWindow->alertXml("PromptMissingSubjMsg", missingSubjMsgAlertCallback, self);
|
||||
LLNotifications::instance().add("PromptMissingSubjMsg", LLSD(), LLSD(), boost::bind(&LLFloaterPostcard::missingSubjMsgAlertCallback, self, _1, _2));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ void LLFloaterPostcard::onClickSend(void* data)
|
|||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ErrorProcessingSnapshot");
|
||||
LLNotifications::instance().add("ErrorProcessingSnapshot");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -286,9 +286,9 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data,
|
|||
|
||||
if (result)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result));
|
||||
gViewerWindow->alertXml("ErrorUploadingPostcard", args);
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
|
||||
LLNotifications::instance().add("ErrorUploadingPostcard", args);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -345,30 +345,28 @@ void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, voi
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterPostcard::missingSubjMsgAlertCallback(S32 option, void* data)
|
||||
bool LLFloaterPostcard::missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if(data)
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if(0 == option)
|
||||
{
|
||||
LLFloaterPostcard* self = static_cast<LLFloaterPostcard*>(data);
|
||||
if(0 == option)
|
||||
// User clicked OK
|
||||
if((childGetValue("subject_form").asString()).empty())
|
||||
{
|
||||
// User clicked OK
|
||||
if((self->childGetValue("subject_form").asString()).empty())
|
||||
{
|
||||
// Stuff the subject back into the form.
|
||||
self->childSetValue("subject_form", self->getString("default_subject"));
|
||||
}
|
||||
|
||||
if(!self->mHasFirstMsgFocus)
|
||||
{
|
||||
// The user never switched focus to the messagee window.
|
||||
// Using the default string.
|
||||
self->childSetValue("msg_form", self->getString("default_message"));
|
||||
}
|
||||
|
||||
self->sendPostcard();
|
||||
// Stuff the subject back into the form.
|
||||
childSetValue("subject_form", getString("default_subject"));
|
||||
}
|
||||
|
||||
if(!mHasFirstMsgFocus)
|
||||
{
|
||||
// The user never switched focus to the messagee window.
|
||||
// Using the default string.
|
||||
childSetValue("msg_form", getString("default_message"));
|
||||
}
|
||||
|
||||
sendPostcard();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterPostcard::sendPostcard()
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public:
|
|||
static void updateUserInfo(const std::string& email);
|
||||
|
||||
static void onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data);
|
||||
static void missingSubjMsgAlertCallback(S32 option, void* data);
|
||||
bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void sendPostcard();
|
||||
|
||||
|
|
|
|||
|
|
@ -169,11 +169,13 @@ void LLFloaterPostProcess::onSaveEffect(void* userData)
|
|||
{
|
||||
LLLineEditor* editBox = static_cast<LLLineEditor*>(userData);
|
||||
|
||||
LLSD::String effectName(editBox->getValue().asString());
|
||||
std::string effectName(editBox->getValue().asString());
|
||||
|
||||
if (gPostProcess->mAllEffects.has(effectName))
|
||||
{
|
||||
gViewerWindow->alertXml("PPSaveEffectAlert", &LLFloaterPostProcess::saveAlertCallback, userData);
|
||||
LLSD payload;
|
||||
payload["effect_name"] = effectName;
|
||||
LLNotifications::instance().add("PPSaveEffectAlert", LLSD(), payload, &LLFloaterPostProcess::saveAlertCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -192,20 +194,18 @@ void LLFloaterPostProcess::onChangeEffectName(LLUICtrl* ctrl, void * userData)
|
|||
editBox->setValue(comboBox->getSelectedValue());
|
||||
}
|
||||
|
||||
void LLFloaterPostProcess::saveAlertCallback(S32 option, void* userData)
|
||||
bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLLineEditor* editBox = static_cast<LLLineEditor*>(userData);
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
// if they choose save, do it. Otherwise, don't do anything
|
||||
if (option == 0)
|
||||
{
|
||||
LLSD::String effectName(editBox->getValue().asString());
|
||||
|
||||
gPostProcess->saveEffect(effectName);
|
||||
gPostProcess->saveEffect(notification["payload"]["effect_name"].asString());
|
||||
|
||||
sPostProcess->syncMenu();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterPostProcess::show()
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
static void onChangeEffectName(LLUICtrl* ctrl, void * userData);
|
||||
|
||||
/// prompts a user when overwriting an effect
|
||||
static void saveAlertCallback(S32 option, void* userData);
|
||||
static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// show off our menu
|
||||
static void show();
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include "llfloatergroups.h"
|
||||
#include "llfloatertelehub.h"
|
||||
#include "llfloaterwindlight.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llalertdialog.h"
|
||||
#include "llnamelistctrl.h"
|
||||
|
|
@ -540,8 +541,8 @@ void LLPanelRegionInfo::initHelpBtn(const std::string& name, const std::string&
|
|||
// static
|
||||
void LLPanelRegionInfo::onClickHelp(void* data)
|
||||
{
|
||||
const std::string* xml_alert = (std::string*)data;
|
||||
gViewerWindow->alertXml(*xml_alert);
|
||||
std::string* xml_alert = (std::string*)data;
|
||||
LLNotifications::instance().add(*xml_alert);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -638,16 +639,17 @@ void LLPanelRegionGeneralInfo::onKickCommit(const std::vector<std::string>& name
|
|||
void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata)
|
||||
{
|
||||
llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl;
|
||||
gViewerWindow->alertXml("KickUsersFromRegion", onKickAllCommit, userdata);
|
||||
LLNotifications::instance().add("KickUsersFromRegion",
|
||||
LLSD(),
|
||||
LLSD(),
|
||||
boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionGeneralInfo::onKickAllCommit(S32 option, void* userdata)
|
||||
bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata;
|
||||
if(!self) return;
|
||||
strings_t strings;
|
||||
// [0] = our agent id
|
||||
std::string buffer;
|
||||
|
|
@ -656,26 +658,29 @@ void LLPanelRegionGeneralInfo::onKickAllCommit(S32 option, void* userdata)
|
|||
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
// historical message name
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
|
||||
sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionGeneralInfo::onClickMessage(void* userdata)
|
||||
{
|
||||
llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl;
|
||||
gViewerWindow->alertXmlEditText("MessageRegion", LLStringUtil::format_map_t(),
|
||||
NULL, NULL,
|
||||
onMessageCommit, userdata);
|
||||
LLNotifications::instance().add("MessageRegion",
|
||||
LLSD(),
|
||||
LLSD(),
|
||||
boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionGeneralInfo::onMessageCommit(S32 option, const std::string& text, void* userdata)
|
||||
bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if(option != 0) return;
|
||||
if(text.empty()) return;
|
||||
LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata;
|
||||
if(!self) return;
|
||||
if(LLNotification::getSelectedOption(notification, response) != 0) return false;
|
||||
|
||||
std::string text = response["message"].asString();
|
||||
if (text.empty()) return false;
|
||||
|
||||
llinfos << "Message to everyone: " << text << llendl;
|
||||
strings_t strings;
|
||||
// [0] grid_x, unused here
|
||||
|
|
@ -693,7 +698,8 @@ void LLPanelRegionGeneralInfo::onMessageCommit(S32 option, const std::string& te
|
|||
strings.push_back(strings_t::value_type(name));
|
||||
strings.push_back(strings_t::value_type(text));
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
|
||||
sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -780,7 +786,7 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()
|
|||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region && access != region->getSimAccess() )
|
||||
{
|
||||
gViewerWindow->alertXml("RegionMaturityChange");
|
||||
LLNotifications::instance().add("RegionMaturityChange");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -881,48 +887,56 @@ void LLPanelRegionDebugInfo::onClickReturn(void* data)
|
|||
LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
|
||||
if (panelp->mTargetAvatar.isNull()) return;
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[USER_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
gViewerWindow->alertXml("EstateObjectReturn", args, callbackReturn, data);
|
||||
LLSD args;
|
||||
args["USER_NAME"] = panelp->childGetValue("target_avatar_name").asString();
|
||||
LLSD payload;
|
||||
payload["avatar_id"] = panelp->mTargetAvatar;
|
||||
|
||||
U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
|
||||
|
||||
if (panelp->childGetValue("return_scripts").asBoolean())
|
||||
{
|
||||
flags |= SWD_SCRIPTED_ONLY;
|
||||
}
|
||||
|
||||
if (panelp->childGetValue("return_other_land").asBoolean())
|
||||
{
|
||||
flags |= SWD_OTHERS_LAND_ONLY;
|
||||
}
|
||||
payload["flags"] = int(flags);
|
||||
payload["return_estate_wide"] = panelp->childGetValue("return_estate_wide").asBoolean();
|
||||
LLNotifications::instance().add("EstateObjectReturn", args, payload,
|
||||
boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionDebugInfo::callbackReturn( S32 option, void* userdata )
|
||||
bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if (option != 0) return;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0) return false;
|
||||
|
||||
LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) userdata;
|
||||
if (!self->mTargetAvatar.isNull())
|
||||
LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID();
|
||||
if (!target_avatar.isNull())
|
||||
{
|
||||
U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
|
||||
|
||||
if (self->childGetValue("return_scripts").asBoolean())
|
||||
{
|
||||
flags |= SWD_SCRIPTED_ONLY;
|
||||
}
|
||||
|
||||
if (self->childGetValue("return_other_land").asBoolean())
|
||||
{
|
||||
flags |= SWD_OTHERS_LAND_ONLY;
|
||||
}
|
||||
|
||||
if (self->childGetValue("return_estate_wide").asBoolean())
|
||||
U32 flags = notification["payload"]["flags"].asInteger();
|
||||
bool return_estate_wide = notification["payload"]["return_estate_wide"];
|
||||
if (return_estate_wide)
|
||||
{
|
||||
// send as estate message - routed by spaceserver to all regions in estate
|
||||
strings_t strings;
|
||||
strings.push_back(llformat("%d", flags));
|
||||
strings.push_back(self->mTargetAvatar.asString());
|
||||
strings.push_back(target_avatar.asString());
|
||||
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
|
||||
sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
|
||||
}
|
||||
else
|
||||
{
|
||||
// send to this simulator only
|
||||
send_sim_wide_deletes(self->mTargetAvatar, flags);
|
||||
}
|
||||
send_sim_wide_deletes(target_avatar, flags);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -953,19 +967,20 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data)
|
|||
// static
|
||||
void LLPanelRegionDebugInfo::onClickRestart(void* data)
|
||||
{
|
||||
gViewerWindow->alertXml("ConfirmRestart", callbackRestart, data);
|
||||
LLNotifications::instance().add("ConfirmRestart", LLSD(), LLSD(),
|
||||
boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionDebugInfo::callbackRestart(S32 option, void* data)
|
||||
bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if (option != 0) return;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0) return false;
|
||||
|
||||
LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
|
||||
strings_t strings;
|
||||
strings.push_back("120");
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
|
||||
sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1123,21 +1138,21 @@ BOOL LLPanelRegionTextureInfo::validateTextureSizes()
|
|||
|
||||
if (components != 3)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[TEXTURE_NUM]"] = llformat("%d",i+1);
|
||||
args["[TEXTURE_BIT_DEPTH]"] = llformat("%d",components * 8);
|
||||
gViewerWindow->alertXml("InvalidTerrainBitDepth", args);
|
||||
LLSD args;
|
||||
args["TEXTURE_NUM"] = i+1;
|
||||
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
|
||||
LLNotifications::instance().add("InvalidTerrainBitDepth", args);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (width > 512 || height > 512)
|
||||
{
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[TEXTURE_NUM]"] = llformat("%d",i+1);
|
||||
args["[TEXTURE_SIZE_X]"] = llformat("%d",width);
|
||||
args["[TEXTURE_SIZE_Y]"] = llformat("%d",height);
|
||||
gViewerWindow->alertXml("InvalidTerrainSize", args);
|
||||
LLSD args;
|
||||
args["TEXTURE_NUM"] = i+1;
|
||||
args["TEXTURE_SIZE_X"] = width;
|
||||
args["TEXTURE_SIZE_Y"] = height;
|
||||
LLNotifications::instance().add("InvalidTerrainSize", args);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
|
@ -1334,26 +1349,27 @@ void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data)
|
|||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
|
||||
|
||||
gViewerWindow->alertXml("RawUploadStarted");
|
||||
LLNotifications::instance().add("RawUploadStarted");
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data)
|
||||
{
|
||||
gViewerWindow->alertXml("ConfirmBakeTerrain",
|
||||
callbackBakeTerrain, data);
|
||||
LLNotifications::instance().add(
|
||||
LLNotification::Params("ConfirmBakeTerrain")
|
||||
.functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2)));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelRegionTerrainInfo::callbackBakeTerrain(S32 option, void* data)
|
||||
bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if (option != 0) return;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0) return false;
|
||||
|
||||
LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
|
||||
strings_t strings;
|
||||
strings.push_back("bake");
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
|
||||
sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1440,9 +1456,9 @@ void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data)
|
|||
{
|
||||
//args
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MAX_AGENTS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
gViewerWindow->alertXml("MaxAllowedAgentOnRegion", args);
|
||||
LLSD args;
|
||||
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotifications::instance().add("MaxAllowedAgentOnRegion", args);
|
||||
return;
|
||||
}
|
||||
accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd");
|
||||
|
|
@ -1462,35 +1478,36 @@ void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data)
|
|||
if (!list) return;
|
||||
if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MAX_GROUPS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
gViewerWindow->alertXml("MaxAllowedGroupsOnRegion", args);
|
||||
LLSD args;
|
||||
args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotifications::instance().add("MaxAllowedGroupsOnRegion", args);
|
||||
return;
|
||||
}
|
||||
|
||||
LLNotification::Params params("ChangeLindenAccess");
|
||||
params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2));
|
||||
if (isLindenEstate())
|
||||
{
|
||||
gViewerWindow->alertXml("ChangeLindenAccess", addAllowedGroup, user_data);
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
else
|
||||
{
|
||||
addAllowedGroup(0, user_data);
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateInfo::addAllowedGroup(S32 option, void* user_data)
|
||||
bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if (option != 0) return;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0) return false;
|
||||
|
||||
LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data;
|
||||
|
||||
LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
|
||||
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
|
||||
|
||||
LLFloaterGroupPicker* widget;
|
||||
widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
|
||||
if (widget)
|
||||
{
|
||||
widget->setSelectCallback(addAllowedGroup2, user_data);
|
||||
widget->setSelectCallback(addAllowedGroup2, NULL);
|
||||
if (parent_floater)
|
||||
{
|
||||
LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
|
||||
|
|
@ -1498,6 +1515,8 @@ void LLPanelEstateInfo::addAllowedGroup(S32 option, void* user_data)
|
|||
parent_floater->addDependentFloater(widget);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1514,9 +1533,9 @@ void LLPanelEstateInfo::onClickAddBannedAgent(void* user_data)
|
|||
if (!list) return;
|
||||
if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MAX_BANNED]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
gViewerWindow->alertXml("MaxBannedAgentsOnRegion", args);
|
||||
LLSD args;
|
||||
args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotifications::instance().add("MaxBannedAgentsOnRegion", args);
|
||||
return;
|
||||
}
|
||||
accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd");
|
||||
|
|
@ -1536,9 +1555,9 @@ void LLPanelEstateInfo::onClickAddEstateManager(void* user_data)
|
|||
if (!list) return;
|
||||
if (list->getItemCount() >= ESTATE_MAX_MANAGERS)
|
||||
{ // Tell user they can't add more managers
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MAX_MANAGER]"] = llformat("%d",ESTATE_MAX_MANAGERS);
|
||||
gViewerWindow->alertXml("MaxManagersOnRegion", args);
|
||||
LLSD args;
|
||||
args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS);
|
||||
LLNotifications::instance().add("MaxManagersOnRegion", args);
|
||||
}
|
||||
else
|
||||
{ // Go pick managers to add
|
||||
|
|
@ -1558,7 +1577,6 @@ void LLPanelEstateInfo::onClickRemoveEstateManager(void* user_data)
|
|||
struct LLKickFromEstateInfo
|
||||
{
|
||||
LLPanelEstateInfo *mEstatePanelp;
|
||||
std::string mDialogName;
|
||||
LLUUID mAgentID;
|
||||
};
|
||||
|
||||
|
|
@ -1590,45 +1608,42 @@ void LLPanelEstateInfo::onKickUserCommit(const std::vector<std::string>& names,
|
|||
//keep track of what user they want to kick and other misc info
|
||||
LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo();
|
||||
kick_info->mEstatePanelp = self;
|
||||
kick_info->mDialogName = "EstateKickUser";
|
||||
kick_info->mAgentID = ids[0];
|
||||
|
||||
//Bring up a confirmation dialog
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[EVIL_USER]"] = names[0];
|
||||
gViewerWindow->alertXml(kick_info->mDialogName, args, LLPanelEstateInfo::kickUserConfirm, (void*)kick_info);
|
||||
LLSD args;
|
||||
args["EVIL_USER"] = names[0];
|
||||
LLSD payload;
|
||||
payload["agent_id"] = ids[0];
|
||||
LLNotifications::instance().add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2));
|
||||
|
||||
}
|
||||
|
||||
void LLPanelEstateInfo::kickUserConfirm(S32 option, void* userdata)
|
||||
bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
//extract the callback parameter
|
||||
LLKickFromEstateInfo *kick_info = (LLKickFromEstateInfo*) userdata;
|
||||
if (!kick_info) return;
|
||||
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
strings_t strings;
|
||||
std::string buffer;
|
||||
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
switch(option)
|
||||
{
|
||||
case 0:
|
||||
//Kick User
|
||||
kick_info->mAgentID.toString(buffer);
|
||||
strings.push_back(buffer);
|
||||
{
|
||||
//Kick User
|
||||
strings_t strings;
|
||||
strings.push_back(notification["payload"]["agent_id"].asString());
|
||||
|
||||
kick_info->mEstatePanelp->sendEstateOwnerMessage(gMessageSystem, "kickestate", invoice, strings);
|
||||
break;
|
||||
sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
delete kick_info;
|
||||
kick_info = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Core Add/Remove estate access methods
|
||||
// TODO: INTERNATIONAL: don't build message text here;
|
||||
// instead, create multiple translatable messages and choose
|
||||
// one based on the status.
|
||||
//---------------------------------------------------------------------------
|
||||
std::string all_estates_text()
|
||||
{
|
||||
|
|
@ -1669,6 +1684,33 @@ bool LLPanelEstateInfo::isLindenEstate()
|
|||
typedef std::vector<LLUUID> AgentOrGroupIDsVector;
|
||||
struct LLEstateAccessChangeInfo
|
||||
{
|
||||
LLEstateAccessChangeInfo(const LLSD& sd)
|
||||
{
|
||||
mDialogName = sd["dialog_name"].asString();
|
||||
mOperationFlag = (U32)sd["operation"].asInteger();
|
||||
LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray();
|
||||
for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray();
|
||||
id_it != end_it;
|
||||
++id_it)
|
||||
{
|
||||
mAgentOrGroupIDs.push_back(id_it->asUUID());
|
||||
}
|
||||
}
|
||||
|
||||
const LLSD asLLSD() const
|
||||
{
|
||||
LLSD sd;
|
||||
sd["name"] = mDialogName;
|
||||
sd["operation"] = (S32)mOperationFlag;
|
||||
for (AgentOrGroupIDsVector::const_iterator it = mAgentOrGroupIDs.begin();
|
||||
it != mAgentOrGroupIDs.end();
|
||||
++it)
|
||||
{
|
||||
sd["allowed_ids"].append(*it);
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc.
|
||||
std::string mDialogName;
|
||||
AgentOrGroupIDsVector mAgentOrGroupIDs; // List of agent IDs to apply to this change
|
||||
|
|
@ -1678,56 +1720,65 @@ struct LLEstateAccessChangeInfo
|
|||
// static
|
||||
void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data)
|
||||
{
|
||||
LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo;
|
||||
change_info->mOperationFlag = ESTATE_ACCESS_ALLOWED_GROUP_ADD;
|
||||
change_info->mDialogName = "EstateAllowedGroupAdd";
|
||||
change_info->mAgentOrGroupIDs.push_back(id);
|
||||
LLSD payload;
|
||||
payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD;
|
||||
payload["dialog_name"] = "EstateAllowedGroupAdd";
|
||||
payload["allowed_ids"].append(id);
|
||||
|
||||
LLSD args;
|
||||
args["ALL_ESTATES"] = all_estates_text();
|
||||
|
||||
LLNotification::Params params("EstateAllowedGroupAdd");
|
||||
params.payload(payload)
|
||||
.substitutions(args)
|
||||
.functor(accessCoreConfirm);
|
||||
if (isLindenEstate())
|
||||
{
|
||||
accessCoreConfirm(0, (void*)change_info);
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[ALL_ESTATES]"] = all_estates_text();
|
||||
gViewerWindow->alertXml(change_info->mDialogName, args, accessCoreConfirm, (void*)change_info);
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name)
|
||||
{
|
||||
LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo;
|
||||
change_info->mOperationFlag = operation_flag;
|
||||
change_info->mDialogName = dialog_name;
|
||||
LLSD payload;
|
||||
payload["operation"] = (S32)operation_flag;
|
||||
payload["dialog_name"] = dialog_name;
|
||||
// agent id filled in after avatar picker
|
||||
|
||||
LLNotification::Params params("ChangeLindenAccess");
|
||||
params.payload(payload)
|
||||
.functor(accessAddCore2);
|
||||
|
||||
if (isLindenEstate())
|
||||
{
|
||||
gViewerWindow->alertXml("ChangeLindenAccess", accessAddCore2, change_info);
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// same as clicking "OK"
|
||||
accessAddCore2(0, change_info);
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateInfo::accessAddCore2(S32 option, void* data)
|
||||
bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0)
|
||||
{
|
||||
// abort change
|
||||
delete change_info;
|
||||
change_info = NULL;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
|
||||
// avatar picker yes multi-select, yes close-on-select
|
||||
LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1756,12 +1807,12 @@ void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, co
|
|||
int currentCount = (list ? list->getItemCount() : 0);
|
||||
if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NUM_ADDED]"] = llformat("%d",ids.size());
|
||||
args["[MAX_AGENTS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
args["[LIST_TYPE]"] = "Allowed Residents";
|
||||
args["[NUM_EXCESS]"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
|
||||
gViewerWindow->alertXml("MaxAgentOnRegionBatch", args);
|
||||
LLSD args;
|
||||
args["NUM_ADDED"] = llformat("%d",ids.size());
|
||||
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
args["LIST_TYPE"] = "Allowed Residents";
|
||||
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotifications::instance().add("MaxAgentOnRegionBatch", args);
|
||||
delete change_info;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1772,28 +1823,34 @@ void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, co
|
|||
int currentCount = (list ? list->getItemCount() : 0);
|
||||
if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NUM_ADDED]"] = llformat("%d",ids.size());
|
||||
args["[MAX_AGENTS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
args["[LIST_TYPE]"] = "Banned Residents";
|
||||
args["[NUM_EXCESS]"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
|
||||
gViewerWindow->alertXml("MaxAgentOnRegionBatch", args);
|
||||
LLSD args;
|
||||
args["NUM_ADDED"] = llformat("%d",ids.size());
|
||||
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
args["LIST_TYPE"] = "Banned Residents";
|
||||
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotifications::instance().add("MaxAgentOnRegionBatch", args);
|
||||
delete change_info;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LLSD args;
|
||||
args["ALL_ESTATES"] = all_estates_text();
|
||||
|
||||
LLNotification::Params params(change_info->mDialogName);
|
||||
params.substitutions(args)
|
||||
.payload(change_info->asLLSD())
|
||||
.functor(accessCoreConfirm);
|
||||
|
||||
if (isLindenEstate())
|
||||
{
|
||||
// just apply to this estate
|
||||
accessCoreConfirm(0, (void*)change_info);
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ask if this estate or all estates with this owner
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[ALL_ESTATES]"] = all_estates_text();
|
||||
gViewerWindow->alertXml(change_info->mDialogName, args, accessCoreConfirm, (void*)change_info);
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1809,85 +1866,87 @@ void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string&
|
|||
if (list_vector.size() == 0)
|
||||
return;
|
||||
|
||||
LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo;
|
||||
change_info->mOperationFlag = operation_flag;
|
||||
change_info->mDialogName = dialog_name;
|
||||
LLSD payload;
|
||||
payload["operation"] = (S32)operation_flag;
|
||||
payload["dialog_name"] = dialog_name;
|
||||
|
||||
for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin();
|
||||
iter != list_vector.end();
|
||||
iter++)
|
||||
{
|
||||
LLScrollListItem *item = (*iter);
|
||||
change_info->mAgentOrGroupIDs.push_back(item->getUUID());
|
||||
payload["allowed_ids"].append(item->getUUID());
|
||||
}
|
||||
|
||||
LLNotification::Params params("ChangeLindenAccess");
|
||||
params.payload(payload)
|
||||
.functor(accessRemoveCore2);
|
||||
|
||||
if (isLindenEstate())
|
||||
{
|
||||
// warn on change linden estate
|
||||
gViewerWindow->alertXml("ChangeLindenAccess",
|
||||
accessRemoveCore2,
|
||||
(void*)change_info);
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just proceed, as if clicking OK
|
||||
accessRemoveCore2(0, (void*)change_info);
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateInfo::accessRemoveCore2(S32 option, void* data)
|
||||
bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0)
|
||||
{
|
||||
// abort
|
||||
delete change_info;
|
||||
change_info = NULL;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If Linden estate, can only apply to "this" estate, not all estates
|
||||
// owned by NULL.
|
||||
if (isLindenEstate())
|
||||
{
|
||||
accessCoreConfirm(0, (void*)change_info);
|
||||
accessCoreConfirm(notification, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[ALL_ESTATES]"] = all_estates_text();
|
||||
gViewerWindow->alertXml(change_info->mDialogName,
|
||||
args,
|
||||
accessCoreConfirm,
|
||||
(void*)change_info);
|
||||
LLSD args;
|
||||
args["ALL_ESTATES"] = all_estates_text();
|
||||
LLNotifications::instance().add(notification["payload"]["dialog_name"],
|
||||
args,
|
||||
notification["payload"],
|
||||
accessCoreConfirm);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used for both access add and remove operations, depending on the mOperationFlag
|
||||
// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.)
|
||||
// static
|
||||
void LLPanelEstateInfo::accessCoreConfirm(S32 option, void* data)
|
||||
bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
|
||||
const U32 originalFlags = change_info->mOperationFlag;
|
||||
AgentOrGroupIDsVector& ids = change_info->mAgentOrGroupIDs;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger();
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
|
||||
for (AgentOrGroupIDsVector::const_iterator iter = ids.begin();
|
||||
iter != ids.end();
|
||||
LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray();
|
||||
|
||||
for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray();
|
||||
iter != end_it;
|
||||
iter++)
|
||||
{
|
||||
U32 flags = originalFlags;
|
||||
if (iter + 1 != ids.end())
|
||||
if (iter + 1 != end_it)
|
||||
flags |= ESTATE_ACCESS_NO_REPLY;
|
||||
|
||||
const LLUUID id = (*iter);
|
||||
if ((change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD)
|
||||
const LLUUID id = iter->asUUID();
|
||||
if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD)
|
||||
&& region && (region->getOwner() == id))
|
||||
{
|
||||
gViewerWindow->alertXml("OwnerCanNotBeDenied");
|
||||
LLNotifications::instance().add("OwnerCanNotBeDenied");
|
||||
break;
|
||||
}
|
||||
switch(option)
|
||||
|
|
@ -1919,8 +1978,7 @@ void LLPanelEstateInfo::accessCoreConfirm(S32 option, void* data)
|
|||
break;
|
||||
}
|
||||
}
|
||||
delete change_info;
|
||||
change_info = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// key = "estateaccessdelta"
|
||||
|
|
@ -2146,34 +2204,34 @@ BOOL LLPanelEstateInfo::sendUpdate()
|
|||
{
|
||||
llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl;
|
||||
|
||||
LLNotification::Params params("ChangeLindenEstate");
|
||||
params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
|
||||
|
||||
if (getEstateID() <= ESTATE_LAST_LINDEN)
|
||||
{
|
||||
// trying to change reserved estate, warn
|
||||
gViewerWindow->alertXml("ChangeLindenEstate",
|
||||
callbackChangeLindenEstate,
|
||||
this);
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for normal estates, just make the change
|
||||
callbackChangeLindenEstate(0, this);
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateInfo::callbackChangeLindenEstate(S32 option, void* data)
|
||||
bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelEstateInfo* self = (LLPanelEstateInfo*)data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
switch(option)
|
||||
{
|
||||
case 0:
|
||||
// send the update
|
||||
if (!self->commitEstateInfoCaps())
|
||||
if (!commitEstateInfoCaps())
|
||||
{
|
||||
// the caps method failed, try the old way
|
||||
LLFloaterRegionInfo::nextInvoice();
|
||||
self->commitEstateInfoDataserver();
|
||||
commitEstateInfoDataserver();
|
||||
}
|
||||
// we don't want to do this because we'll get it automatically from the sim
|
||||
// after the spaceserver processes it
|
||||
|
|
@ -2188,6 +2246,7 @@ void LLPanelEstateInfo::callbackChangeLindenEstate(S32 option, void* data)
|
|||
// do nothing
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2572,18 +2631,15 @@ BOOL LLPanelEstateInfo::checkSunHourSlider(LLUICtrl* child_ctrl)
|
|||
void LLPanelEstateInfo::onClickMessageEstate(void* userdata)
|
||||
{
|
||||
llinfos << "LLPanelEstateInfo::onClickMessageEstate" << llendl;
|
||||
gViewerWindow->alertXmlEditText("MessageEstate", LLStringUtil::format_map_t(),
|
||||
NULL, NULL,
|
||||
onMessageCommit, userdata);
|
||||
LLNotifications::instance().add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateInfo::onMessageCommit(S32 option, const std::string& text, void* userdata)
|
||||
bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
if(option != 0) return;
|
||||
if(text.empty()) return;
|
||||
LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata;
|
||||
if(!self) return;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
std::string text = response["message"].asString();
|
||||
if(option != 0) return false;
|
||||
if(text.empty()) return false;
|
||||
llinfos << "Message to everyone: " << text << llendl;
|
||||
strings_t strings;
|
||||
//integers_t integers;
|
||||
|
|
@ -2592,7 +2648,8 @@ void LLPanelEstateInfo::onMessageCommit(S32 option, const std::string& text, voi
|
|||
strings.push_back(strings_t::value_type(name));
|
||||
strings.push_back(strings_t::value_type(text));
|
||||
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
|
||||
self->sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings);
|
||||
sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings);
|
||||
return false;
|
||||
}
|
||||
|
||||
LLPanelEstateCovenant::LLPanelEstateCovenant()
|
||||
|
|
@ -2695,9 +2752,10 @@ BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop
|
|||
*accept = ACCEPT_YES_COPY_SINGLE;
|
||||
if (item && drop)
|
||||
{
|
||||
gViewerWindow->alertXml("EstateChangeCovenant",
|
||||
LLPanelEstateCovenant::confirmChangeCovenantCallback,
|
||||
item);
|
||||
LLSD payload;
|
||||
payload["item_id"] = item->getUUID();
|
||||
LLNotifications::instance().add("EstateChangeCovenant", LLSD(), payload,
|
||||
LLPanelEstateCovenant::confirmChangeCovenantCallback);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2709,12 +2767,13 @@ BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop
|
|||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateCovenant::confirmChangeCovenantCallback(S32 option, void* userdata)
|
||||
bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLInventoryItem* item = (LLInventoryItem*)userdata;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
|
||||
LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
|
||||
|
||||
if (!item || !self) return;
|
||||
if (!item || !self) return false;
|
||||
|
||||
switch(option)
|
||||
{
|
||||
|
|
@ -2724,22 +2783,22 @@ void LLPanelEstateCovenant::confirmChangeCovenantCallback(S32 option, void* user
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateCovenant::resetCovenantID(void* userdata)
|
||||
{
|
||||
gViewerWindow->alertXml("EstateChangeCovenant",
|
||||
LLPanelEstateCovenant::confirmResetCovenantCallback,
|
||||
NULL);
|
||||
LLNotifications::instance().add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateCovenant::confirmResetCovenantCallback(S32 option, void* userdata)
|
||||
bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
|
||||
if (!self) return;
|
||||
if (!self) return false;
|
||||
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
switch(option)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -2748,6 +2807,7 @@ void LLPanelEstateCovenant::confirmResetCovenantCallback(S32 option, void* userd
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp)
|
||||
|
|
@ -2808,7 +2868,7 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
|
|||
if( !panelp->mEditor->importBuffer( buffer, file_length+1 ) )
|
||||
{
|
||||
llwarns << "Problem importing estate covenant." << llendl;
|
||||
gViewerWindow->alertXml("ProblemImportingEstateCovenant");
|
||||
LLNotifications::instance().add("ProblemImportingEstateCovenant");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2829,15 +2889,15 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
|
|||
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
|
||||
LL_ERR_FILE_EMPTY == status)
|
||||
{
|
||||
gViewerWindow->alertXml("MissingNotecardAssetID");
|
||||
LLNotifications::instance().add("MissingNotecardAssetID");
|
||||
}
|
||||
else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
|
||||
{
|
||||
gViewerWindow->alertXml("NotAllowedToViewNotecard");
|
||||
LLNotifications::instance().add("NotAllowedToViewNotecard");
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("UnableToLoadNotecard");
|
||||
LLNotifications::instance().add("UnableToLoadNotecardAsset");
|
||||
}
|
||||
|
||||
llwarns << "Problem loading notecard: " << status << llendl;
|
||||
|
|
|
|||
|
|
@ -161,9 +161,9 @@ protected:
|
|||
static void onClickKick(void* userdata);
|
||||
static void onKickCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata);
|
||||
static void onClickKickAll(void* userdata);
|
||||
static void onKickAllCommit(S32 option, void* userdata);
|
||||
bool onKickAllCommit(const LLSD& notification, const LLSD& response);
|
||||
static void onClickMessage(void* userdata);
|
||||
static void onMessageCommit(S32 option, const std::string& text, void* userdata);
|
||||
bool onMessageCommit(const LLSD& notification, const LLSD& response);
|
||||
static void onClickManageTelehub(void* data);
|
||||
};
|
||||
|
||||
|
|
@ -186,11 +186,11 @@ protected:
|
|||
static void onClickChooseAvatar(void*);
|
||||
static void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
|
||||
static void onClickReturn(void *);
|
||||
static void callbackReturn(S32 option, void*);
|
||||
bool callbackReturn(const LLSD& notification, const LLSD& response);
|
||||
static void onClickTopColliders(void*);
|
||||
static void onClickTopScripts(void*);
|
||||
static void onClickRestart(void* data);
|
||||
static void callbackRestart(S32 option, void* data);
|
||||
bool callbackRestart(const LLSD& notification, const LLSD& response);
|
||||
static void onClickCancelRestart(void* data);
|
||||
|
||||
private:
|
||||
|
|
@ -240,7 +240,7 @@ protected:
|
|||
static void onClickDownloadRaw(void*);
|
||||
static void onClickUploadRaw(void*);
|
||||
static void onClickBakeTerrain(void*);
|
||||
static void callbackBakeTerrain(S32 option, void* data);
|
||||
bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -269,27 +269,27 @@ public:
|
|||
static void onClickKickUser(void* userdata);
|
||||
|
||||
// Group picker callback is different, can't use core methods below
|
||||
static void addAllowedGroup(S32 option, void* data);
|
||||
bool addAllowedGroup(const LLSD& notification, const LLSD& response);
|
||||
static void addAllowedGroup2(LLUUID id, void* data);
|
||||
|
||||
// Core methods for all above add/remove button clicks
|
||||
static void accessAddCore(U32 operation_flag, const std::string& dialog_name);
|
||||
static void accessAddCore2(S32 option, void* data);
|
||||
static bool accessAddCore2(const LLSD& notification, const LLSD& response);
|
||||
static void accessAddCore3(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
|
||||
|
||||
static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name);
|
||||
static void accessRemoveCore2(S32 option, void* data);
|
||||
static bool accessRemoveCore2(const LLSD& notification, const LLSD& response);
|
||||
|
||||
// used for both add and remove operations
|
||||
static void accessCoreConfirm(S32 option, void* data);
|
||||
static void kickUserConfirm(S32 option, void* userdata);
|
||||
static bool accessCoreConfirm(const LLSD& notification, const LLSD& response);
|
||||
bool kickUserConfirm(const LLSD& notification, const LLSD& response);
|
||||
|
||||
// Send the actual EstateOwnerRequest "estateaccessdelta" message
|
||||
static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id);
|
||||
|
||||
static void onKickUserCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata);
|
||||
static void onClickMessageEstate(void* data);
|
||||
static void onMessageCommit(S32 option, const std::string& text, void* data);
|
||||
bool onMessageCommit(const LLSD& notification, const LLSD& response);
|
||||
|
||||
LLPanelEstateInfo();
|
||||
~LLPanelEstateInfo() {}
|
||||
|
|
@ -344,7 +344,7 @@ public:
|
|||
protected:
|
||||
virtual BOOL sendUpdate();
|
||||
// confirmation dialog callback
|
||||
static void callbackChangeLindenEstate(S32 opt, void* data);
|
||||
bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void commitEstateInfoDataserver();
|
||||
bool commitEstateInfoCaps();
|
||||
|
|
@ -377,9 +377,9 @@ public:
|
|||
BOOL drop, EDragAndDropType cargo_type,
|
||||
void *cargo_data, EAcceptance *accept,
|
||||
std::string& tooltip_msg);
|
||||
static void confirmChangeCovenantCallback(S32 option, void* userdata);
|
||||
static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response);
|
||||
static void resetCovenantID(void* userdata);
|
||||
static void confirmResetCovenantCallback(S32 option, void* userdata);
|
||||
static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response);
|
||||
void sendChangeCovenantID(const LLUUID &asset_id);
|
||||
void loadInvItem(LLInventoryItem *itemp);
|
||||
static void onLoadComplete(LLVFS *vfs,
|
||||
|
|
|
|||
|
|
@ -207,10 +207,10 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
|
|||
{
|
||||
if ( gEmailToEstateOwner )
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseEmailEO");
|
||||
LLNotifications::instance().add("HelpReportAbuseEmailEO");
|
||||
}
|
||||
else
|
||||
gViewerWindow->alertXml("HelpReportAbuseEmailLL");
|
||||
LLNotifications::instance().add("HelpReportAbuseEmailLL");
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -406,7 +406,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
|
|||
category_value == IP_CONTENT_REMOVAL ||
|
||||
category_value == IP_PERMISSONS_EXPLOIT)
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseContainsCopyright");
|
||||
LLNotifications::instance().add("HelpReportAbuseContainsCopyright");
|
||||
self->mCopyrightWarningSeen = TRUE;
|
||||
return;
|
||||
}
|
||||
|
|
@ -415,7 +415,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
|
|||
{
|
||||
// IP_CONTENT_REMOVAL *always* shows the dialog -
|
||||
// ergo you can never send that abuse report type.
|
||||
gViewerWindow->alertXml("HelpReportAbuseContainsCopyright");
|
||||
LLNotifications::instance().add("HelpReportAbuseContainsCopyright");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -524,7 +524,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
|
|||
|
||||
if (report_type == BUG_REPORT)
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportBug");
|
||||
LLNotifications::instance().add("HelpReportBug");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -610,11 +610,11 @@ bool LLFloaterReporter::validateReport()
|
|||
{
|
||||
if ( mReportType != BUG_REPORT )
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseSelectCategory");
|
||||
LLNotifications::instance().add("HelpReportAbuseSelectCategory");
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportBugSelectCategory");
|
||||
LLNotifications::instance().add("HelpReportBugSelectCategory");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -623,13 +623,13 @@ bool LLFloaterReporter::validateReport()
|
|||
{
|
||||
if ( childGetText("abuser_name_edit").empty() )
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseAbuserNameEmpty");
|
||||
LLNotifications::instance().add("HelpReportAbuseAbuserNameEmpty");
|
||||
return false;
|
||||
};
|
||||
|
||||
if ( childGetText("abuse_location_edit").empty() )
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseAbuserLocationEmpty");
|
||||
LLNotifications::instance().add("HelpReportAbuseAbuserLocationEmpty");
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
|
@ -638,11 +638,11 @@ bool LLFloaterReporter::validateReport()
|
|||
{
|
||||
if ( mReportType != BUG_REPORT )
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseSummaryEmpty");
|
||||
LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportBugSummaryEmpty");
|
||||
LLNotifications::instance().add("HelpReportBugSummaryEmpty");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
@ -651,11 +651,11 @@ bool LLFloaterReporter::validateReport()
|
|||
{
|
||||
if ( mReportType != BUG_REPORT )
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportAbuseDetailsEmpty");
|
||||
LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("HelpReportBugDetailsEmpty");
|
||||
LLNotifications::instance().add("HelpReportBugDetailsEmpty");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
@ -951,13 +951,12 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
|
|||
|
||||
if(result < 0)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
std::string reason = std::string(LLAssetStorage::getErrorString(result));
|
||||
args["[REASON]"] = reason;
|
||||
gViewerWindow->alertXml("ErrorUploadingReportScreenshot", args);
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
|
||||
LLNotifications::instance().add("ErrorUploadingReportScreenshot", args);
|
||||
|
||||
std::string err_msg("There was a problem uploading a report screenshot");
|
||||
err_msg += " due to the following reason: " + reason;
|
||||
err_msg += " due to the following reason: " + args["REASON"].asString();
|
||||
llwarns << err_msg << llendl;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ private:
|
|||
static void doSelectAgent(void *userdata);
|
||||
static void doCancel(void *userdata);
|
||||
static void doSellLand(void *userdata);
|
||||
static void onConfirmSale(S32 option, void *userdata);
|
||||
bool onConfirmSale(const LLSD& notification, const LLSD& response);
|
||||
static void doShowObjects(void *userdata);
|
||||
static void callbackHighlightTransferable(S32 option, void* userdata);
|
||||
static bool callbackHighlightTransferable(const LLSD& notification, const LLSD& response);
|
||||
|
||||
static void callbackAvatarPick(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
|
||||
|
||||
|
|
@ -443,15 +443,16 @@ void LLFloaterSellLandUI::doShowObjects(void *userdata)
|
|||
|
||||
send_parcel_select_objects(parcel->getLocalID(), RT_SELL);
|
||||
|
||||
LLNotifyBox::showXml("TransferObjectsHighlighted",
|
||||
callbackHighlightTransferable,
|
||||
userdata);
|
||||
LLNotifications::instance().add("TransferObjectsHighlighted",
|
||||
LLSD(), LLSD(),
|
||||
&LLFloaterSellLandUI::callbackHighlightTransferable);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSellLandUI::callbackHighlightTransferable(S32 option, void* userdata)
|
||||
bool LLFloaterSellLandUI::callbackHighlightTransferable(const LLSD& notification, const LLSD& data)
|
||||
{
|
||||
LLSelectMgr::getInstance()->unhighlightAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -462,83 +463,89 @@ void LLFloaterSellLandUI::doSellLand(void *userdata)
|
|||
LLParcel* parcel = self->mParcelSelection->getParcel();
|
||||
|
||||
// Do a confirmation
|
||||
if (!parcel->getForSale())
|
||||
S32 sale_price = self->childGetValue("price");
|
||||
S32 area = parcel->getArea();
|
||||
std::string authorizedBuyerName = "Anyone";
|
||||
bool sell_to_anyone = true;
|
||||
if ("user" == self->childGetValue("sell_to").asString())
|
||||
{
|
||||
S32 sale_price = self->childGetValue("price");
|
||||
S32 area = parcel->getArea();
|
||||
std::string authorizedBuyerName = "Anyone";
|
||||
bool sell_to_anyone = true;
|
||||
if ("user" == self->childGetValue("sell_to").asString())
|
||||
{
|
||||
authorizedBuyerName = self->childGetText("sell_to_agent");
|
||||
sell_to_anyone = false;
|
||||
}
|
||||
authorizedBuyerName = self->childGetText("sell_to_agent");
|
||||
sell_to_anyone = false;
|
||||
}
|
||||
|
||||
// must sell to someone if indicating sale to anyone
|
||||
if ((sale_price == 0) && sell_to_anyone)
|
||||
{
|
||||
gViewerWindow->alertXml("SalePriceRestriction");
|
||||
return;
|
||||
}
|
||||
// must sell to someone if indicating sale to anyone
|
||||
if (!parcel->getForSale()
|
||||
&& (sale_price == 0)
|
||||
&& sell_to_anyone)
|
||||
{
|
||||
LLNotifications::instance().add("SalePriceRestriction");
|
||||
return;
|
||||
}
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[LAND_SIZE]"] = llformat("%d",area);
|
||||
args["[SALE_PRICE]"] = llformat("%d",sale_price);
|
||||
args["[NAME]"] = authorizedBuyerName;
|
||||
LLSD args;
|
||||
args["LAND_SIZE"] = llformat("%d",area);
|
||||
args["SALE_PRICE"] = llformat("%d",sale_price);
|
||||
args["NAME"] = authorizedBuyerName;
|
||||
|
||||
if (sell_to_anyone)
|
||||
{
|
||||
gViewerWindow->alertXml("ConfirmLandSaleToAnyoneChange", args, onConfirmSale, self);
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ConfirmLandSaleChange", args, onConfirmSale, self);
|
||||
}
|
||||
LLNotification::Params params("ConfirmLandSaleChange");
|
||||
params.substitutions(args)
|
||||
.functor(boost::bind(&LLFloaterSellLandUI::onConfirmSale, self, _1, _2));
|
||||
|
||||
if (sell_to_anyone)
|
||||
{
|
||||
params.name("ConfirmLandSaleToAnyoneChange");
|
||||
}
|
||||
|
||||
if (parcel->getForSale())
|
||||
{
|
||||
// parcel already for sale, so ignore this question
|
||||
LLNotifications::instance().forceResponse(params, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
onConfirmSale(-1, self);
|
||||
// ask away
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSellLandUI::onConfirmSale(S32 option, void *userdata)
|
||||
bool LLFloaterSellLandUI::onConfirmSale(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option != 0)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
|
||||
S32 sale_price = self->childGetValue("price");
|
||||
S32 sale_price = childGetValue("price");
|
||||
|
||||
// Valid extracted data
|
||||
if (sale_price < 0)
|
||||
{
|
||||
// TomY TODO: Throw an error
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
LLParcel* parcel = self->mParcelSelection->getParcel();
|
||||
if (!parcel) return;
|
||||
LLParcel* parcel = mParcelSelection->getParcel();
|
||||
if (!parcel) return false;
|
||||
|
||||
// can_agent_modify_parcel deprecated by GROUPS
|
||||
// if (!can_agent_modify_parcel(parcel))
|
||||
// {
|
||||
// self->close();
|
||||
// close();
|
||||
// return;
|
||||
// }
|
||||
|
||||
parcel->setParcelFlag(PF_FOR_SALE, TRUE);
|
||||
parcel->setSalePrice(sale_price);
|
||||
bool sell_with_objects = false;
|
||||
if ("yes" == self->childGetValue("sell_objects").asString())
|
||||
if ("yes" == childGetValue("sell_objects").asString())
|
||||
{
|
||||
sell_with_objects = true;
|
||||
}
|
||||
parcel->setSellWithObjects(sell_with_objects);
|
||||
if ("user" == self->childGetValue("sell_to").asString())
|
||||
if ("user" == childGetValue("sell_to").asString())
|
||||
{
|
||||
parcel->setAuthorizedBuyerID(self->mAuthorizedBuyer);
|
||||
parcel->setAuthorizedBuyerID(mAuthorizedBuyer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -548,5 +555,6 @@ void LLFloaterSellLandUI::onConfirmSale(S32 option, void *userdata)
|
|||
// Send update to server
|
||||
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
|
||||
|
||||
self->close();
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -966,7 +966,7 @@ void LLSnapshotLivePreview::saveTexture()
|
|||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ErrorEncodingSnapshot");
|
||||
LLNotifications::instance().add("ErrorEncodingSnapshot");
|
||||
llwarns << "Error encoding snapshot" << llendl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -353,17 +353,19 @@ void LLFloaterTopObjects::doToObjects(int action, bool all)
|
|||
}
|
||||
|
||||
//static
|
||||
void LLFloaterTopObjects::callbackReturnAll(S32 option, void* userdata)
|
||||
bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
sInstance->doToObjects(ACTION_RETURN, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterTopObjects::onReturnAll(void* data)
|
||||
{
|
||||
gViewerWindow->alertXml("ReturnAllTopObjects", callbackReturnAll, NULL);
|
||||
LLNotifications::instance().add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -374,17 +376,19 @@ void LLFloaterTopObjects::onReturnSelected(void* data)
|
|||
|
||||
|
||||
//static
|
||||
void LLFloaterTopObjects::callbackDisableAll(S32 option, void* userdata)
|
||||
bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
sInstance->doToObjects(ACTION_DISABLE, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterTopObjects::onDisableAll(void* data)
|
||||
{
|
||||
gViewerWindow->alertXml("DisableAllTopObjects", callbackDisableAll, NULL);
|
||||
LLNotifications::instance().add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
|
||||
}
|
||||
|
||||
void LLFloaterTopObjects::onDisableSelected(void* data)
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ private:
|
|||
static void onDisableAll(void* data);
|
||||
static void onDisableSelected(void* data);
|
||||
|
||||
static void callbackReturnAll(S32 option, void* userdata);
|
||||
static void callbackDisableAll(S32 option, void* userdata);
|
||||
static bool callbackReturnAll(const LLSD& notification, const LLSD& response);
|
||||
static bool callbackDisableAll(const LLSD& notification, const LLSD& response);
|
||||
|
||||
static void onGetByOwnerName(LLUICtrl* ctrl, void* data);
|
||||
static void onGetByObjectName(LLUICtrl* ctrl, void* data);
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ void LLFloaterTOS::onCancel( void* userdata )
|
|||
{
|
||||
LLFloaterTOS* self = (LLFloaterTOS*) userdata;
|
||||
llinfos << "User disagrees with TOS." << llendl;
|
||||
gViewerWindow->alertXml("MustAgreeToLogIn", login_alert_done);
|
||||
LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done);
|
||||
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
|
||||
self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS
|
||||
self->close(); // destroys this object
|
||||
|
|
|
|||
|
|
@ -262,32 +262,30 @@ void LLFloaterURLEntry::onBtnCancel( void* userdata )
|
|||
//-----------------------------------------------------------------------------
|
||||
void LLFloaterURLEntry::onBtnClear( void* userdata )
|
||||
{
|
||||
gViewerWindow->alertXml( "ConfirmClearMediaUrlList", callback_clear_url_list, userdata );
|
||||
LLNotifications::instance().add( "ConfirmClearMediaUrlList", LLSD(), LLSD(),
|
||||
boost::bind(&LLFloaterURLEntry::callback_clear_url_list, (LLFloaterURLEntry*)userdata, _1, _2) );
|
||||
}
|
||||
|
||||
void LLFloaterURLEntry::callback_clear_url_list(S32 option, void* userdata)
|
||||
bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if ( option == 0 ) // YES
|
||||
{
|
||||
LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata;
|
||||
|
||||
if ( self )
|
||||
// clear saved list
|
||||
LLCtrlListInterface* url_list = childGetListInterface("media_entry");
|
||||
if ( url_list )
|
||||
{
|
||||
// clear saved list
|
||||
LLCtrlListInterface* url_list = self->childGetListInterface("media_entry");
|
||||
if ( url_list )
|
||||
{
|
||||
url_list->operateOnAll( LLCtrlListInterface::OP_DELETE );
|
||||
}
|
||||
|
||||
// clear current contents of combo box
|
||||
self->mMediaURLEdit->clear();
|
||||
|
||||
// clear stored version of list
|
||||
LLURLHistory::clear("parcel");
|
||||
|
||||
// cleared the list so disable Clear button
|
||||
self->childSetEnabled( "clear_btn", false );
|
||||
url_list->operateOnAll( LLCtrlListInterface::OP_DELETE );
|
||||
}
|
||||
|
||||
// clear current contents of combo box
|
||||
mMediaURLEdit->clear();
|
||||
|
||||
// clear stored version of list
|
||||
LLURLHistory::clear("parcel");
|
||||
|
||||
// cleared the list so disable Clear button
|
||||
childSetEnabled( "clear_btn", false );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ private:
|
|||
static void onBtnOK(void*);
|
||||
static void onBtnCancel(void*);
|
||||
static void onBtnClear(void*);
|
||||
static void callback_clear_url_list(S32 option, void* userdata);
|
||||
bool callback_clear_url_list(const LLSD& notification, const LLSD& response);
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERURLENTRY_H
|
||||
|
|
|
|||
|
|
@ -176,15 +176,7 @@ void LLFloaterWater::onClickHelp(void* data)
|
|||
LLFloaterWater* self = LLFloaterWater::instance();
|
||||
|
||||
const std::string* xml_alert = (std::string*)data;
|
||||
LLAlertDialog* dialogp = gViewerWindow->alertXml(*xml_alert);
|
||||
if (dialogp)
|
||||
{
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(self);
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(dialogp);
|
||||
}
|
||||
}
|
||||
LLNotifications::instance().add(self->contextualNotification(*xml_alert));
|
||||
}
|
||||
|
||||
void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml_alert)
|
||||
|
|
@ -192,11 +184,14 @@ void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml
|
|||
childSetAction(name, onClickHelp, new std::string(xml_alert));
|
||||
}
|
||||
|
||||
void LLFloaterWater::newPromptCallback(S32 option, const std::string& text, void* userData)
|
||||
bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
std::string text = response["message"].asString();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
if(text == "")
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(option == 0) {
|
||||
|
|
@ -224,9 +219,10 @@ void LLFloaterWater::newPromptCallback(S32 option, const std::string& text, void
|
|||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ExistsWaterPresetAlert");
|
||||
LLNotifications::instance().add("ExistsWaterPresetAlert");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterWater::syncMenu()
|
||||
|
|
@ -596,8 +592,7 @@ void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData)
|
|||
|
||||
void LLFloaterWater::onNewPreset(void* userData)
|
||||
{
|
||||
gViewerWindow->alertXmlEditText("NewWaterPreset", LLStringUtil::format_map_t(),
|
||||
NULL, NULL, newPromptCallback, NULL);
|
||||
LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), newPromptCallback);
|
||||
}
|
||||
|
||||
void LLFloaterWater::onSavePreset(void* userData)
|
||||
|
|
@ -619,15 +614,16 @@ void LLFloaterWater::onSavePreset(void* userData)
|
|||
comboBox->getSelectedItemLabel());
|
||||
if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("WaterEditPresets"))
|
||||
{
|
||||
gViewerWindow->alertXml("WLNoEditDefault");
|
||||
LLNotifications::instance().add("WLNoEditDefault");
|
||||
return;
|
||||
}
|
||||
|
||||
gViewerWindow->alertXml("WLSavePresetAlert", saveAlertCallback, sWaterMenu);
|
||||
LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback);
|
||||
}
|
||||
|
||||
void LLFloaterWater::saveAlertCallback(S32 option, void* userdata)
|
||||
bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
// if they choose save, do it. Otherwise, don't do anything
|
||||
if(option == 0)
|
||||
{
|
||||
|
|
@ -640,7 +636,7 @@ void LLFloaterWater::saveAlertCallback(S32 option, void* userdata)
|
|||
// comment this back in to save to file
|
||||
param_mgr->savePreset(param_mgr->mCurParams.mName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterWater::onDeletePreset(void* userData)
|
||||
|
|
@ -652,13 +648,14 @@ void LLFloaterWater::onDeletePreset(void* userData)
|
|||
return;
|
||||
}
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[SKY]"] = combo_box->getSelectedValue().asString();
|
||||
gViewerWindow->alertXml("WLDeletePresetAlert", args, deleteAlertCallback, sWaterMenu);
|
||||
LLSD args;
|
||||
args["SKY"] = combo_box->getSelectedValue().asString();
|
||||
LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback);
|
||||
}
|
||||
|
||||
void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata)
|
||||
bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
// if they choose delete, do it. Otherwise, don't do anything
|
||||
if(option == 0)
|
||||
{
|
||||
|
|
@ -680,8 +677,8 @@ void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata)
|
|||
std::set<std::string>::iterator sIt = sDefaultPresets.find(name);
|
||||
if(sIt != sDefaultPresets.end())
|
||||
{
|
||||
gViewerWindow->alertXml("WaterNoEditDefault");
|
||||
return;
|
||||
LLNotifications::instance().add("WaterNoEditDefault");
|
||||
return false;
|
||||
}
|
||||
|
||||
LLWaterParamManager::instance()->removeParamSet(name, true);
|
||||
|
|
@ -710,6 +707,7 @@ void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata)
|
|||
combo_box->setCurrentByIndex(new_index);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public:
|
|||
static void onClickHelp(void* data);
|
||||
void initHelpBtn(const std::string& name, const std::string& xml_alert);
|
||||
|
||||
static void newPromptCallback(S32 option, const std::string& text, void* userData);
|
||||
static bool newPromptCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// general purpose callbacks for dealing with color controllers
|
||||
static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
|
||||
|
|
@ -97,13 +97,13 @@ public:
|
|||
static void onSavePreset(void* userData);
|
||||
|
||||
/// prompts a user when overwriting a preset
|
||||
static void saveAlertCallback(S32 option, void* userdata);
|
||||
static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// when user hits the save preset button
|
||||
static void onDeletePreset(void* userData);
|
||||
|
||||
/// prompts a user when overwriting a preset
|
||||
static void deleteAlertCallback(S32 option, void* userdata);
|
||||
static bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// what to do when you change the preset name
|
||||
static void onChangePresetName(LLUICtrl* ctrl, void* userData);
|
||||
|
|
|
|||
|
|
@ -233,16 +233,8 @@ void LLFloaterWindLight::onClickHelp(void* data)
|
|||
{
|
||||
LLFloaterWindLight* self = LLFloaterWindLight::instance();
|
||||
|
||||
const std::string* xml_alert = (std::string*)data;
|
||||
LLAlertDialog* dialogp = gViewerWindow->alertXml(*xml_alert);
|
||||
if (dialogp)
|
||||
{
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(self);
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(dialogp);
|
||||
}
|
||||
}
|
||||
const std::string xml_alert = *(std::string*)data;
|
||||
LLNotifications::instance().add(self->contextualNotification(xml_alert));
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string& xml_alert)
|
||||
|
|
@ -250,11 +242,14 @@ void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string&
|
|||
childSetAction(name, onClickHelp, new std::string(xml_alert));
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::newPromptCallback(S32 option, const std::string& text, void* userData)
|
||||
bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
std::string text = response["message"].asString();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
if(text == "")
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(option == 0) {
|
||||
|
|
@ -303,9 +298,10 @@ void LLFloaterWindLight::newPromptCallback(S32 option, const std::string& text,
|
|||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->alertXml("ExistsSkyPresetAlert");
|
||||
LLNotifications::instance().add("ExistsSkyPresetAlert");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::syncMenu()
|
||||
|
|
@ -784,8 +780,7 @@ void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData)
|
|||
|
||||
void LLFloaterWindLight::onNewPreset(void* userData)
|
||||
{
|
||||
gViewerWindow->alertXmlEditText("NewSkyPreset", LLStringUtil::format_map_t(),
|
||||
NULL, NULL, newPromptCallback, NULL);
|
||||
LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback);
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::onSavePreset(void* userData)
|
||||
|
|
@ -805,18 +800,19 @@ void LLFloaterWindLight::onSavePreset(void* userData)
|
|||
comboBox->getSelectedItemLabel());
|
||||
if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets"))
|
||||
{
|
||||
gViewerWindow->alertXml("WLNoEditDefault");
|
||||
LLNotifications::instance().add("WLNoEditDefault");
|
||||
return;
|
||||
}
|
||||
|
||||
LLWLParamManager::instance()->mCurParams.mName =
|
||||
comboBox->getSelectedItemLabel();
|
||||
|
||||
gViewerWindow->alertXml("WLSavePresetAlert", saveAlertCallback, sWindLight);
|
||||
LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback);
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::saveAlertCallback(S32 option, void* userdata)
|
||||
bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
// if they choose save, do it. Otherwise, don't do anything
|
||||
if(option == 0)
|
||||
{
|
||||
|
|
@ -827,7 +823,7 @@ void LLFloaterWindLight::saveAlertCallback(S32 option, void* userdata)
|
|||
// comment this back in to save to file
|
||||
param_mgr->savePreset(param_mgr->mCurParams.mName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::onDeletePreset(void* userData)
|
||||
|
|
@ -840,17 +836,20 @@ void LLFloaterWindLight::onDeletePreset(void* userData)
|
|||
return;
|
||||
}
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[SKY]"] = combo_box->getSelectedValue().asString();
|
||||
gViewerWindow->alertXml("WLDeletePresetAlert", args, deleteAlertCallback, sWindLight);
|
||||
LLSD args;
|
||||
args["SKY"] = combo_box->getSelectedValue().asString();
|
||||
LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(),
|
||||
boost::bind(&LLFloaterWindLight::deleteAlertCallback, sWindLight, _1, _2));
|
||||
}
|
||||
|
||||
void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata)
|
||||
bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
// if they choose delete, do it. Otherwise, don't do anything
|
||||
if(option == 0)
|
||||
{
|
||||
LLComboBox* combo_box = sWindLight->getChild<LLComboBox>(
|
||||
LLComboBox* combo_box = getChild<LLComboBox>(
|
||||
"WLPresetsCombo");
|
||||
LLFloaterDayCycle* day_cycle = NULL;
|
||||
LLComboBox* key_combo = NULL;
|
||||
|
|
@ -870,8 +869,8 @@ void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata)
|
|||
std::set<std::string>::iterator sIt = sDefaultPresets.find(name);
|
||||
if(sIt != sDefaultPresets.end())
|
||||
{
|
||||
gViewerWindow->alertXml("WLNoEditDefault");
|
||||
return;
|
||||
LLNotifications::instance().add("WLNoEditDefault");
|
||||
return false;
|
||||
}
|
||||
|
||||
LLWLParamManager::instance()->removeParamSet(name, true);
|
||||
|
|
@ -899,6 +898,7 @@ void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata)
|
|||
combo_box->setCurrentByIndex(new_index);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public:
|
|||
static void onClickHelp(void* data);
|
||||
void initHelpBtn(const std::string& name, const std::string& xml_alert);
|
||||
|
||||
static void newPromptCallback(S32 option, const std::string& text, void* userData);
|
||||
static bool newPromptCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// general purpose callbacks for dealing with color controllers
|
||||
static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
|
||||
|
|
@ -94,13 +94,13 @@ public:
|
|||
static void onSavePreset(void* userData);
|
||||
|
||||
/// prompts a user when overwriting a preset
|
||||
static void saveAlertCallback(S32 option, void* userdata);
|
||||
static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// when user hits the save preset button
|
||||
static void onDeletePreset(void* userData);
|
||||
|
||||
/// prompts a user when overwriting a preset
|
||||
static void deleteAlertCallback(S32 option, void* userdata);
|
||||
bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/// what to do when you change the preset name
|
||||
static void onChangePresetName(LLUICtrl* ctrl, void* userData);
|
||||
|
|
|
|||
|
|
@ -1303,10 +1303,10 @@ void LLFloaterWorldMap::onCopySLURL(void* data)
|
|||
LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
|
||||
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(self->mSLURL));
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[SLURL]"] = self->mSLURL;
|
||||
LLSD args;
|
||||
args["SLURL"] = self->mSLURL;
|
||||
|
||||
LLAlertDialog::showXml("CopySLURL", args);
|
||||
LLNotifications::instance().add("CopySLURL", args);
|
||||
}
|
||||
|
||||
void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data)
|
||||
|
|
|
|||
|
|
@ -952,9 +952,9 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
|
|||
&& gGestureManager.mDeactivateSimilarNames.length() > 0)
|
||||
{
|
||||
// we're done with this set of deactivations
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAMES]"] = gGestureManager.mDeactivateSimilarNames;
|
||||
LLNotifyBox::showXml("DeactivatedGesturesTrigger", args);
|
||||
LLSD args;
|
||||
args["NAMES"] = gGestureManager.mDeactivateSimilarNames;
|
||||
LLNotifications::instance().add("DeactivatedGesturesTrigger", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1288,9 +1288,9 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
|
|||
else
|
||||
{
|
||||
// *TODO:translate
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MESSAGE]"] = message;
|
||||
gViewerWindow->alertXml("UnableToCreateGroup", args);
|
||||
LLSD args;
|
||||
args["MESSAGE"] = message;
|
||||
LLNotifications::instance().add("UnableToCreateGroup", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,13 +306,13 @@ void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
|
|||
if ( 403 == status )
|
||||
{
|
||||
//403 == no ability
|
||||
LLNotifyBox::showXml(
|
||||
LLNotifications::instance().add(
|
||||
"VoiceNotAllowed",
|
||||
channelp->getNotifyArgs());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotifyBox::showXml(
|
||||
LLNotifications::instance().add(
|
||||
"VoiceCallGenericError",
|
||||
channelp->getNotifyArgs());
|
||||
}
|
||||
|
|
@ -348,7 +348,7 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& sess
|
|||
mSessionName(session_name),
|
||||
mIgnoreNextSessionLeave(FALSE)
|
||||
{
|
||||
mNotifyArgs["[VOICE_CHANNEL_NAME]"] = mSessionName;
|
||||
mNotifyArgs["VOICE_CHANNEL_NAME"] = mSessionName;
|
||||
|
||||
if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second)
|
||||
{
|
||||
|
|
@ -384,13 +384,13 @@ void LLVoiceChannel::setChannelInfo(
|
|||
{
|
||||
if (mURI.empty())
|
||||
{
|
||||
LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs);
|
||||
LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs);
|
||||
llwarns << "Received empty URI for channel " << mSessionName << llendl;
|
||||
deactivate();
|
||||
}
|
||||
else if (mCredentials.empty())
|
||||
{
|
||||
LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs);
|
||||
LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs);
|
||||
llwarns << "Received empty credentials for channel " << mSessionName << llendl;
|
||||
deactivate();
|
||||
}
|
||||
|
|
@ -433,25 +433,26 @@ void LLVoiceChannel::handleStatusChange(EStatusType type)
|
|||
switch(type)
|
||||
{
|
||||
case STATUS_LOGIN_RETRY:
|
||||
mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle();
|
||||
//mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle();
|
||||
LLNotifications::instance().add("VoiceLoginRetry");
|
||||
break;
|
||||
case STATUS_LOGGED_IN:
|
||||
if (!mLoginNotificationHandle.isDead())
|
||||
{
|
||||
LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get();
|
||||
if (notifyp)
|
||||
{
|
||||
notifyp->close();
|
||||
}
|
||||
mLoginNotificationHandle.markDead();
|
||||
}
|
||||
//if (!mLoginNotificationHandle.isDead())
|
||||
//{
|
||||
// LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get();
|
||||
// if (notifyp)
|
||||
// {
|
||||
// notifyp->close();
|
||||
// }
|
||||
// mLoginNotificationHandle.markDead();
|
||||
//}
|
||||
break;
|
||||
case STATUS_LEFT_CHANNEL:
|
||||
if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended)
|
||||
{
|
||||
// if forceably removed from channel
|
||||
// update the UI and revert to default channel
|
||||
LLNotifyBox::showXml("VoiceChannelDisconnected", mNotifyArgs);
|
||||
LLNotifications::instance().add("VoiceChannelDisconnected", mNotifyArgs);
|
||||
deactivate();
|
||||
}
|
||||
mIgnoreNextSessionLeave = FALSE;
|
||||
|
|
@ -793,9 +794,9 @@ void LLVoiceChannelGroup::handleError(EStatusType status)
|
|||
// notification
|
||||
if (!notify.empty())
|
||||
{
|
||||
LLNotifyBox::showXml(notify, mNotifyArgs);
|
||||
LLNotificationPtr notification = LLNotifications::instance().add(notify, mNotifyArgs);
|
||||
// echo to im window
|
||||
gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, LLNotifyBox::getTemplateMessage(notify, mNotifyArgs));
|
||||
gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, notification->getMessage());
|
||||
}
|
||||
|
||||
LLVoiceChannel::handleError(status);
|
||||
|
|
@ -896,7 +897,7 @@ void LLVoiceChannelProximal::handleError(EStatusType status)
|
|||
// notification
|
||||
if (!notify.empty())
|
||||
{
|
||||
LLNotifyBox::showXml(notify, mNotifyArgs);
|
||||
LLNotifications::instance().add(notify, mNotifyArgs);
|
||||
}
|
||||
|
||||
LLVoiceChannel::handleError(status);
|
||||
|
|
@ -934,12 +935,12 @@ void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
|
|||
if (mState == STATE_RINGING)
|
||||
{
|
||||
// other user declined call
|
||||
LLNotifyBox::showXml("P2PCallDeclined", mNotifyArgs);
|
||||
LLNotifications::instance().add("P2PCallDeclined", mNotifyArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// other user hung up
|
||||
LLNotifyBox::showXml("VoiceChannelDisconnectedP2P", mNotifyArgs);
|
||||
LLNotifications::instance().add("VoiceChannelDisconnectedP2P", mNotifyArgs);
|
||||
}
|
||||
deactivate();
|
||||
}
|
||||
|
|
@ -957,7 +958,7 @@ void LLVoiceChannelP2P::handleError(EStatusType type)
|
|||
switch(type)
|
||||
{
|
||||
case ERROR_NOT_AVAILABLE:
|
||||
LLNotifyBox::showXml("P2PCallNoAnswer", mNotifyArgs);
|
||||
LLNotifications::instance().add("P2PCallNoAnswer", mNotifyArgs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -2213,35 +2214,33 @@ void LLFloaterIMPanel::showSessionStartError(
|
|||
//their own XML file which would be read in by any LLIMPanel
|
||||
//post build function instead of repeating the same info
|
||||
//in the group, adhoc and normal IM xml files.
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] =
|
||||
LLSD args;
|
||||
args["REASON"] =
|
||||
LLFloaterIM::sErrorStringsMap[error_string];
|
||||
args["[RECIPIENT]"] = getTitle();
|
||||
args["RECIPIENT"] = getTitle();
|
||||
|
||||
gViewerWindow->alertXml(
|
||||
LLSD payload;
|
||||
payload["session_id"] = mSessionUUID;
|
||||
|
||||
LLNotifications::instance().add(
|
||||
"ChatterBoxSessionStartError",
|
||||
args,
|
||||
onConfirmForceCloseError,
|
||||
new LLUUID(mSessionUUID));
|
||||
payload,
|
||||
onConfirmForceCloseError);
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::showSessionEventError(
|
||||
const std::string& event_string,
|
||||
const std::string& error_string)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
std::string event;
|
||||
LLSD args;
|
||||
args["REASON"] =
|
||||
LLFloaterIM::sErrorStringsMap[error_string];
|
||||
args["EVENT"] =
|
||||
LLFloaterIM::sEventStringsMap[event_string];
|
||||
args["RECIPIENT"] = getTitle();
|
||||
|
||||
event = LLFloaterIM::sEventStringsMap[event_string];
|
||||
args["[RECIPIENT]"] = getTitle();
|
||||
LLStringUtil::format(event, args);
|
||||
|
||||
|
||||
args = LLStringUtil::format_map_t();
|
||||
args["[REASON]"] = LLFloaterIM::sErrorStringsMap[error_string];
|
||||
args["[EVENT]"] = event;
|
||||
|
||||
gViewerWindow->alertXml(
|
||||
LLNotifications::instance().add(
|
||||
"ChatterBoxSessionEventError",
|
||||
args);
|
||||
}
|
||||
|
|
@ -2249,16 +2248,19 @@ void LLFloaterIMPanel::showSessionEventError(
|
|||
void LLFloaterIMPanel::showSessionForceClose(
|
||||
const std::string& reason_string)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
LLSD args;
|
||||
|
||||
args["[NAME]"] = getTitle();
|
||||
args["[REASON]"] = LLFloaterIM::sForceCloseSessionMap[reason_string];
|
||||
args["NAME"] = getTitle();
|
||||
args["REASON"] = LLFloaterIM::sForceCloseSessionMap[reason_string];
|
||||
|
||||
gViewerWindow->alertXml(
|
||||
LLSD payload;
|
||||
payload["session_id"] = mSessionUUID;
|
||||
|
||||
LLNotifications::instance().add(
|
||||
"ForceCloseChatterBoxSession",
|
||||
args,
|
||||
LLFloaterIMPanel::onConfirmForceCloseError,
|
||||
new LLUUID(mSessionUUID));
|
||||
payload,
|
||||
LLFloaterIMPanel::onConfirmForceCloseError);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -2268,10 +2270,10 @@ void LLFloaterIMPanel::onKickSpeaker(void* user_data)
|
|||
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data)
|
||||
bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
//only 1 option really
|
||||
LLUUID session_id = *((LLUUID*) data);
|
||||
LLUUID session_id = notification["payload"]["session_id"];
|
||||
|
||||
if ( gIMMgr )
|
||||
{
|
||||
|
|
@ -2280,6 +2282,7 @@ void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data)
|
|||
|
||||
if ( floaterp ) floaterp->close(FALSE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public:
|
|||
EState getState() { return mState; }
|
||||
|
||||
void updateSessionID(const LLUUID& new_session_id);
|
||||
const LLStringUtil::format_map_t& getNotifyArgs() { return mNotifyArgs; }
|
||||
const LLSD& getNotifyArgs() { return mNotifyArgs; }
|
||||
|
||||
static LLVoiceChannel* getChannelByID(const LLUUID& session_id);
|
||||
static LLVoiceChannel* getChannelByURI(std::string uri);
|
||||
|
|
@ -100,7 +100,7 @@ protected:
|
|||
LLUUID mSessionID;
|
||||
EState mState;
|
||||
std::string mSessionName;
|
||||
LLStringUtil::format_map_t mNotifyArgs;
|
||||
LLSD mNotifyArgs;
|
||||
BOOL mIgnoreNextSessionLeave;
|
||||
LLHandle<LLPanel> mLoginNotificationHandle;
|
||||
|
||||
|
|
@ -266,7 +266,7 @@ public:
|
|||
const std::string& error_string);
|
||||
void showSessionForceClose(const std::string& reason);
|
||||
|
||||
static void onConfirmForceCloseError(S32 option, void* data);
|
||||
static bool onConfirmForceCloseError(const LLSD& notification, const LLSD& response);
|
||||
|
||||
private:
|
||||
// called by constructors
|
||||
|
|
|
|||
|
|
@ -97,6 +97,96 @@ std::map<std::string,std::string> LLFloaterIM::sForceCloseSessionMap;
|
|||
// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0);
|
||||
//}
|
||||
|
||||
class LLViewerChatterBoxInvitationAcceptResponder :
|
||||
public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
LLViewerChatterBoxInvitationAcceptResponder(
|
||||
const LLUUID& session_id,
|
||||
LLIMMgr::EInvitationType invitation_type)
|
||||
{
|
||||
mSessionID = session_id;
|
||||
mInvitiationType = invitation_type;
|
||||
}
|
||||
|
||||
void result(const LLSD& content)
|
||||
{
|
||||
if ( gIMMgr)
|
||||
{
|
||||
LLFloaterIMPanel* floaterp =
|
||||
gIMMgr->findFloaterBySession(mSessionID);
|
||||
|
||||
if (floaterp)
|
||||
{
|
||||
//we've accepted our invitation
|
||||
//and received a list of agents that were
|
||||
//currently in the session when the reply was sent
|
||||
//to us. Now, it is possible that there were some agents
|
||||
//to slip in/out between when that message was sent to us
|
||||
//and now.
|
||||
|
||||
//the agent list updates we've received have been
|
||||
//accurate from the time we were added to the session
|
||||
//but unfortunately, our base that we are receiving here
|
||||
//may not be the most up to date. It was accurate at
|
||||
//some point in time though.
|
||||
floaterp->setSpeakers(content);
|
||||
|
||||
//we now have our base of users in the session
|
||||
//that was accurate at some point, but maybe not now
|
||||
//so now we apply all of the udpates we've received
|
||||
//in case of race conditions
|
||||
floaterp->updateSpeakersList(
|
||||
gIMMgr->getPendingAgentListUpdates(mSessionID));
|
||||
|
||||
if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
|
||||
{
|
||||
floaterp->requestAutoConnect();
|
||||
LLFloaterIMPanel::onClickStartCall(floaterp);
|
||||
// always open IM window when connecting to voice
|
||||
LLFloaterChatterBox::showInstance(TRUE);
|
||||
}
|
||||
else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
|
||||
{
|
||||
LLFloaterChatterBox::showInstance(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(mSessionID);
|
||||
gIMMgr->clearPendingInvitation(mSessionID);
|
||||
}
|
||||
}
|
||||
|
||||
void error(U32 statusNum, const std::string& reason)
|
||||
{
|
||||
//throw something back to the viewer here?
|
||||
if ( gIMMgr )
|
||||
{
|
||||
gIMMgr->clearPendingAgentListUpdates(mSessionID);
|
||||
gIMMgr->clearPendingInvitation(mSessionID);
|
||||
|
||||
LLFloaterIMPanel* floaterp =
|
||||
gIMMgr->findFloaterBySession(mSessionID);
|
||||
|
||||
if ( floaterp )
|
||||
{
|
||||
if ( 404 == statusNum )
|
||||
{
|
||||
std::string error_string;
|
||||
error_string = "does not exist";
|
||||
|
||||
floaterp->showSessionStartError(
|
||||
error_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
LLUUID mSessionID;
|
||||
LLIMMgr::EInvitationType mInvitiationType;
|
||||
};
|
||||
|
||||
|
||||
// the other_participant_id is either an agent_id, a group_id, or an inventory
|
||||
// folder item_id (collection of calling cards)
|
||||
|
|
@ -256,38 +346,104 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class LLIMMgr::LLIMSessionInvite
|
||||
bool inviteUserResponse(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
public:
|
||||
LLIMSessionInvite(
|
||||
const LLUUID& session_id,
|
||||
const std::string& session_name,
|
||||
const LLUUID& caller_id,
|
||||
const std::string& caller_name,
|
||||
EInstantMessage type,
|
||||
EInvitationType inv_type,
|
||||
const std::string& session_handle,
|
||||
const std::string& notify_box) :
|
||||
mSessionID(session_id),
|
||||
mSessionName(session_name),
|
||||
mCallerID(caller_id),
|
||||
mCallerName(caller_name),
|
||||
mType(type),
|
||||
mInvType(inv_type),
|
||||
mSessionHandle(session_handle),
|
||||
mNotifyBox(notify_box)
|
||||
{};
|
||||
const LLSD& payload = notification["payload"];
|
||||
LLUUID session_id = payload["session_id"].asUUID();
|
||||
EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
|
||||
LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
switch(option)
|
||||
{
|
||||
case 0: // accept
|
||||
{
|
||||
if (type == IM_SESSION_P2P_INVITE)
|
||||
{
|
||||
// create a normal IM session
|
||||
session_id = gIMMgr->addP2PSession(
|
||||
payload["session_name"].asString(),
|
||||
payload["caller_id"].asUUID(),
|
||||
payload["session_handle"].asString());
|
||||
|
||||
LLUUID mSessionID;
|
||||
std::string mSessionName;
|
||||
LLUUID mCallerID;
|
||||
std::string mCallerName;
|
||||
EInstantMessage mType;
|
||||
EInvitationType mInvType;
|
||||
std::string mSessionHandle;
|
||||
std::string mNotifyBox;
|
||||
};
|
||||
LLFloaterIMPanel* im_floater =
|
||||
gIMMgr->findFloaterBySession(
|
||||
session_id);
|
||||
if (im_floater)
|
||||
{
|
||||
im_floater->requestAutoConnect();
|
||||
LLFloaterIMPanel::onClickStartCall(im_floater);
|
||||
// always open IM window when connecting to voice
|
||||
LLFloaterChatterBox::showInstance(session_id);
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(session_id);
|
||||
gIMMgr->clearPendingInvitation(session_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
gIMMgr->addSession(
|
||||
payload["session_name"].asString(),
|
||||
type,
|
||||
session_id);
|
||||
|
||||
std::string url = gAgent.getRegion()->getCapability(
|
||||
"ChatSessionRequest");
|
||||
|
||||
LLSD data;
|
||||
data["method"] = "accept invitation";
|
||||
data["session-id"] = session_id;
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
data,
|
||||
new LLViewerChatterBoxInvitationAcceptResponder(
|
||||
session_id,
|
||||
inv_type));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
|
||||
{
|
||||
// mute the sender of this invite
|
||||
if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID()))
|
||||
{
|
||||
LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT);
|
||||
LLMuteList::getInstance()->add(mute);
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 1: // decline
|
||||
{
|
||||
if (type == IM_SESSION_P2P_INVITE)
|
||||
{
|
||||
if(gVoiceClient)
|
||||
{
|
||||
std::string s = payload["session_handle"].asString();
|
||||
gVoiceClient->declineInvite(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string url = gAgent.getRegion()->getCapability(
|
||||
"ChatSessionRequest");
|
||||
|
||||
LLSD data;
|
||||
data["method"] = "decline invitation";
|
||||
data["session-id"] = session_id;
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
data,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(session_id);
|
||||
gIMMgr->clearPendingInvitation(session_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Public Static Member Functions
|
||||
|
|
@ -510,7 +666,7 @@ void LLIMMgr::addMessage(
|
|||
}
|
||||
}
|
||||
|
||||
void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLStringUtil::format_map_t& args)
|
||||
void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
|
||||
{
|
||||
LLUIString message;
|
||||
|
||||
|
|
@ -520,7 +676,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
|
|||
LLFloaterChat* floaterp = LLFloaterChat::getInstance();
|
||||
|
||||
message = floaterp->getString(message_name);
|
||||
message.setArgList(args);
|
||||
message.setArgs(args);
|
||||
|
||||
LLChat chat(message);
|
||||
chat.mSourceType = CHAT_SOURCE_SYSTEM;
|
||||
|
|
@ -532,7 +688,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
|
|||
if (floaterp)
|
||||
{
|
||||
message = floaterp->getString(message_name);
|
||||
message.setArgList(args);
|
||||
message.setArgs(args);
|
||||
|
||||
gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
|
||||
}
|
||||
|
|
@ -687,7 +843,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
|
|||
LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
|
||||
//mTabContainer->removeTabPanel(floater);
|
||||
|
||||
clearPendingInviation(session_id);
|
||||
clearPendingInvitation(session_id);
|
||||
clearPendingAgentListUpdates(session_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -733,21 +889,21 @@ void LLIMMgr::inviteToSession(
|
|||
ad_hoc_invite = TRUE;
|
||||
}
|
||||
|
||||
LLIMSessionInvite* invite = new LLIMSessionInvite(
|
||||
session_id,
|
||||
session_name,
|
||||
caller_id,
|
||||
caller_name,
|
||||
type,
|
||||
inv_type,
|
||||
session_handle,
|
||||
notify_box_type);
|
||||
LLSD payload;
|
||||
payload["session_id"] = session_id;
|
||||
payload["session_name"] = session_name;
|
||||
payload["caller_id"] = caller_id;
|
||||
payload["caller_name"] = caller_name;
|
||||
payload["type"] = type;
|
||||
payload["inv_type"] = inv_type;
|
||||
payload["session_handle"] = session_handle;
|
||||
payload["notify_box_type"] = notify_box_type;
|
||||
|
||||
LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
|
||||
if (channelp && channelp->callStarted())
|
||||
{
|
||||
// you have already started a call to the other user, so just accept the invite
|
||||
inviteUserResponse(0, invite); // inviteUserResponse deletes
|
||||
LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -761,7 +917,7 @@ void LLIMMgr::inviteToSession(
|
|||
if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
|
||||
{
|
||||
// invite not from a friend, so decline
|
||||
inviteUserResponse(1, invite); // inviteUserResponse deletes
|
||||
LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -771,230 +927,41 @@ void LLIMMgr::inviteToSession(
|
|||
{
|
||||
if (caller_name.empty())
|
||||
{
|
||||
gCacheName->get(caller_id, FALSE, onInviteNameLookup, invite);
|
||||
gCacheName->getName(caller_id, onInviteNameLookup, new LLSD(payload));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = caller_name;
|
||||
args["[GROUP]"] = session_name;
|
||||
LLSD args;
|
||||
args["NAME"] = caller_name;
|
||||
args["GROUP"] = session_name;
|
||||
|
||||
LLNotifyBox::showXml(notify_box_type,
|
||||
LLNotifications::instance().add(notify_box_type,
|
||||
args,
|
||||
inviteUserResponse,
|
||||
(void*)invite); // inviteUserResponse deletes
|
||||
payload,
|
||||
&inviteUserResponse);
|
||||
|
||||
}
|
||||
mPendingInvitations[session_id.asString()] = LLSD();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete invite;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata)
|
||||
{
|
||||
LLIMSessionInvite* invite = (LLIMSessionInvite*)userdata;
|
||||
LLSD payload = *(LLSD*)userdata;
|
||||
delete (LLSD*)userdata;
|
||||
|
||||
invite->mCallerName = first + " " + last;
|
||||
invite->mSessionName = invite->mCallerName;
|
||||
payload["caller_name"] = first + " " + last;
|
||||
payload["session_name"] = payload["caller_name"].asString();
|
||||
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = invite->mCallerName;
|
||||
LLSD args;
|
||||
args["NAME"] = payload["caller_name"].asString();
|
||||
|
||||
LLNotifyBox::showXml(
|
||||
invite->mNotifyBox,
|
||||
LLNotifications::instance().add(
|
||||
payload["notify_box_type"].asString(),
|
||||
args,
|
||||
inviteUserResponse,
|
||||
(void*)invite);
|
||||
}
|
||||
|
||||
class LLViewerChatterBoxInvitationAcceptResponder :
|
||||
public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
LLViewerChatterBoxInvitationAcceptResponder(
|
||||
const LLUUID& session_id,
|
||||
LLIMMgr::EInvitationType invitation_type)
|
||||
{
|
||||
mSessionID = session_id;
|
||||
mInvitiationType = invitation_type;
|
||||
}
|
||||
|
||||
void result(const LLSD& content)
|
||||
{
|
||||
if ( gIMMgr)
|
||||
{
|
||||
LLFloaterIMPanel* floaterp =
|
||||
gIMMgr->findFloaterBySession(mSessionID);
|
||||
|
||||
if (floaterp)
|
||||
{
|
||||
//we've accepted our invitation
|
||||
//and received a list of agents that were
|
||||
//currently in the session when the reply was sent
|
||||
//to us. Now, it is possible that there were some agents
|
||||
//to slip in/out between when that message was sent to us
|
||||
//and now.
|
||||
|
||||
//the agent list updates we've received have been
|
||||
//accurate from the time we were added to the session
|
||||
//but unfortunately, our base that we are receiving here
|
||||
//may not be the most up to date. It was accurate at
|
||||
//some point in time though.
|
||||
floaterp->setSpeakers(content);
|
||||
|
||||
//we now have our base of users in the session
|
||||
//that was accurate at some point, but maybe not now
|
||||
//so now we apply all of the udpates we've received
|
||||
//in case of race conditions
|
||||
floaterp->updateSpeakersList(
|
||||
gIMMgr->getPendingAgentListUpdates(mSessionID));
|
||||
|
||||
if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
|
||||
{
|
||||
floaterp->requestAutoConnect();
|
||||
LLFloaterIMPanel::onClickStartCall(floaterp);
|
||||
// always open IM window when connecting to voice
|
||||
LLFloaterChatterBox::showInstance(TRUE);
|
||||
}
|
||||
else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
|
||||
{
|
||||
LLFloaterChatterBox::showInstance(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(mSessionID);
|
||||
gIMMgr->clearPendingInviation(mSessionID);
|
||||
}
|
||||
}
|
||||
|
||||
void error(U32 statusNum, const std::string& reason)
|
||||
{
|
||||
//throw something back to the viewer here?
|
||||
if ( gIMMgr )
|
||||
{
|
||||
gIMMgr->clearPendingAgentListUpdates(mSessionID);
|
||||
gIMMgr->clearPendingInviation(mSessionID);
|
||||
|
||||
LLFloaterIMPanel* floaterp =
|
||||
gIMMgr->findFloaterBySession(mSessionID);
|
||||
|
||||
if ( floaterp )
|
||||
{
|
||||
if ( 404 == statusNum )
|
||||
{
|
||||
std::string error_string;
|
||||
error_string = "does not exist";
|
||||
|
||||
floaterp->showSessionStartError(
|
||||
error_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
LLUUID mSessionID;
|
||||
LLIMMgr::EInvitationType mInvitiationType;
|
||||
};
|
||||
|
||||
//static
|
||||
void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
|
||||
{
|
||||
LLIMSessionInvite* invitep = (LLIMSessionInvite*)user_data;
|
||||
|
||||
switch(option)
|
||||
{
|
||||
case 0: // accept
|
||||
{
|
||||
if (invitep->mType == IM_SESSION_P2P_INVITE)
|
||||
{
|
||||
// create a normal IM session
|
||||
invitep->mSessionID = gIMMgr->addP2PSession(
|
||||
invitep->mSessionName,
|
||||
invitep->mCallerID,
|
||||
invitep->mSessionHandle);
|
||||
|
||||
LLFloaterIMPanel* im_floater =
|
||||
gIMMgr->findFloaterBySession(
|
||||
invitep->mSessionID);
|
||||
if (im_floater)
|
||||
{
|
||||
im_floater->requestAutoConnect();
|
||||
LLFloaterIMPanel::onClickStartCall(im_floater);
|
||||
// always open IM window when connecting to voice
|
||||
LLFloaterChatterBox::showInstance(invitep->mSessionID);
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
|
||||
gIMMgr->clearPendingInviation(invitep->mSessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
gIMMgr->addSession(
|
||||
invitep->mSessionName,
|
||||
invitep->mType,
|
||||
invitep->mSessionID);
|
||||
|
||||
std::string url = gAgent.getRegion()->getCapability(
|
||||
"ChatSessionRequest");
|
||||
|
||||
LLSD data;
|
||||
data["method"] = "accept invitation";
|
||||
data["session-id"] = invitep->mSessionID;
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
data,
|
||||
new LLViewerChatterBoxInvitationAcceptResponder(
|
||||
invitep->mSessionID,
|
||||
invitep->mInvType));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
|
||||
{
|
||||
// mute the sender of this invite
|
||||
if (!LLMuteList::getInstance()->isMuted(invitep->mCallerID))
|
||||
{
|
||||
LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
|
||||
LLMuteList::getInstance()->add(mute);
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 1: // decline
|
||||
{
|
||||
if (invitep->mType == IM_SESSION_P2P_INVITE)
|
||||
{
|
||||
if(gVoiceClient)
|
||||
{
|
||||
gVoiceClient->declineInvite(invitep->mSessionHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string url = gAgent.getRegion()->getCapability(
|
||||
"ChatSessionRequest");
|
||||
|
||||
LLSD data;
|
||||
data["method"] = "decline invitation";
|
||||
data["session-id"] = invitep->mSessionID;
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
data,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
|
||||
gIMMgr->clearPendingInviation(invitep->mSessionID);
|
||||
break;
|
||||
}
|
||||
|
||||
delete invitep;
|
||||
payload,
|
||||
&inviteUserResponse);
|
||||
}
|
||||
|
||||
void LLIMMgr::refresh()
|
||||
|
|
@ -1068,7 +1035,7 @@ BOOL LLIMMgr::hasSession(const LLUUID& session_id)
|
|||
return (findFloaterBySession(session_id) != NULL);
|
||||
}
|
||||
|
||||
void LLIMMgr::clearPendingInviation(const LLUUID& session_id)
|
||||
void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
|
||||
{
|
||||
if ( mPendingInvitations.has(session_id.asString()) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
const LLVector3& position = LLVector3::zero,
|
||||
bool link_name = false);
|
||||
|
||||
void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLStringUtil::format_map_t& args);
|
||||
void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);
|
||||
|
||||
// This method returns TRUE if the local viewer has a session
|
||||
// currently open keyed to the uuid. The uuid can be keyed by
|
||||
|
|
@ -157,7 +157,7 @@ public:
|
|||
|
||||
static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id);
|
||||
|
||||
void clearPendingInviation(const LLUUID& session_id);
|
||||
void clearPendingInvitation(const LLUUID& session_id);
|
||||
|
||||
LLSD getPendingAgentListUpdates(const LLUUID& session_id);
|
||||
void addPendingAgentListUpdates(
|
||||
|
|
@ -169,8 +169,6 @@ public:
|
|||
const std::set<LLHandle<LLFloater> >& getIMFloaterHandles() { return mFloaters; }
|
||||
|
||||
private:
|
||||
class LLIMSessionInvite;
|
||||
|
||||
// create a panel and update internal representation for
|
||||
// consistency. Returns the pointer, caller (the class instance
|
||||
// since it is a private method) is not responsible for deleting
|
||||
|
|
@ -197,7 +195,6 @@ private:
|
|||
|
||||
void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
|
||||
|
||||
static void inviteUserResponse(S32 option, void* user_data);
|
||||
static void onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
|
|||
void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append);
|
||||
void remove_inventory_category_from_avatar(LLInventoryCategory* category);
|
||||
void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata);
|
||||
void move_task_inventory_callback(S32 option, void* user_data);
|
||||
void confirm_replace_attachment_rez(S32 option, void* user_data);
|
||||
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
|
||||
bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response);
|
||||
|
||||
std::string ICON_NAME[ICON_NAME_COUNT] =
|
||||
{
|
||||
|
|
@ -1288,7 +1288,7 @@ void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
|
|||
{
|
||||
dialog = "MoveInventoryFromObject";
|
||||
}
|
||||
gViewerWindow->alertXml(dialog, move_task_inventory_callback, move_inv);
|
||||
LLNotifications::instance().add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
|
||||
}
|
||||
|
||||
// Move/copy all inventory items from the Contents folder of an in-world
|
||||
|
|
@ -1377,7 +1377,9 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
|
|||
}
|
||||
else
|
||||
{
|
||||
move_task_inventory_callback(0, (void*)(move_inv));
|
||||
LLNotification::Params params("MoveInventoryFromObject");
|
||||
params.functor(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
}
|
||||
return accept;
|
||||
|
|
@ -2187,12 +2189,12 @@ void LLFolderBridge::modifyOutfit(BOOL append)
|
|||
}
|
||||
|
||||
// helper stuff
|
||||
void move_task_inventory_callback(S32 option, void* user_data)
|
||||
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv* move_inv)
|
||||
{
|
||||
LLMoveInv* move_inv = (LLMoveInv*)user_data;
|
||||
LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData;
|
||||
LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID);
|
||||
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
if(option == 0 && object)
|
||||
{
|
||||
if (cat_and_wear && cat_and_wear->mWear)
|
||||
|
|
@ -2223,6 +2225,7 @@ void move_task_inventory_callback(S32 option, void* user_data)
|
|||
}
|
||||
|
||||
delete move_inv;
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
|
||||
|
|
@ -2353,7 +2356,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
|
|||
}
|
||||
else
|
||||
{
|
||||
move_task_inventory_callback(0, (void*)(move_inv));
|
||||
LLNotification::Params params("MoveInventoryFromObject");
|
||||
params.functor(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
|
||||
LLNotifications::instance().forceResponse(params, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2648,23 +2653,28 @@ void open_landmark(LLViewerInventoryItem* inv_item,
|
|||
}
|
||||
}
|
||||
|
||||
static void open_landmark_callback(S32 option, void* data)
|
||||
static bool open_landmark_callback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLUUID* asset_idp = (LLUUID*)data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
LLUUID asset_id = notification["payload"]["asset_id"].asUUID();
|
||||
if (option == 0)
|
||||
{
|
||||
// HACK: This is to demonstrate teleport on double click for landmarks
|
||||
gAgent.teleportViaLandmark( *asset_idp );
|
||||
gAgent.teleportViaLandmark( asset_id );
|
||||
|
||||
// we now automatically track the landmark you're teleporting to
|
||||
// because you'll probably arrive at a telehub instead
|
||||
if( gFloaterWorldMap )
|
||||
{
|
||||
gFloaterWorldMap->trackLandmark( *asset_idp );
|
||||
gFloaterWorldMap->trackLandmark( asset_id );
|
||||
}
|
||||
}
|
||||
delete asset_idp;
|
||||
|
||||
return false;
|
||||
}
|
||||
static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportFromLandmark", open_landmark_callback);
|
||||
|
||||
|
||||
void LLLandmarkBridge::openItem()
|
||||
{
|
||||
|
|
@ -2674,9 +2684,9 @@ void LLLandmarkBridge::openItem()
|
|||
// Opening (double-clicking) a landmark immediately teleports,
|
||||
// but warns you the first time.
|
||||
// open_landmark(item, std::string(" ") + getPrefix() + item->getName(), FALSE);
|
||||
LLUUID* asset_idp = new LLUUID(item->getAssetUUID());
|
||||
LLAlertDialog::showXml("TeleportFromLandmark",
|
||||
open_landmark_callback, (void*)asset_idp);
|
||||
LLSD payload;
|
||||
payload["asset_id"] = item->getAssetUUID();
|
||||
LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3321,8 +3331,9 @@ std::string LLObjectBridge::getLabelSuffix() const
|
|||
|
||||
void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment)
|
||||
{
|
||||
LLAttachmentRezAction* rez_action = new LLAttachmentRezAction;
|
||||
rez_action->mItemID = item->getUUID();
|
||||
LLSD payload;
|
||||
payload["item_id"] = item->getUUID();
|
||||
|
||||
S32 attach_pt = 0;
|
||||
if (gAgent.getAvatarObject() && attachment)
|
||||
{
|
||||
|
|
@ -3336,46 +3347,46 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
|
|||
}
|
||||
}
|
||||
}
|
||||
rez_action->mAttachPt = attach_pt;
|
||||
|
||||
payload["attachment_point"] = attach_pt;
|
||||
|
||||
if (attachment && attachment->getObject())
|
||||
{
|
||||
gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action);
|
||||
LLNotifications::instance().add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action);
|
||||
LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
|
||||
}
|
||||
}
|
||||
|
||||
void confirm_replace_attachment_rez(S32 option, void* user_data)
|
||||
bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLAttachmentRezAction* rez_action = (LLAttachmentRezAction*)user_data;
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
if (option == 0/*YES*/)
|
||||
{
|
||||
if (rez_action)
|
||||
LLViewerInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID());
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
LLViewerInventoryItem* itemp = gInventory.getItem(rez_action->mItemID);
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_ObjectData);
|
||||
msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
|
||||
msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
|
||||
msg->addU8Fast(_PREHASH_AttachmentPt, rez_action->mAttachPt);
|
||||
pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
|
||||
msg->addStringFast(_PREHASH_Name, itemp->getName());
|
||||
msg->addStringFast(_PREHASH_Description, itemp->getDescription());
|
||||
msg->sendReliable(gAgent.getRegion()->getHost());
|
||||
}
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_ObjectData);
|
||||
msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
|
||||
msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
|
||||
msg->addU8Fast(_PREHASH_AttachmentPt, notification["payload"]["attachment_point"].asInteger());
|
||||
pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
|
||||
msg->addStringFast(_PREHASH_Name, itemp->getName());
|
||||
msg->addStringFast(_PREHASH_Description, itemp->getDescription());
|
||||
msg->sendReliable(gAgent.getRegion()->getHost());
|
||||
}
|
||||
}
|
||||
delete rez_action;
|
||||
return false;
|
||||
}
|
||||
static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_replace_attachment_rez);
|
||||
|
||||
void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
{
|
||||
|
|
@ -3927,7 +3938,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
|
|||
|
||||
if( !wearable_count && !obj_count && !gest_count)
|
||||
{
|
||||
gViewerWindow->alertXml("CouldNotPutOnOutfit");
|
||||
LLNotifications::instance().add("CouldNotPutOnOutfit");
|
||||
delete wear_info;
|
||||
return;
|
||||
}
|
||||
|
|
@ -4334,7 +4345,7 @@ void LLWearableBridge::openItem()
|
|||
{
|
||||
if( isInTrash() )
|
||||
{
|
||||
gViewerWindow->alertXml("CannotWearTrash");
|
||||
LLNotifications::instance().add("CannotWearTrash");
|
||||
}
|
||||
else if(isAgentInventory())
|
||||
{
|
||||
|
|
@ -4363,7 +4374,7 @@ void LLWearableBridge::openItem()
|
|||
{
|
||||
// *TODO: We should fetch the item details, and then do
|
||||
// the operation above.
|
||||
gViewerWindow->alertXml("CannotWearInfoNotComplete");
|
||||
LLNotifications::instance().add("CannotWearInfoNotComplete");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4464,7 +4475,7 @@ void LLWearableBridge::wearOnAvatar()
|
|||
// destroy clothing items.
|
||||
if (!gAgent.areWearablesLoaded())
|
||||
{
|
||||
gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
|
||||
LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue