svn merge -r106715:HEAD svn+ssh://svn.lindenlab.com/svn/linden/branches/q/notifications-merge-r106715 . QAR-1149 -- Final merge of notifications to trunk.

master
Kent Quirk 2009-01-05 18:59:12 +00:00
parent 95f365789f
commit 667ca55bad
159 changed files with 6819 additions and 3260 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -223,6 +223,11 @@ public:
return *this;
}
bool isValid() const
{
return mLeft <= mRight && mBottom <= mTop;
}
bool isNull() const
{
return mLeft == mRight || mBottom == mTop;

View File

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

View File

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

View File

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

View File

@ -188,6 +188,7 @@ protected:
LLScrollListCtrl* mList;
EPreferredPosition mListPosition;
LLPointer<LLUIImage> mArrowImage;
std::string mLabel;
private:
S32 mButtonPadding;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1001,7 +1001,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
else
{
llwarns << "Failure writing animation data." << llendl;
gViewerWindow->alertXml("WriteAnimationFail");
LLNotifications::instance().add("WriteAnimationFail");
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -153,5 +153,5 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
//static
void LLFloaterPerms::onClickHelp(void* data)
{
gViewerWindow->alertXml("ClickUploadHelpPermissions");
LLNotifications::instance().add("ClickUploadHelpPermissions");
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -966,7 +966,7 @@ void LLSnapshotLivePreview::saveTexture()
}
else
{
gViewerWindow->alertXml("ErrorEncodingSnapshot");
LLNotifications::instance().add("ErrorEncodingSnapshot");
llwarns << "Error encoding snapshot" << llendl;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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