pull from gate

master
Glenn Glazer 2017-05-23 07:59:15 -07:00
commit 3fda9bea31
299 changed files with 4339 additions and 1009 deletions

View File

@ -526,3 +526,4 @@ c9ce2295012995e3cf5c57bcffcb4870b94c649f 5.0.1-release
cea1632c002c065985ebea15eeeb4aac90f50545 5.0.2-release
02c24e9f4f7d8aa0de75f27817dda098582f4936 5.0.3-release
022709ef76a331cac1ba6ef1a6da8a5e9ef63f5a 5.0.4-release
b4d76b5590fdf8bab72c64442353753a527cbc44 5.0.5-release

View File

@ -214,6 +214,7 @@ Ansariel Hiller
MAINT-6953
MAINT-7028
MAINT-7059
MAINT-6519
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@ -770,6 +771,8 @@ Kadah Coba
STORM-1060
STORM-1843
Jondan Lundquist
Joosten Briebers
MAINT-7074
Josef Munster
Josette Windlow
Juilan Tripsa

View File

@ -323,26 +323,27 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(lldeadmantimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventfilter "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocinfo "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltrace "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}")
## llexception_test.cpp isn't a regression test, and doesn't need to be run
## every build. It's to help a developer make implementation choices about

View File

@ -38,12 +38,18 @@
#include "llerror.h" // LL_ERRS
#include "llsdutil.h" // llsd_matches()
/*****************************************************************************
* LLEventFilter
*****************************************************************************/
LLEventFilter::LLEventFilter(LLEventPump& source, const std::string& name, bool tweak):
LLEventStream(name, tweak),
mSource(source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1)))
{
}
/*****************************************************************************
* LLEventMatching
*****************************************************************************/
LLEventMatching::LLEventMatching(const LLSD& pattern):
LLEventFilter("matching"),
mPattern(pattern)
@ -64,6 +70,9 @@ bool LLEventMatching::post(const LLSD& event)
return LLEventStream::post(event);
}
/*****************************************************************************
* LLEventTimeoutBase
*****************************************************************************/
LLEventTimeoutBase::LLEventTimeoutBase():
LLEventFilter("timeout")
{
@ -148,6 +157,14 @@ bool LLEventTimeoutBase::tick(const LLSD&)
return false; // show event to other listeners
}
bool LLEventTimeoutBase::running() const
{
return mMainloop.connected();
}
/*****************************************************************************
* LLEventTimeout
*****************************************************************************/
LLEventTimeout::LLEventTimeout() {}
LLEventTimeout::LLEventTimeout(LLEventPump& source):
@ -164,3 +181,231 @@ bool LLEventTimeout::countdownElapsed() const
{
return mTimer.hasExpired();
}
/*****************************************************************************
* LLEventBatch
*****************************************************************************/
LLEventBatch::LLEventBatch(std::size_t size):
LLEventFilter("batch"),
mBatchSize(size)
{}
LLEventBatch::LLEventBatch(LLEventPump& source, std::size_t size):
LLEventFilter(source, "batch"),
mBatchSize(size)
{}
void LLEventBatch::flush()
{
// copy and clear mBatch BEFORE posting to avoid weird circularity effects
LLSD batch(mBatch);
mBatch.clear();
LLEventStream::post(batch);
}
bool LLEventBatch::post(const LLSD& event)
{
mBatch.append(event);
// calling setSize(same) performs the very check we want
setSize(mBatchSize);
return false;
}
void LLEventBatch::setSize(std::size_t size)
{
mBatchSize = size;
// changing the size might mean that we have to flush NOW
if (mBatch.size() >= mBatchSize)
{
flush();
}
}
/*****************************************************************************
* LLEventThrottleBase
*****************************************************************************/
LLEventThrottleBase::LLEventThrottleBase(F32 interval):
LLEventFilter("throttle"),
mInterval(interval),
mPosts(0)
{}
LLEventThrottleBase::LLEventThrottleBase(LLEventPump& source, F32 interval):
LLEventFilter(source, "throttle"),
mInterval(interval),
mPosts(0)
{}
void LLEventThrottleBase::flush()
{
// flush() is a no-op unless there's something pending.
// Don't test mPending because there's no requirement that the consumer
// post() anything but an isUndefined(). This is what mPosts is for.
if (mPosts)
{
mPosts = 0;
alarmCancel();
// This is not to set our alarm; we are not yet requesting
// any notification. This is just to track whether subsequent post()
// calls fall within this mInterval or not.
timerSet(mInterval);
// copy and clear mPending BEFORE posting to avoid weird circularity
// effects
LLSD pending = mPending;
mPending.clear();
LLEventStream::post(pending);
}
}
LLSD LLEventThrottleBase::pending() const
{
return mPending;
}
bool LLEventThrottleBase::post(const LLSD& event)
{
// Always capture most recent post() event data. If caller wants to
// aggregate multiple events, let them retrieve pending() and modify
// before calling post().
mPending = event;
// Always increment mPosts. Unless we count this call, flush() does
// nothing.
++mPosts;
// We reset mTimer on every flush() call to let us know if we're still
// within the same mInterval. So -- are we?
F32 timeRemaining = timerGetRemaining();
if (! timeRemaining)
{
// more than enough time has elapsed, immediately flush()
flush();
}
else
{
// still within mInterval of the last flush() call: have to defer
if (! alarmRunning())
{
// timeRemaining tells us how much longer it will be until
// mInterval seconds since the last flush() call. At that time,
// flush() deferred events.
alarmActionAfter(timeRemaining, boost::bind(&LLEventThrottleBase::flush, this));
}
}
return false;
}
void LLEventThrottleBase::setInterval(F32 interval)
{
F32 oldInterval = mInterval;
mInterval = interval;
// If we are not now within oldInterval of the last flush(), we're done:
// this will only affect behavior starting with the next flush().
F32 timeRemaining = timerGetRemaining();
if (timeRemaining)
{
// We are currently within oldInterval of the last flush(). Figure out
// how much time remains until (the new) mInterval of the last
// flush(). Bt we don't actually store a timestamp for the last
// flush(); it's implicit. There are timeRemaining seconds until what
// used to be the end of the interval. Move that endpoint by the
// difference between the new interval and the old.
timeRemaining += (mInterval - oldInterval);
// If we're called with a larger interval, the difference is positive
// and timeRemaining increases.
// If we're called with a smaller interval, the difference is negative
// and timeRemaining decreases. The interesting case is when it goes
// nonpositive: when the new interval means we can flush immediately.
if (timeRemaining <= 0.0f)
{
flush();
}
else
{
// immediately reset mTimer
timerSet(timeRemaining);
// and if mAlarm is running, reset that too
if (alarmRunning())
{
alarmActionAfter(timeRemaining, boost::bind(&LLEventThrottleBase::flush, this));
}
}
}
}
F32 LLEventThrottleBase::getDelay() const
{
return timerGetRemaining();
}
/*****************************************************************************
* LLEventThrottle implementation
*****************************************************************************/
LLEventThrottle::LLEventThrottle(F32 interval):
LLEventThrottleBase(interval)
{}
LLEventThrottle::LLEventThrottle(LLEventPump& source, F32 interval):
LLEventThrottleBase(source, interval)
{}
void LLEventThrottle::alarmActionAfter(F32 interval, const LLEventTimeoutBase::Action& action)
{
mAlarm.actionAfter(interval, action);
}
bool LLEventThrottle::alarmRunning() const
{
return mAlarm.running();
}
void LLEventThrottle::alarmCancel()
{
return mAlarm.cancel();
}
void LLEventThrottle::timerSet(F32 interval)
{
mTimer.setTimerExpirySec(interval);
}
F32 LLEventThrottle::timerGetRemaining() const
{
return mTimer.getRemainingTimeF32();
}
/*****************************************************************************
* LLEventBatchThrottle
*****************************************************************************/
LLEventBatchThrottle::LLEventBatchThrottle(F32 interval, std::size_t size):
LLEventThrottle(interval),
mBatchSize(size)
{}
LLEventBatchThrottle::LLEventBatchThrottle(LLEventPump& source, F32 interval, std::size_t size):
LLEventThrottle(source, interval),
mBatchSize(size)
{}
bool LLEventBatchThrottle::post(const LLSD& event)
{
// simply retrieve pending value and append the new event to it
LLSD partial = pending();
partial.append(event);
bool ret = LLEventThrottle::post(partial);
// The post() call above MIGHT have called flush() already. If it did,
// then pending() was reset to empty. If it did not, though, but the batch
// size has grown to the limit, flush() anyway. If there's a limit at all,
// of course. Calling setSize(same) performs the very check we want.
setSize(mBatchSize);
return ret;
}
void LLEventBatchThrottle::setSize(std::size_t size)
{
mBatchSize = size;
// Changing the size might mean that we have to flush NOW. Don't forget
// that 0 means unlimited.
if (mBatchSize && pending().size() >= mBatchSize)
{
flush();
}
}

View File

@ -177,6 +177,9 @@ public:
/// Cancel timer without event
void cancel();
/// Is this timer currently running?
bool running() const;
protected:
virtual void setCountdown(F32 seconds) = 0;
virtual bool countdownElapsed() const = 0;
@ -215,4 +218,162 @@ private:
LLTimer mTimer;
};
/**
* LLEventBatch: accumulate post() events (LLSD blobs) into an LLSD Array
* until the array reaches a certain size, then call listeners with the Array
* and clear it back to empty.
*/
class LL_COMMON_API LLEventBatch: public LLEventFilter
{
public:
// pass batch size
LLEventBatch(std::size_t size);
// construct and connect
LLEventBatch(LLEventPump& source, std::size_t size);
// force out the pending batch
void flush();
// accumulate an event and flush() when big enough
virtual bool post(const LLSD& event);
// query or reset batch size
std::size_t getSize() const { return mBatchSize; }
void setSize(std::size_t size);
private:
LLSD mBatch;
std::size_t mBatchSize;
};
/**
* LLEventThrottleBase: construct with a time interval. Regardless of how
* frequently you call post(), LLEventThrottle will pass on an event to
* its listeners no more often than once per specified interval.
*
* A new event after more than the specified interval will immediately be
* passed along to listeners. But subsequent events will be delayed until at
* least one time interval since listeners were last called. Consider the
* sequence below. Suppose we have an LLEventThrottle constructed with an
* interval of 3 seconds. The numbers on the left are timestamps in seconds
* relative to an arbitrary reference point.
*
* 1: post(): event immediately passed to listeners, next no sooner than 4
* 2: post(): deferred: waiting for 3 seconds to elapse
* 3: post(): deferred
* 4: no post() call, but event delivered to listeners; next no sooner than 7
* 6: post(): deferred
* 7: no post() call, but event delivered; next no sooner than 10
* 12: post(): immediately passed to listeners, next no sooner than 15
* 17: post(): immediately passed to listeners, next no sooner than 20
*
* For a deferred event, the LLSD blob delivered to listeners is from the most
* recent deferred post() call. However, a sender may obtain the previous
* event blob by calling pending(), modifying it as desired and post()ing the
* new value. (See LLEventBatchThrottle.) Each time an event is delivered to
* listeners, the pending() value is reset to isUndefined().
*
* You may also call flush() to immediately pass along any deferred events to
* all listeners.
*
* @NOTE This is an abstract base class so that, for testing, we can use an
* alternate "timer" that doesn't actually consume real time. See
* LLEventThrottle.
*/
class LL_COMMON_API LLEventThrottleBase: public LLEventFilter
{
public:
// pass time interval
LLEventThrottleBase(F32 interval);
// construct and connect
LLEventThrottleBase(LLEventPump& source, F32 interval);
// force out any deferred events
void flush();
// retrieve (aggregate) deferred event since last event sent to listeners
LLSD pending() const;
// register an event, may be either passed through or deferred
virtual bool post(const LLSD& event);
// query or reset interval
F32 getInterval() const { return mInterval; }
void setInterval(F32 interval);
// deferred posts
std::size_t getPostCount() const { return mPosts; }
// time until next event would be passed through, 0.0 if now
F32 getDelay() const;
protected:
// Implement these time-related methods for a valid LLEventThrottleBase
// subclass (see LLEventThrottle). For testing, we use a subclass that
// doesn't involve actual elapsed time.
virtual void alarmActionAfter(F32 interval, const LLEventTimeoutBase::Action& action) = 0;
virtual bool alarmRunning() const = 0;
virtual void alarmCancel() = 0;
virtual void timerSet(F32 interval) = 0;
virtual F32 timerGetRemaining() const = 0;
private:
// remember throttle interval
F32 mInterval;
// count post() calls since last flush()
std::size_t mPosts;
// pending event data from most recent deferred event
LLSD mPending;
};
/**
* Production implementation of LLEventThrottle.
*/
class LLEventThrottle: public LLEventThrottleBase
{
public:
LLEventThrottle(F32 interval);
LLEventThrottle(LLEventPump& source, F32 interval);
private:
virtual void alarmActionAfter(F32 interval, const LLEventTimeoutBase::Action& action) /*override*/;
virtual bool alarmRunning() const /*override*/;
virtual void alarmCancel() /*override*/;
virtual void timerSet(F32 interval) /*override*/;
virtual F32 timerGetRemaining() const /*override*/;
// use this to arrange a deferred flush() call
LLEventTimeout mAlarm;
// use this to track whether we're within mInterval of last flush()
LLTimer mTimer;
};
/**
* LLEventBatchThrottle: like LLEventThrottle, it's reluctant to pass events
* to listeners more often than once per specified time interval -- but only
* reluctant, since exceeding the specified batch size limit can cause it to
* deliver accumulated events sooner. Like LLEventBatch, it accumulates
* pending events into an LLSD Array, optionally flushing when the batch grows
* to a certain size.
*/
class LLEventBatchThrottle: public LLEventThrottle
{
public:
// pass time interval and (optionally) max batch size; 0 means batch can
// grow arbitrarily large
LLEventBatchThrottle(F32 interval, std::size_t size = 0);
// construct and connect
LLEventBatchThrottle(LLEventPump& source, F32 interval, std::size_t size = 0);
// append a new event to current batch
virtual bool post(const LLSD& event);
// query or reset batch size
std::size_t getSize() const { return mBatchSize; }
void setSize(std::size_t size);
private:
std::size_t mBatchSize;
};
#endif /* ! defined(LL_LLEVENTFILTER_H) */

View File

@ -220,6 +220,9 @@ void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initSt
std::find(initializing.begin(), initializing.end(), this);
if (found != initializing.end())
{
list_t::const_iterator it_next = found;
it_next++;
// Report the circularity. Requiring the coder to dig through the
// logic to diagnose exactly how we got here is less than helpful.
std::ostringstream out;
@ -238,11 +241,30 @@ void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initSt
// otherwise we'd be returning a pointer to a partially-
// constructed object! But from initSingleton() is okay: that
// method exists specifically to support circularity.
// Decide which log helper to call based on initState. They have
// identical signatures.
((initState == CONSTRUCTING)? logerrs : logwarns)
("LLSingleton circularity: ", out.str().c_str(),
demangle(typeid(*this).name()).c_str(), "");
// Decide which log helper to call.
if (initState == CONSTRUCTING)
{
logerrs("LLSingleton circularity in Constructor: ", out.str().c_str(),
demangle(typeid(*this).name()).c_str(), "");
}
else if (it_next == initializing.end())
{
// Points to self after construction, but during initialization.
// Singletons can initialize other classes that depend onto them,
// so this is expected.
//
// Example: LLNotifications singleton initializes default channels.
// Channels register themselves with singleton once done.
logdebugs("LLSingleton circularity: ", out.str().c_str(),
demangle(typeid(*this).name()).c_str(), "");
}
else
{
// Actual circularity with other singleton (or single singleton is used extensively).
// Dependency can be unclear.
logwarns("LLSingleton circularity: ", out.str().c_str(),
demangle(typeid(*this).name()).c_str(), "");
}
}
else
{

View File

@ -336,6 +336,7 @@ public:
static void addCRLF(string_type& string);
static void removeCRLF(string_type& string);
static void removeWindowsCR(string_type& string);
static void replaceTabsWithSpaces( string_type& string, size_type spaces_per_tab );
static void replaceNonstandardASCII( string_type& string, T replacement );
@ -1322,6 +1323,28 @@ void LLStringUtilBase<T>::removeCRLF(string_type& string)
//static
template<class T>
void LLStringUtilBase<T>::removeWindowsCR(string_type& string)
{
const T LF = 10;
const T CR = 13;
size_type cr_count = 0;
size_type len = string.size();
size_type i;
for( i = 0; i < len - cr_count - 1; i++ )
{
if( string[i+cr_count] == CR && string[i+cr_count+1] == LF)
{
cr_count++;
}
string[i] = string[i+cr_count];
}
string.erase(i, cr_count);
}
//static
template<class T>
void LLStringUtilBase<T>::replaceChar( string_type& string, T target, T replacement )
{
size_type found_pos = 0;

View File

@ -40,7 +40,8 @@
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/algorithm/string/finder.hpp>
void encode_character(std::ostream& ostr, std::string::value_type val)
// static
void LLURI::encodeCharacter(std::ostream& ostr, std::string::value_type val)
{
ostr << "%"
@ -95,7 +96,7 @@ std::string LLURI::escape(
}
else
{
encode_character(ostr, c);
encodeCharacter(ostr, c);
}
}
}
@ -106,7 +107,7 @@ std::string LLURI::escape(
c = *it;
if(allowed.find(c) == std::string::npos)
{
encode_character(ostr, c);
encodeCharacter(ostr, c);
}
else
{

View File

@ -120,6 +120,14 @@ public:
/** @name Escaping Utilities */
//@{
/**
* @brief 'Escape' symbol into stream
*
* @param ostr Output stream.
* @param val Symbol to encode.
*/
static void encodeCharacter(std::ostream& ostr, std::string::value_type val);
/**
* @brief Escape the string passed except for unreserved
*

View File

@ -138,4 +138,15 @@ struct Collect
StringVec result;
};
struct Concat
{
bool operator()(const LLSD& event)
{
result += event.asString();
return false;
}
void clear() { result.clear(); }
std::string result;
};
#endif /* ! defined(LL_LISTENER_H) */

View File

@ -70,6 +70,85 @@ private:
bool mElapsed;
};
// Similar remarks about LLEventThrottle: we're actually testing the logic in
// LLEventThrottleBase, dummying out the LLTimer and LLEventTimeout used by
// the production LLEventThrottle class.
class TestEventThrottle: public LLEventThrottleBase
{
public:
TestEventThrottle(F32 interval):
LLEventThrottleBase(interval),
mAlarmRemaining(-1),
mTimerRemaining(-1)
{}
TestEventThrottle(LLEventPump& source, F32 interval):
LLEventThrottleBase(source, interval),
mAlarmRemaining(-1),
mTimerRemaining(-1)
{}
/*----- implementation of LLEventThrottleBase timing functionality -----*/
virtual void alarmActionAfter(F32 interval, const LLEventTimeoutBase::Action& action) /*override*/
{
mAlarmRemaining = interval;
mAlarmAction = action;
}
virtual bool alarmRunning() const /*override*/
{
// decrementing to exactly 0 should mean the alarm fires
return mAlarmRemaining > 0;
}
virtual void alarmCancel() /*override*/
{
mAlarmRemaining = -1;
}
virtual void timerSet(F32 interval) /*override*/
{
mTimerRemaining = interval;
}
virtual F32 timerGetRemaining() const /*override*/
{
// LLTimer.getRemainingTimeF32() never returns negative; 0.0 means expired
return (mTimerRemaining > 0.0)? mTimerRemaining : 0.0;
}
/*------------------- methods for manipulating time --------------------*/
void alarmAdvance(F32 delta)
{
bool wasRunning = alarmRunning();
mAlarmRemaining -= delta;
if (wasRunning && ! alarmRunning())
{
mAlarmAction();
}
}
void timerAdvance(F32 delta)
{
// This simple implementation, like alarmAdvance(), completely ignores
// HOW negative mTimerRemaining might go. All that matters is whether
// it's negative. We trust that no test method in this source will
// drive it beyond the capacity of an F32. Seems like a safe assumption.
mTimerRemaining -= delta;
}
void advance(F32 delta)
{
// Advance the timer first because it has no side effects.
// alarmAdvance() might call flush(), which will need to see the
// change in the timer.
timerAdvance(delta);
alarmAdvance(delta);
}
F32 mAlarmRemaining, mTimerRemaining;
LLEventTimeoutBase::Action mAlarmAction;
};
/*****************************************************************************
* TUT
*****************************************************************************/
@ -116,7 +195,9 @@ namespace tut
listener0.listenTo(driver));
// Construct a pattern LLSD: desired Event must have a key "foo"
// containing string "bar"
LLEventMatching filter(driver, LLSD().insert("foo", "bar"));
LLSD pattern;
pattern.insert("foo", "bar");
LLEventMatching filter(driver, pattern);
listener1.reset(0);
LLTempBoundListener temp2(
listener1.listenTo(filter));
@ -285,6 +366,47 @@ namespace tut
mainloop.post(17);
check_listener("no timeout 3", listener0, LLSD(0));
}
template<> template<>
void filter_object::test<5>()
{
set_test_name("LLEventThrottle");
TestEventThrottle throttle(3);
Concat cat;
throttle.listen("concat", boost::ref(cat));
// (sequence taken from LLEventThrottleBase Doxygen comments)
// 1: post(): event immediately passed to listeners, next no sooner than 4
throttle.advance(1);
throttle.post("1");
ensure_equals("1", cat.result, "1"); // delivered immediately
// 2: post(): deferred: waiting for 3 seconds to elapse
throttle.advance(1);
throttle.post("2");
ensure_equals("2", cat.result, "1"); // "2" not yet delivered
// 3: post(): deferred
throttle.advance(1);
throttle.post("3");
ensure_equals("3", cat.result, "1"); // "3" not yet delivered
// 4: no post() call, but event delivered to listeners; next no sooner than 7
throttle.advance(1);
ensure_equals("4", cat.result, "13"); // "3" delivered
// 6: post(): deferred
throttle.advance(2);
throttle.post("6");
ensure_equals("6", cat.result, "13"); // "6" not yet delivered
// 7: no post() call, but event delivered; next no sooner than 10
throttle.advance(1);
ensure_equals("7", cat.result, "136"); // "6" delivered
// 12: post(): immediately passed to listeners, next no sooner than 15
throttle.advance(5);
throttle.post(";12");
ensure_equals("12", cat.result, "136;12"); // "12" delivered
// 17: post(): immediately passed to listeners, next no sooner than 20
throttle.advance(5);
throttle.post(";17");
ensure_equals("17", cat.result, "136;12;17"); // "17" delivered
}
} // namespace tut
/*****************************************************************************

View File

@ -508,6 +508,9 @@ public:
{ return mRegionDenyAnonymousOverride; }
BOOL getRegionDenyAgeUnverifiedOverride() const
{ return mRegionDenyAgeUnverifiedOverride; }
BOOL getRegionAllowAccessOverride() const
{ return mRegionAllowAccessoverride; }
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; }
@ -576,6 +579,7 @@ public:
void setRegionPushOverride(BOOL override) {mRegionPushOverride = override; }
void setRegionDenyAnonymousOverride(BOOL override) { mRegionDenyAnonymousOverride = override; }
void setRegionDenyAgeUnverifiedOverride(BOOL override) { mRegionDenyAgeUnverifiedOverride = override; }
void setRegionAllowAccessOverride(BOOL override) { mRegionAllowAccessoverride = override; }
// Accessors for parcel sellWithObjects
void setPreviousOwnerID(LLUUID prev_owner) { mPreviousOwnerID = prev_owner; }
@ -657,6 +661,7 @@ protected:
BOOL mRegionPushOverride;
BOOL mRegionDenyAnonymousOverride;
BOOL mRegionDenyAgeUnverifiedOverride;
BOOL mRegionAllowAccessoverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;

View File

@ -42,6 +42,9 @@ const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3);
// Does the sun move?
const U64 REGION_FLAGS_SUN_FIXED = (1 << 4);
// Does the estate owner allow private parcels?
const U64 REGION_FLAGS_ALLOW_ACCESS_OVERRIDE = (1 << 5);
// Can't change the terrain heightfield, even on owned parcels,
// but can plant trees and grass.
const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6);

View File

@ -1373,6 +1373,9 @@ char const* const _PREHASH_OwnerMask = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_TransferInventoryAck = LLMessageStringTable::getInstance()->getString("TransferInventoryAck");
char const* const _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getInstance()->getString("RegionDenyAgeUnverified");
char const* const _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock");
char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getInstance()->getString("RegionAllowAccessBlock");
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
char const* const _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex");

View File

@ -1373,6 +1373,8 @@ extern char const* const _PREHASH_OwnerMask;
extern char const* const _PREHASH_TransferInventoryAck;
extern char const* const _PREHASH_RegionDenyAgeUnverified;
extern char const* const _PREHASH_AgeVerificationBlock;
extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
extern char const* const _PREHASH_FaceIndex;

View File

@ -305,6 +305,8 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
}
face = LLVolumeFace();
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
point_map.clear();
}
}
@ -549,6 +551,8 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
}
face = LLVolumeFace();
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
verts.clear();
indices.clear();
point_map.clear();

View File

@ -1405,20 +1405,14 @@ void LLNotifications::createDefaultChannels()
mDefaultChannels.push_back(new LLPersistentNotificationChannel());
// connect action methods to these channels
LLNotifications::instance().getChannel("Enabled")->
connectFailedFilter(&defaultResponse);
LLNotifications::instance().getChannel("Expiration")->
connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
getChannel("Enabled")->connectFailedFilter(&defaultResponse);
getChannel("Expiration")->connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
// uniqueHandler slot should be added as first slot of the signal due to
// usage LLStopWhenHandled combiner in LLStandardSignal
LLNotifications::instance().getChannel("Unique")->
connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
LLNotifications::instance().getChannel("Unique")->
connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
LLNotifications::instance().getChannel("Ignore")->
connectFailedFilter(&handleIgnoredNotification);
LLNotifications::instance().getChannel("VisibilityRules")->
connectFailedFilter(&visibilityRuleMached);
getChannel("Unique")->connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
getChannel("Unique")->connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
getChannel("Ignore")->connectFailedFilter(&handleIgnoredNotification);
getChannel("VisibilityRules")->connectFailedFilter(&visibilityRuleMached);
}

View File

@ -1505,8 +1505,8 @@ void LLTextBase::reflow()
segment_set_t::iterator seg_iter = mSegments.begin();
S32 seg_offset = 0;
S32 line_start_index = 0;
const S32 text_available_width = mVisibleTextRect.getWidth() - mHPad; // reserve room for margin
S32 remaining_pixels = text_available_width;
const F32 text_available_width = mVisibleTextRect.getWidth() - mHPad; // reserve room for margin
F32 remaining_pixels = text_available_width;
S32 line_count = 0;
// find and erase line info structs starting at start_index and going to end of document
@ -1532,14 +1532,15 @@ void LLTextBase::reflow()
S32 cur_index = segment->getStart() + seg_offset;
// ask segment how many character fit in remaining space
S32 character_count = segment->getNumChars(getWordWrap() ? llmax(0, remaining_pixels) : S32_MAX,
S32 character_count = segment->getNumChars(getWordWrap() ? llmax(0, ll_round(remaining_pixels)) : S32_MAX,
seg_offset,
cur_index - line_start_index,
S32_MAX,
line_count - seg_line_offset);
S32 segment_width, segment_height;
bool force_newline = segment->getDimensions(seg_offset, character_count, segment_width, segment_height);
F32 segment_width;
S32 segment_height;
bool force_newline = segment->getDimensionsF32(seg_offset, character_count, segment_width, segment_height);
// grow line height as necessary based on reported height of this segment
line_height = llmax(line_height, segment_height);
remaining_pixels -= segment_width;
@ -1548,11 +1549,13 @@ void LLTextBase::reflow()
S32 last_segment_char_on_line = segment->getStart() + seg_offset;
S32 text_actual_width = text_available_width - remaining_pixels;
// Note: make sure text will fit in width - use ceil, but also make sure
// ceil is used only once per line
S32 text_actual_width = llceil(text_available_width - remaining_pixels);
S32 text_left = getLeftOffset(text_actual_width);
LLRect line_rect(text_left,
cur_top,
text_left + text_actual_width,
text_left + text_actual_width,
cur_top - line_height);
// if we didn't finish the current segment...
@ -3066,7 +3069,15 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc
LLTextSegment::~LLTextSegment()
{}
bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { width = 0; height = 0; return false;}
bool LLTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { width = 0; height = 0; return false; }
bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
{
F32 fwidth = 0;
bool result = getDimensionsF32(first_char, num_chars, fwidth, height);
width = ll_round(fwidth);
return result;
}
S32 LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; }
S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { return 0; }
void LLTextSegment::updateLayout(const LLTextBase& editor) {}
@ -3314,7 +3325,7 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
mTooltip = tooltip;
}
bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
height = 0;
width = 0;
@ -3323,7 +3334,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
height = mFontHeight;
const LLWString &text = getWText();
// if last character is a newline, then return true, forcing line break
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
width = mStyle->getFont()->getWidthF32(text.c_str(), mStart + first_char, num_chars);
}
return false;
}
@ -3491,7 +3502,7 @@ LLInlineViewSegment::~LLInlineViewSegment()
mView->die();
}
bool LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
if (first_char == 0 && num_chars == 0)
{
@ -3578,7 +3589,7 @@ LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLT
LLLineBreakTextSegment::~LLLineBreakTextSegment()
{
}
bool LLLineBreakTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
bool LLLineBreakTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
width = 0;
height = mFontHeight;
@ -3607,7 +3618,7 @@ LLImageTextSegment::~LLImageTextSegment()
static const S32 IMAGE_HPAD = 3;
bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
bool LLImageTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
width = 0;
height = mStyle->getFont()->getLineHeight();

View File

@ -61,8 +61,9 @@ public:
mEnd(end)
{}
virtual ~LLTextSegment();
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
virtual bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
virtual bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
/**
@ -126,7 +127,7 @@ public:
LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
virtual ~LLNormalTextSegment();
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
@ -212,7 +213,7 @@ public:
LLInlineViewSegment(const Params& p, S32 start, S32 end);
~LLInlineViewSegment();
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
/*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
@ -236,7 +237,7 @@ public:
LLLineBreakTextSegment(LLStyleConstSP style,S32 pos);
LLLineBreakTextSegment(S32 pos);
~LLLineBreakTextSegment();
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
@ -249,7 +250,7 @@ class LLImageTextSegment : public LLTextSegment
public:
LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor);
~LLImageTextSegment();
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 char_offset, S32 max_chars, S32 line_ind) const;
F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);

View File

@ -917,7 +917,7 @@ std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLab
//
LLUrlEntryObjectIM::LLUrlEntryObjectIM()
{
mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\?.*",
mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\?\\S*\\w",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_objectim.xml";
}

View File

@ -720,6 +720,15 @@ std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
<< ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS")
<< LL_ENDL;
// Build results vector.
std::vector<std::string> results;
// Disallow filenames that may escape subdir
if (filename.find("..") != std::string::npos)
{
LL_WARNS("LLDir") << "Ignoring potentially relative filename '" << filename << "'" << LL_ENDL;
return results;
}
// Cache the default language directory for each subdir we've encountered.
// A cache entry whose value is the empty string means "not localized,
// don't bother checking again."
@ -784,8 +793,6 @@ std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
}
}
// Build results vector.
std::vector<std::string> results;
// The process we use depends on 'constraint'.
if (constraint != CURRENT_SKIN) // meaning ALL_SKINS
{

View File

@ -2801,7 +2801,7 @@ BOOL LLWindowWin32::pasteTextFromClipboard(LLWString &dst)
if (utf16str)
{
dst = utf16str_to_wstring(utf16str);
LLWStringUtil::removeCRLF(dst);
LLWStringUtil::removeWindowsCR(dst);
GlobalUnlock(h_data);
success = TRUE;
}

View File

@ -255,6 +255,7 @@ set(viewer_SOURCE_FILES
llfloaterlagmeter.cpp
llfloaterland.cpp
llfloaterlandholdings.cpp
llfloaterlinkreplace.cpp
llfloaterloadprefpreset.cpp
llfloatermarketplacelistings.cpp
llfloatermap.cpp
@ -277,6 +278,7 @@ set(viewer_SOURCE_FILES
llfloaterperms.cpp
llfloaterpostprocess.cpp
llfloaterpreference.cpp
llfloaterpreviewtrash.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@ -876,6 +878,7 @@ set(viewer_HEADER_FILES
llfloaterlagmeter.h
llfloaterland.h
llfloaterlandholdings.h
llfloaterlinkreplace.h
llfloaterloadprefpreset.h
llfloatermap.h
llfloatermarketplacelistings.h
@ -898,6 +901,7 @@ set(viewer_HEADER_FILES
llfloaterperms.h
llfloaterpostprocess.h
llfloaterpreference.h
llfloaterpreviewtrash.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h

View File

@ -333,7 +333,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.5</real>
<real>0.3</real>
</map>
<key>AudioLevelMic</key>
<map>
@ -355,7 +355,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.5</real>
<real>0.3</real>
</map>
<key>AudioLevelRolloff</key>
<map>
@ -1619,6 +1619,17 @@
<key>Value</key>
<string>default</string>
</map>
<key>ChatAutocompleteGestures</key>
<map>
<key>Comment</key>
<string>Auto-complete gestures in nearby chat</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ChatBarStealsFocus</key>
<map>
<key>Comment</key>
@ -5439,6 +5450,28 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>LinkReplaceBatchSize</key>
<map>
<key>Comment</key>
<string>The maximum size of a batch in a link replace operation</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>25</integer>
</map>
<key>LinkReplaceBatchPauseTime</key>
<map>
<key>Comment</key>
<string>The time in seconds between two batches in a link replace operation</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>LipSyncAah</key>
<map>
<key>Comment</key>
@ -10157,6 +10190,17 @@
<key>Value</key>
<integer>10</integer>
</map>
<key>MaxAttachmentComplexity</key>
<map>
<key>Comment</key>
<string>Attachment's render weight limit</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0E6</real>
</map>
<key>ComplexityChangesPopUpDelay</key>
<map>
<key>Comment</key>
@ -10723,6 +10767,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>ScriptDialogLimitations</key>
<map>
<key>Comment</key>
<string>Limits amount of dialogs per script (0 - per object, 1 - per channel, 2 - per channel for attachments, 3 - per channel for HUDs, 4 -unconstrained for HUDs)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SecondLifeEnterprise</key>
<map>
<key>Comment</key>
@ -11834,6 +11889,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>SyncMaterialSettings</key>
<map>
<key>Comment</key>
<string>SyncMaterialSettings</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SnapshotQuality</key>
<map>
<key>Comment</key>

View File

@ -1644,7 +1644,7 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)
if (user_cancel && !mAutoPilotBehaviorName.empty())
{
if (mAutoPilotBehaviorName == "Sit")
LLNotificationsUtil::add("CancelledSit");
LL_INFOS("Agent") << "Autopilot-Sit was canceled by user action" << LL_ENDL;
else if (mAutoPilotBehaviorName == "Attach")
LLNotificationsUtil::add("CancelledAttach");
else

View File

@ -2917,11 +2917,32 @@ void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
removeItemsFromAvatar(ids_to_remove);
}
void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
class LLUpdateOnCOFLinkRemove : public LLInventoryCallback
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
public:
LLUpdateOnCOFLinkRemove(const LLUUID& remove_item_id, LLPointer<LLInventoryCallback> cb = NULL):
mItemID(remove_item_id),
mCB(cb)
{
}
LLInventoryModel::cat_array_t cat_array;
/* virtual */ void fire(const LLUUID& item_id)
{
// just removed cof link, "(wear)" suffix depends on presence of link, so update label
gInventory.addChangedMask(LLInventoryObserver::LABEL, mItemID);
if (mCB.notNull())
{
mCB->fire(item_id);
}
}
private:
LLUUID mItemID;
LLPointer<LLInventoryCallback> mCB;
};
void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
{ LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
cat_array,
@ -2932,12 +2953,20 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve
const LLInventoryItem* item = item_array.at(i).get();
if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
{
bool immediate_delete = false;
if (item->getType() == LLAssetType::AT_OBJECT)
{
immediate_delete = true;
// Immediate delete
remove_inventory_item(item->getUUID(), cb, true);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
}
else
{
// Delayed delete
// Pointless to update item_id label here since link still exists and first notifyObservers
// call will restore (wear) suffix, mark for update after deletion
LLPointer<LLUpdateOnCOFLinkRemove> cb_label = new LLUpdateOnCOFLinkRemove(item_id, cb);
remove_inventory_item(item->getUUID(), cb_label, false);
}
remove_inventory_item(item->getUUID(), cb, immediate_delete);
}
}
}

View File

@ -929,7 +929,6 @@ void LLAvatarActions::shareWithAvatars(LLView * panel)
LLNotificationsUtil::add("ShareNotification");
}
// static
bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NULL*/)
{

View File

@ -492,7 +492,7 @@ void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)
mCachedRegionPrefs = new_settings;
// Load region sky presets.
LLWLParamManager::instance().refreshRegionPresets();
LLWLParamManager::instance().refreshRegionPresets(getRegionSettings().getSkyMap());
// If using server settings, update managers.
if (getUseRegionSettings())
@ -525,6 +525,25 @@ void LLEnvManagerNew::initSingleton()
LL_DEBUGS("Windlight") << "Initializing LLEnvManagerNew" << LL_ENDL;
loadUserPrefs();
// preferences loaded, can set params
std::string preferred_day = getDayCycleName();
if (!useDayCycle(preferred_day, LLEnvKey::SCOPE_LOCAL))
{
LL_WARNS() << "No day cycle named " << preferred_day << ", reverting LLWLParamManager to defaults" << LL_ENDL;
LLWLParamManager::instance().setDefaultDay();
}
std::string sky = getSkyPresetName();
if (!useSkyPreset(sky))
{
LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL;
LLWLParamManager::instance().setDefaultSky();
// *TODO: Fix user preferences accordingly.
}
LLWLParamManager::instance().resetAnimator(0.5 /*noon*/, getUseDayCycle());
}
void LLEnvManagerNew::updateSkyFromPrefs()

View File

@ -71,14 +71,16 @@ bool LLEstateInfoModel::getIsExternallyVisible() const { return getFlag(REGION_F
bool LLEstateInfoModel::getAllowDirectTeleport() const { return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT); }
bool LLEstateInfoModel::getDenyAnonymous() const { return getFlag(REGION_FLAGS_DENY_ANONYMOUS); }
bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); }
bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); }
void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); }
void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); }
void LLEstateInfoModel::setAllowDirectTeleport(bool val) { setFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, val); }
void LLEstateInfoModel::setDenyAnonymous(bool val) { setFlag(REGION_FLAGS_DENY_ANONYMOUS, val); }
void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED, val); }
void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); }
void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); }
void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); }
void LLEstateInfoModel::update(const strings_t& strings)
{
@ -145,6 +147,7 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
body["deny_anonymous"] = getDenyAnonymous();
body["deny_age_unverified"] = getDenyAgeUnverified();
body["allow_voice_chat"] = getAllowVoiceChat();
body["override_public_access"] = getAllowAccessOverride();
body["invoice"] = LLFloaterRegionInfo::getLastInvoice();
@ -218,6 +221,7 @@ std::string LLEstateInfoModel::getInfoDump()
dump["deny_anonymous" ] = getDenyAnonymous();
dump["deny_age_unverified" ] = getDenyAgeUnverified();
dump["allow_voice_chat" ] = getAllowVoiceChat();
dump["override_public_access"] = getAllowAccessOverride();
std::stringstream dump_str;
dump_str << dump;

View File

@ -55,6 +55,7 @@ public:
bool getDenyAnonymous() const;
bool getDenyAgeUnverified() const;
bool getAllowVoiceChat() const;
bool getAllowAccessOverride() const;
const std::string& getName() const { return mName; }
const LLUUID& getOwnerID() const { return mOwnerID; }
@ -68,6 +69,7 @@ public:
void setDenyAnonymous(bool val);
void setDenyAgeUnverified(bool val);
void setAllowVoiceChat(bool val);
void setAllowAccessOverride(bool val);
void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }

View File

@ -44,7 +44,7 @@ public:
mExpanderLabel(more_text)
{}
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
// more label always spans width of text box
if (num_chars == 0)

View File

@ -33,6 +33,7 @@
#include "llfloaterreg.h"
#include "llnamelistctrl.h"
#include "llmenugl.h"
#include "lltrans.h"
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
@ -144,6 +145,8 @@ void LLFloaterAvatarRenderSettings::updateList()
item_params.columns.add().value(av_name.getCompleteName()).column("name");
std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
item_params.columns.add().value(setting).column("setting");
std::string timestamp = createTimestamp(LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first));
item_params.columns.add().value(timestamp).column("timestamp");
mAvatarSettingsList->addNameItemRow(item_params);
}
}
@ -205,15 +208,7 @@ void LLFloaterAvatarRenderSettings::onCustomAction (const LLSD& userdata, const
new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
}
LLVOAvatar *avatarp = find_avatar(av_id);
if (avatarp)
{
avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
}
else
{
LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
}
setAvatarRenderSetting(av_id, new_setting);
}
@ -273,14 +268,44 @@ void LLFloaterAvatarRenderSettings::onClickAdd(const LLSD& userdata)
void LLFloaterAvatarRenderSettings::callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting)
{
if (ids.empty()) return;
setAvatarRenderSetting(ids[0], visual_setting);
}
LLVOAvatar *avatarp = find_avatar(ids[0]);
void LLFloaterAvatarRenderSettings::setAvatarRenderSetting(const LLUUID& av_id, S32 new_setting)
{
LLVOAvatar *avatarp = find_avatar(av_id);
if (avatarp)
{
avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(visual_setting));
avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
}
else
{
LLRenderMuteList::getInstance()->saveVisualMuteSetting(ids[0], visual_setting);
LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
}
}
BOOL LLFloaterAvatarRenderSettings::handleKeyHere(KEY key, MASK mask )
{
BOOL handled = FALSE;
if (KEY_DELETE == key)
{
setAvatarRenderSetting(mAvatarSettingsList->getCurrentID(), (S32)LLVOAvatar::AV_RENDER_NORMALLY);
handled = TRUE;
}
return handled;
}
std::string LLFloaterAvatarRenderSettings::createTimestamp(S32 datetime)
{
std::string timeStr;
LLSD substitution;
substitution["datetime"] = datetime;
timeStr = "["+LLTrans::getString ("TimeMonth")+"]/["
+LLTrans::getString ("TimeDay")+"]/["
+LLTrans::getString ("TimeYear")+"]";
LLStringUtil::format (timeStr, substitution);
return timeStr;
}

View File

@ -43,6 +43,7 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void draw();
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
@ -51,6 +52,9 @@ public:
void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
void onClickAdd(const LLSD& userdata);
void setAvatarRenderSetting(const LLUUID& av_id, S32 new_setting);
std::string createTimestamp(S32 datetime);
static void setNeedsUpdate();

View File

@ -485,7 +485,8 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke()
KEY key = gKeyboard->currentKey();
// Ignore "special" keys, like backspace, arrows, etc.
if (length > 1
if (gSavedSettings.getBOOL("ChatAutocompleteGestures")
&& length > 1
&& raw_text[0] == '/'
&& key < KEY_SPECIAL)
{

View File

@ -2432,9 +2432,16 @@ void LLPanelLandAccess::refresh()
BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
BOOL public_access = !use_access_list;
getChild<LLUICtrl>("public_access")->setValue(public_access );
getChild<LLUICtrl>("GroupCheck")->setValue(use_group );
if (parcel->getRegionAllowAccessOverride())
{
getChild<LLUICtrl>("public_access")->setValue(public_access);
getChild<LLUICtrl>("GroupCheck")->setValue(use_group);
}
else
{
getChild<LLUICtrl>("public_access")->setValue(TRUE);
getChild<LLUICtrl>("GroupCheck")->setValue(FALSE);
}
std::string group_name;
gCacheName->getGroupName(parcel->getGroupID(), group_name);
getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name );
@ -2610,9 +2617,14 @@ void LLPanelLandAccess::refresh_ui()
LLParcel *parcel = mParcel->getParcel();
if (parcel && !gDisconnected)
{
BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED);
BOOL can_manage_allowed = false;
BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED);
if (parcel->getRegionAllowAccessOverride())
{ // Estate owner may have disabled allowing the parcel owner from managing access.
can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED);
}
getChildView("public_access")->setEnabled(can_manage_allowed);
BOOL public_access = getChild<LLUICtrl>("public_access")->getValue().asBoolean();
if (public_access)
@ -2666,7 +2678,8 @@ void LLPanelLandAccess::refresh_ui()
std::string group_name;
if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
{
getChildView("GroupCheck")->setEnabled(can_manage_allowed);
bool can_allow_groups = !public_access || (public_access && (getChild<LLUICtrl>("limit_payment")->getValue().asBoolean() ^ getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean()));
getChildView("GroupCheck")->setEnabled(can_manage_allowed && can_allow_groups);
}
getChildView("AccessList")->setEnabled(can_manage_allowed);
S32 allowed_list_count = parcel->mAccessList.size();

View File

@ -0,0 +1,396 @@
/**
* @file llfloaterlinkreplace.cpp
* @brief Allows replacing link targets in inventory links
* @author Ansariel Hiller
*
* $LicenseInfo:firstyear=2017&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterlinkreplace.h"
#include "llagent.h"
#include "llappearancemgr.h"
#include "lllineeditor.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
LLFloaterLinkReplace::LLFloaterLinkReplace(const LLSD& key)
: LLFloater(key),
LLEventTimer(gSavedSettings.getF32("LinkReplaceBatchPauseTime")),
mRemainingItems(0),
mSourceUUID(LLUUID::null),
mTargetUUID(LLUUID::null),
mInstance(NULL),
mBatchSize(gSavedSettings.getU32("LinkReplaceBatchSize"))
{
mEventTimer.stop();
mInstance = this;
}
LLFloaterLinkReplace::~LLFloaterLinkReplace()
{
mInstance = NULL;
}
BOOL LLFloaterLinkReplace::postBuild()
{
mStartBtn = getChild<LLButton>("btn_start");
mStartBtn->setCommitCallback(boost::bind(&LLFloaterLinkReplace::onStartClicked, this));
mRefreshBtn = getChild<LLButton>("btn_refresh");
mRefreshBtn->setCommitCallback(boost::bind(&LLFloaterLinkReplace::checkEnableStart, this));
mSourceEditor = getChild<LLInventoryLinkReplaceDropTarget>("source_uuid_editor");
mTargetEditor = getChild<LLInventoryLinkReplaceDropTarget>("target_uuid_editor");
mSourceEditor->setDADCallback(boost::bind(&LLFloaterLinkReplace::onSourceItemDrop, this, _1));
mTargetEditor->setDADCallback(boost::bind(&LLFloaterLinkReplace::onTargetItemDrop, this, _1));
mStatusText = getChild<LLTextBox>("status_text");
return TRUE;
}
void LLFloaterLinkReplace::onOpen(const LLSD& key)
{
if (key.asUUID().notNull())
{
LLUUID item_id = key.asUUID();
LLViewerInventoryItem* item = gInventory.getItem(item_id);
mSourceEditor->setItem(item);
onSourceItemDrop(item->getLinkedUUID());
}
else
{
checkEnableStart();
}
}
void LLFloaterLinkReplace::onSourceItemDrop(const LLUUID& source_item_id)
{
mSourceUUID = source_item_id;
checkEnableStart();
}
void LLFloaterLinkReplace::onTargetItemDrop(const LLUUID& target_item_id)
{
mTargetUUID = target_item_id;
checkEnableStart();
}
void LLFloaterLinkReplace::updateFoundLinks()
{
LLInventoryModel::item_array_t items;
LLInventoryModel::cat_array_t cat_array;
LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
items,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
mRemainingItems = (U32)items.size();
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsFound", args));
}
void LLFloaterLinkReplace::checkEnableStart()
{
if (mSourceUUID.notNull() && mTargetUUID.notNull() && mSourceUUID == mTargetUUID)
{
mStatusText->setText(getString("ItemsIdentical"));
}
else if (mSourceUUID.notNull())
{
updateFoundLinks();
}
mStartBtn->setEnabled(mRemainingItems > 0 && mSourceUUID.notNull() && mTargetUUID.notNull() && mSourceUUID != mTargetUUID);
}
void LLFloaterLinkReplace::onStartClicked()
{
LL_INFOS() << "Starting inventory link replace" << LL_ENDL;
if (mSourceUUID.isNull() || mTargetUUID.isNull())
{
LL_WARNS() << "Cannot replace. Either source or target UUID is null." << LL_ENDL;
return;
}
if (mSourceUUID == mTargetUUID)
{
LL_WARNS() << "Cannot replace. Source and target are identical." << LL_ENDL;
return;
}
LLInventoryModel::cat_array_t cat_array;
LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
mRemainingInventoryItems,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
if (mRemainingInventoryItems.size() > 0)
{
LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
if (target_item)
{
mRemainingItems = (U32)mRemainingInventoryItems.size();
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsRemaining", args));
mStartBtn->setEnabled(FALSE);
mRefreshBtn->setEnabled(FALSE);
mEventTimer.start();
tick();
}
else
{
mStatusText->setText(getString("TargetNotFound"));
LL_WARNS() << "Link replace target not found." << LL_ENDL;
}
}
}
void LLFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id,
const LLUUID& target_item_id,
bool needs_wearable_ordering_update,
bool needs_description_update,
const LLUUID& outfit_folder_id)
{
LL_DEBUGS() << "Inventory link replace:" << LL_NEWLINE
<< " - old_item_id = " << old_item_id.asString() << LL_NEWLINE
<< " - target_item_id = " << target_item_id.asString() << LL_NEWLINE
<< " - order update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE
<< " - description update = " << (needs_description_update ? "true" : "false") << LL_NEWLINE
<< " - outfit_folder_id = " << outfit_folder_id.asString() << LL_ENDL;
// If we are replacing an object, bodypart or gesture link within an outfit folder,
// we need to change the actual description of the link itself. LLAppearanceMgr *should*
// have created COF links that will be used to save the outfit with an empty description.
// Since link_inventory_array() will set the description of the linked item for the link
// itself, this will lead to a dirty outfit state when the outfit with the replaced
// link is worn. So we have to correct this.
if (needs_description_update && outfit_folder_id.notNull())
{
LLInventoryModel::item_array_t items;
LLInventoryModel::cat_array_t cats;
LLLinkedItemIDMatches is_target_link(target_item_id);
gInventory.collectDescendentsIf(outfit_folder_id,
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
is_target_link);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
LLPointer<LLViewerInventoryItem> item = *it;
if ((item->getType() == LLAssetType::AT_BODYPART ||
item->getType() == LLAssetType::AT_OBJECT ||
item->getType() == LLAssetType::AT_GESTURE)
&& !item->getActualDescription().empty())
{
LL_DEBUGS() << "Updating description for " << item->getName() << LL_ENDL;
LLSD updates;
updates["desc"] = "";
update_inventory_item(item->getUUID(), updates, LLPointer<LLInventoryCallback>(NULL));
}
}
}
LLUUID outfit_update_folder = LLUUID::null;
if (needs_wearable_ordering_update && outfit_folder_id.notNull())
{
// If a wearable item was involved in the link replace operation and replaced
// a link in an outfit folder, we need to update the clothing ordering information
// *after* the original link has been removed. LLAppearanceMgr abuses the actual link
// description to store the clothing ordering information it. We will have to update
// the clothing ordering information or the outfit will be in dirty state when worn.
outfit_update_folder = outfit_folder_id;
}
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::itemRemovedCallback, this, outfit_update_folder));
remove_inventory_object(old_item_id, cb);
}
void LLFloaterLinkReplace::itemRemovedCallback(const LLUUID& outfit_folder_id)
{
if (outfit_folder_id.notNull())
{
LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(outfit_folder_id);
}
if (mInstance)
{
decreaseOpenItemCount();
}
}
void LLFloaterLinkReplace::decreaseOpenItemCount()
{
mRemainingItems--;
if (mRemainingItems == 0)
{
mStatusText->setText(getString("ReplaceFinished"));
mStartBtn->setEnabled(TRUE);
mRefreshBtn->setEnabled(TRUE);
mEventTimer.stop();
LL_INFOS() << "Inventory link replace finished." << LL_ENDL;
}
else
{
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsRemaining", args));
LL_DEBUGS() << "Inventory link replace: " << mRemainingItems << " links remaining..." << LL_ENDL;
}
}
BOOL LLFloaterLinkReplace::tick()
{
LL_DEBUGS() << "Calling tick - remaining items = " << mRemainingInventoryItems.size() << LL_ENDL;
LLInventoryModel::item_array_t current_batch;
for (U32 i = 0; i < mBatchSize; ++i)
{
if (!mRemainingInventoryItems.size())
{
mEventTimer.stop();
break;
}
current_batch.push_back(mRemainingInventoryItems.back());
mRemainingInventoryItems.pop_back();
}
processBatch(current_batch);
return FALSE;
}
void LLFloaterLinkReplace::processBatch(LLInventoryModel::item_array_t items)
{
const LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
const LLUUID cof_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
const LLUUID outfit_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
LLPointer<LLInventoryItem> source_item = *it;
if (source_item->getParentUUID() != cof_folder_id)
{
bool is_outfit_folder = gInventory.isObjectDescendentOf(source_item->getParentUUID(), outfit_folder_id);
// If either the new or old item in the COF is a wearable, we need to update wearable ordering after the link has been replaced
bool needs_wearable_ordering_update = (is_outfit_folder && source_item->getType() == LLAssetType::AT_CLOTHING) || target_item->getType() == LLAssetType::AT_CLOTHING;
// Other items in the COF need a description update (description of the actual link item must be empty)
bool needs_description_update = is_outfit_folder && target_item->getType() != LLAssetType::AT_CLOTHING;
LL_DEBUGS() << "is_outfit_folder = " << (is_outfit_folder ? "true" : "false") << LL_NEWLINE
<< "needs_wearable_ordering_update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE
<< "needs_description_update = " << (needs_description_update ? "true" : "false") << LL_ENDL;
LLInventoryObject::const_object_list_t obj_array;
obj_array.push_back(LLConstPointer<LLInventoryObject>(target_item));
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::linkCreatedCallback,
this,
source_item->getUUID(),
target_item->getUUID(),
needs_wearable_ordering_update,
needs_description_update,
(is_outfit_folder ? source_item->getParentUUID() : LLUUID::null) ));
link_inventory_array(source_item->getParentUUID(), obj_array, cb);
}
else
{
decreaseOpenItemCount();
}
}
}
//////////////////////////////////////////////////////////////////////////////
// LLInventoryLinkReplaceDropTarget
static LLDefaultChildRegistry::Register<LLInventoryLinkReplaceDropTarget> r("inventory_link_replace_drop_target");
BOOL LLInventoryLinkReplaceDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
LLInventoryItem* item = (LLInventoryItem*)cargo_data;
if (cargo_type >= DAD_TEXTURE && cargo_type <= DAD_LINK &&
item && item->getActualType() != LLAssetType::AT_LINK_FOLDER && item->getType() != LLAssetType::AT_CATEGORY &&
(
LLAssetType::lookupCanLink(item->getType()) ||
(item->getType() == LLAssetType::AT_LINK && !gInventory.getObject(item->getLinkedUUID())) // Broken Link!
))
{
if (drop)
{
setItem(item);
if (!mDADSignal.empty())
{
mDADSignal(mItemID);
}
}
else
{
*accept = ACCEPT_YES_SINGLE;
}
}
else
{
*accept = ACCEPT_NO;
}
return TRUE;
}
void LLInventoryLinkReplaceDropTarget::setItem(LLInventoryItem* item)
{
if (item)
{
mItemID = item->getLinkedUUID();
setText(item->getName());
}
else
{
mItemID.setNull();
setText(LLStringExplicit(""));
}
}

View File

@ -0,0 +1,127 @@
/**
* @file llfloaterlinkreplace.h
* @brief Allows replacing link targets in inventory links
* @author Ansariel Hiller
*
* $LicenseInfo:firstyear=2017&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_FLOATERLINKREPLACE_H
#define LL_FLOATERLINKREPLACE_H
#include "llfloater.h"
#include "lleventtimer.h"
#include "lllineeditor.h"
#include "llinventoryfunctions.h"
#include "llviewerinventory.h"
class LLButton;
class LLTextBox;
class LLInventoryLinkReplaceDropTarget : public LLLineEditor
{
public:
struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
{
Params()
{}
};
LLInventoryLinkReplaceDropTarget(const Params& p)
: LLLineEditor(p) {}
~LLInventoryLinkReplaceDropTarget() {}
typedef boost::signals2::signal<void(const LLUUID& id)> item_dad_callback_t;
boost::signals2::connection setDADCallback(const item_dad_callback_t::slot_type& cb)
{
return mDADSignal.connect(cb);
}
virtual BOOL postBuild()
{
setEnabled(FALSE);
return LLLineEditor::postBuild();
}
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
LLUUID getItemID() const { return mItemID; }
void setItem(LLInventoryItem* item);
private:
LLUUID mItemID;
item_dad_callback_t mDADSignal;
};
class LLFloaterLinkReplace : public LLFloater, LLEventTimer
{
LOG_CLASS(LLFloaterLinkReplace);
public:
LLFloaterLinkReplace(const LLSD& key);
virtual ~LLFloaterLinkReplace();
BOOL postBuild();
virtual void onOpen(const LLSD& key);
virtual BOOL tick();
private:
void checkEnableStart();
void onStartClicked();
void decreaseOpenItemCount();
void updateFoundLinks();
void processBatch(LLInventoryModel::item_array_t items);
void linkCreatedCallback(const LLUUID& old_item_id,
const LLUUID& target_item_id,
bool needs_wearable_ordering_update,
bool needs_description_update,
const LLUUID& outfit_folder_id);
void itemRemovedCallback(const LLUUID& outfit_folder_id);
void onSourceItemDrop(const LLUUID& source_item_id);
void onTargetItemDrop(const LLUUID& target_item_id);
LLInventoryLinkReplaceDropTarget* mSourceEditor;
LLInventoryLinkReplaceDropTarget* mTargetEditor;
LLButton* mStartBtn;
LLButton* mRefreshBtn;
LLTextBox* mStatusText;
LLUUID mSourceUUID;
LLUUID mTargetUUID;
U32 mRemainingItems;
U32 mBatchSize;
LLInventoryModel::item_array_t mRemainingInventoryItems;
LLFloaterLinkReplace* mInstance;
};
#endif // LL_FLOATERLINKREPLACE_H

View File

@ -1262,6 +1262,10 @@ LLModelPreview::~LLModelPreview()
// glod.dll!glodShutdown() + 0x77 bytes
//
//glodShutdown();
if(mModelLoader)
{
mModelLoader->shutdown();
}
}
U32 LLModelPreview::calcResourceCost()

View File

@ -0,0 +1,82 @@
/**
* @file llfloaterpreviewtrash.cpp
* @author AndreyK Productengine
* @brief LLFloaterPreviewTrash class implementation
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterpreviewtrash.h"
#include "llinventoryfunctions.h"
#include "llfloaterreg.h"
LLFloaterPreviewTrash::LLFloaterPreviewTrash(const LLSD& key)
: LLFloater(key)
{
}
BOOL LLFloaterPreviewTrash::postBuild()
{
getChild<LLUICtrl>("empty_btn")->setCommitCallback(
boost::bind(&LLFloaterPreviewTrash::onClickEmpty, this));
getChild<LLUICtrl>("cancel_btn")->setCommitCallback(
boost::bind(&LLFloaterPreviewTrash::onClickCancel, this));
// Always center the dialog. User can change the size,
// but purchases are important and should be center screen.
// This also avoids problems where the user resizes the application window
// mid-session and the saved rect is off-center.
center();
return TRUE;
}
LLFloaterPreviewTrash::~LLFloaterPreviewTrash()
{
}
// static
void LLFloaterPreviewTrash::show()
{
LLFloaterReg::showTypedInstance<LLFloaterPreviewTrash>("preview_trash", LLSD(), TRUE);
}
// static
bool LLFloaterPreviewTrash::isVisible()
{
return LLFloaterReg::instanceVisible("preview_trash");
}
void LLFloaterPreviewTrash::onClickEmpty()
{
gInventory.emptyFolderType("PurgeSelectedItems", LLFolderType::FT_TRASH);
closeFloater();
}
void LLFloaterPreviewTrash::onClickCancel()
{
closeFloater();
}

View File

@ -0,0 +1,49 @@
/**
* @file llfloaterpreviewtrash.h
* @author AndreyK Productengine
* @brief LLFloaterPreviewTrash class header file
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERPREVIEWTRASH_H
#define LL_LLFLOATERPREVIEWTRASH_H
#include "llfloater.h"
class LLFloaterPreviewTrash
: public LLFloater
{
public:
static void show();
static bool isVisible();
LLFloaterPreviewTrash(const LLSD& key);
~LLFloaterPreviewTrash();
/*virtual*/ BOOL postBuild();
protected:
void onClickEmpty();
void onClickCancel();
};
#endif

View File

@ -2235,11 +2235,12 @@ bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg)
BOOL LLPanelEstateInfo::postBuild()
{
// set up the callbacks for the generic controls
initCtrl("externally_visible_check");
initCtrl("externally_visible_radio");
initCtrl("allow_direct_teleport");
initCtrl("limit_payment");
initCtrl("limit_age_verified");
initCtrl("voice_chat_check");
initCtrl("parcel_access_override");
getChild<LLUICtrl>("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
LLNameListCtrl *avatar_name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list");
@ -2287,13 +2288,15 @@ BOOL LLPanelEstateInfo::postBuild()
childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this));
childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this));
getChild<LLUICtrl>("parcel_access_override")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAccessOverride, this));
return LLPanelRegionInfo::postBuild();
}
void LLPanelEstateInfo::refresh()
{
// Disable access restriction controls if they make no sense.
bool public_access = getChild<LLUICtrl>("externally_visible_check")->getValue().asBoolean();
bool public_access = getChild<LLRadioGroup>("externally_visible_radio")->getSelectedIndex();
getChildView("Only Allow")->setEnabled(public_access);
getChildView("limit_payment")->setEnabled(public_access);
@ -2314,11 +2317,12 @@ void LLPanelEstateInfo::refreshFromEstate()
getChild<LLUICtrl>("estate_name")->setValue(estate_info.getName());
setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString());
getChild<LLUICtrl>("externally_visible_check")->setValue(estate_info.getIsExternallyVisible());
getChild<LLRadioGroup>("externally_visible_radio")->setSelectedIndex(estate_info.getIsExternallyVisible() ? 1 : 0);
getChild<LLUICtrl>("voice_chat_check")->setValue(estate_info.getAllowVoiceChat());
getChild<LLUICtrl>("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport());
getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
getChild<LLUICtrl>("parcel_access_override")->setValue(estate_info.getAllowAccessOverride());
// Ensure appriopriate state of the management UI
updateControls(gAgent.getRegion());
@ -2356,12 +2360,14 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
// update model
estate_info.setUseFixedSun(false); // we don't support fixed sun estates anymore
estate_info.setIsExternallyVisible(getChild<LLUICtrl>("externally_visible_check")->getValue().asBoolean());
estate_info.setIsExternallyVisible(getChild<LLRadioGroup>("externally_visible_radio")->getSelectedIndex());
estate_info.setAllowDirectTeleport(getChild<LLUICtrl>("allow_direct_teleport")->getValue().asBoolean());
estate_info.setDenyAnonymous(getChild<LLUICtrl>("limit_payment")->getValue().asBoolean());
estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
estate_info.setAllowAccessOverride(getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean());
// JIGGLYPUFF
//estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean());
// send the update to sim
estate_info.sendEstateInfo();
}
@ -2462,6 +2468,14 @@ bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& re
return false;
}
void LLPanelEstateInfo::onChangeAccessOverride()
{
if (!getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean())
{
LLNotificationsUtil::add("EstateParcelAccessOverride");
}
}
LLPanelEstateCovenant::LLPanelEstateCovenant()
:
mCovenantID(LLUUID::null),

View File

@ -274,6 +274,7 @@ public:
void onChangeFixedSun();
void onChangeUseGlobalTime();
void onChangeAccessOverride();
void onClickEditSky();
void onClickEditSkyHelp();

View File

@ -269,8 +269,11 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg)
{
if(!gAgent.isDoNotDisturb())
{
// Open conversations floater
LLFloaterReg::showInstance("im_container");
if(!LLAppViewer::instance()->quitRequested() && !LLFloater::isVisible(im_box))
{
// Open conversations floater
LLFloaterReg::showInstance("im_container");
}
im_box->collapseMessagesPane(false);
if (session_floater)
{
@ -2677,49 +2680,57 @@ void LLIMMgr::addMessage(
LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id);
skip_message &= !session->isGroupSessionType(); // Do not skip group chats...
if(skip_message)
if (session)
{
gIMMgr->leaveSession(new_session_id);
}
// When we get a new IM, and if you are a god, display a bit
// of information about the source. This is to help liaisons
// when answering questions.
if(gAgent.isGodlike())
{
// *TODO:translate (low priority, god ability)
std::ostringstream bonus_info;
bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + ":" + " "
<< parent_estate_id
<< ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "")
<< ((parent_estate_id == 5) ? "," + LLTrans::getString ("IMTeen") : "");
// once we have web-services (or something) which returns
// information about a region id, we can print this out
// and even have it link to map-teleport or something.
//<< "*** region_id: " << region_id << std::endl
//<< "*** position: " << position << std::endl;
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
}
// Logically it would make more sense to reject the session sooner, in another area of the
// code, but the session has to be established inside the server before it can be left.
if (LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !from_linden)
{
LL_WARNS() << "Leaving IM session from initiating muted resident " << from << LL_ENDL;
if(!gIMMgr->leaveSession(new_session_id))
skip_message &= !session->isGroupSessionType(); // Do not skip group chats...
if (skip_message)
{
LL_INFOS() << "Session " << new_session_id << " does not exist." << LL_ENDL;
gIMMgr->leaveSession(new_session_id);
}
return;
}
// When we get a new IM, and if you are a god, display a bit
// of information about the source. This is to help liaisons
// when answering questions.
if (gAgent.isGodlike())
{
// *TODO:translate (low priority, god ability)
std::ostringstream bonus_info;
bonus_info << LLTrans::getString("***") + " " + LLTrans::getString("IMParentEstate") + ":" + " "
<< parent_estate_id
<< ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "")
<< ((parent_estate_id == 5) ? "," + LLTrans::getString("IMTeen") : "");
//Play sound for new conversations
if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
{
make_ui_sound("UISndNewIncomingIMSession");
}
// once we have web-services (or something) which returns
// information about a region id, we can print this out
// and even have it link to map-teleport or something.
//<< "*** region_id: " << region_id << std::endl
//<< "*** position: " << position << std::endl;
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
}
// Logically it would make more sense to reject the session sooner, in another area of the
// code, but the session has to be established inside the server before it can be left.
if (LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !from_linden)
{
LL_WARNS() << "Leaving IM session from initiating muted resident " << from << LL_ENDL;
if (!gIMMgr->leaveSession(new_session_id))
{
LL_INFOS() << "Session " << new_session_id << " does not exist." << LL_ENDL;
}
return;
}
//Play sound for new conversations
if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
{
make_ui_sound("UISndNewIncomingIMSession");
}
}
else
{
// Failed to create a session, most likely due to empty name (name cache failed?)
LL_WARNS() << "Failed to create IM session " << fixed_session_name << LL_ENDL;
}
}
if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
@ -3022,7 +3033,7 @@ void LLIMMgr::inviteToSession(
LLIncomingCallDialog::processCallResponse(1, payload);
return;
}
else if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat))
else if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat) && !voice_invite)
{
LL_INFOS() << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
return;

View File

@ -391,6 +391,7 @@ void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
}
}
removeBatchNoCheck(batch);
model->checkTrashOverflow();
}
void LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch)
@ -851,6 +852,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
getClipboardEntries(true, items, disabled_items, flags);
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -1051,6 +1053,20 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
items.push_back(std::string("Marketplace Listings Separator"));
}
void LLInvFVBridge::addLinkReplaceMenuOption(menuentry_vec_t& items, menuentry_vec_t& disabled_items)
{
const LLInventoryObject* obj = getInventoryObject();
if (isAgentInventory() && obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getType() != LLAssetType::AT_LINK_FOLDER)
{
items.push_back(std::string("Replace Links"));
if (mRoot->getSelectedCount() != 1)
{
disabled_items.push_back(std::string("Replace Links"));
}
}
}
// *TODO: remove this
BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
@ -3855,6 +3871,13 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
if(trash_id == mUUID)
{
bool is_recent_panel = false;
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (active_panel && (active_panel->getName() == "Recent Items"))
{
is_recent_panel = true;
}
// This is the trash.
items.push_back(std::string("Empty Trash"));
@ -3862,7 +3885,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
LLInventoryModel::item_array_t* item_array;
gInventory.getDirectDescendentsOf(mUUID, cat_array, item_array);
// Enable Empty menu item only when there is something to act upon.
if (0 == cat_array->size() && 0 == item_array->size())
if ((0 == cat_array->size() && 0 == item_array->size()) || is_recent_panel)
{
disabled_items.push_back(std::string("Empty Trash"));
}
@ -5179,6 +5202,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
disabled_items.push_back(std::string("Save As"));
}
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -5251,6 +5275,7 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Sound Play"));
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -5339,6 +5364,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
disabled_items.push_back(std::string("About Landmark"));
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -5641,6 +5667,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
disabled_items.push_back(std::string("Conference Chat"));
}
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -5910,6 +5937,7 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Activate"));
}
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -5967,6 +5995,7 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Animation Audition"));
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -6283,6 +6312,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
}
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -6511,6 +6541,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
}
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -6682,6 +6713,7 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Properties"));
addDeleteContextMenuOptions(items, disabled_items);
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
@ -6733,6 +6765,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
getClipboardEntries(true, items, disabled_items, flags);
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}

View File

@ -148,6 +148,9 @@ protected:
virtual void addMarketplaceContextMenuOptions(U32 flags,
menuentry_vec_t &items,
menuentry_vec_t &disabled_items);
virtual void addLinkReplaceMenuOption(menuentry_vec_t& items,
menuentry_vec_t& disabled_items);
protected:
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);

View File

@ -2306,6 +2306,26 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
// Clear the clipboard before we start adding things on it
LLClipboard::instance().reset();
}
if ("replace_links" == action)
{
LLSD params;
if (root->getSelectedCount() == 1)
{
LLFolderViewItem* folder_item = root->getSelectedItems().front();
LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
if (bridge)
{
LLInventoryObject* obj = bridge->getInventoryObject();
if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER)
{
params = LLSD(obj->getUUID());
}
}
}
LLFloaterReg::showInstance("linkreplace", params);
return;
}
static const std::string change_folder_string = "change_folder_type_";
if (action.length() > change_folder_string.length() &&

View File

@ -41,6 +41,7 @@
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "llfloaterpreviewtrash.h"
#include "llnotificationsutil.h"
#include "llmarketplacefunctions.h"
#include "llwindow.h"
@ -3299,9 +3300,7 @@ void LLInventoryModel::processMoveInventoryItem(LLMessageSystem* msg, void**)
}
//----------------------------------------------------------------------------
// Trash: LLFolderType::FT_TRASH, "ConfirmEmptyTrash"
// Trash: LLFolderType::FT_TRASH, "TrashIsFull" when trash exceeds maximum capacity
// Lost&Found: LLFolderType::FT_LOST_AND_FOUND, "ConfirmEmptyLostAndFound"
bool LLInventoryModel::callbackEmptyFolderType(const LLSD& notification, const LLSD& response, LLFolderType::EType preferred_type)
@ -3319,7 +3318,14 @@ void LLInventoryModel::emptyFolderType(const std::string notification, LLFolderT
{
if (!notification.empty())
{
LLNotificationsUtil::add(notification, LLSD(), LLSD(),
LLSD args;
if(LLFolderType::FT_TRASH == preferred_type)
{
static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity");
const LLUUID trash_id = findCategoryUUIDForType(preferred_type);
args["COUNT"] = (S32)getDescendentsCountRecursive(trash_id, trash_max_capacity);
}
LLNotificationsUtil::add(notification, args, LLSD(),
boost::bind(&LLInventoryModel::callbackEmptyFolderType, this, _1, _2, preferred_type));
}
else
@ -3415,13 +3421,32 @@ void LLInventoryModel::removeObject(const LLUUID& object_id)
}
}
bool callback_preview_trash_folder(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0) // YES
{
LLFloaterPreviewTrash::show();
}
return false;
}
void LLInventoryModel::checkTrashOverflow()
{
static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity");
const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
if (getDescendentsCountRecursive(trash_id, trash_max_capacity) >= trash_max_capacity)
{
gInventory.emptyFolderType("TrashIsFull", LLFolderType::FT_TRASH);
if (LLFloaterPreviewTrash::isVisible())
{
// bring to front
LLFloaterPreviewTrash::show();
}
else
{
LLNotificationsUtil::add("TrashIsFull", LLSD(), LLSD(),
boost::bind(callback_preview_trash_folder, _1, _2));
}
}
}

View File

@ -411,6 +411,7 @@ public:
/// removeItem() or removeCategory(), whichever is appropriate
void removeObject(const LLUUID& object_id);
// "TrashIsFull" when trash exceeds maximum capacity
void checkTrashOverflow();
protected:

View File

@ -76,13 +76,6 @@
// * Review the download rate throttling. Slow then fast?
// Detect bandwidth usage and speed up when it drops?
//
// * A lot of calls to notifyObservers(). It looks like
// these could be collapsed by maintaining a 'dirty'
// bit and there appears to be an attempt to do this.
// But it isn't used or is used in a limited fashion.
// Are there semanic issues requiring a call after certain
// updateItem() calls?
//
// * An error on a fetch could be due to one item in the batch.
// If the batch were broken up, perhaps more of the inventory
// would download. (Handwave here, not certain this is an
@ -393,6 +386,12 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
{
// Process completed background HTTP requests
gInventory.handleResponses(false);
// Just processed a bunch of items.
// Note: do we really need notifyObservers() here?
// OnIdle it will be called anyway due to Add flag for processed item.
// It seems like in some cases we are updaiting on fail (no flag),
// but is there anything to update?
gInventory.notifyObservers();
}
if ((mFetchCount > max_concurrent_fetches) ||
@ -711,7 +710,6 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res
titem->setParent(lost_uuid);
titem->updateParentOnServer(FALSE);
gInventory.updateItem(titem);
gInventory.notifyObservers();
}
}
}
@ -784,8 +782,6 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res
{
fetcher->setAllFoldersFetched();
}
gInventory.notifyObservers();
}
@ -828,7 +824,6 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http
fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers();
}
@ -866,7 +861,6 @@ void BGFolderHttpHandler::processFailure(const char * const reason, LLCore::Http
fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers();
}

View File

@ -43,6 +43,7 @@
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llnotificationsutil.h"
#include "llpreview.h"
#include "llsidepanelinventory.h"
#include "lltrans.h"
@ -1211,6 +1212,33 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
}
}
void LLInventoryPanel::purgeSelectedItems()
{
const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
if (inventory_selected.empty()) return;
LLSD args;
args["COUNT"] = (S32)inventory_selected.size();
LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(&LLInventoryPanel::callbackPurgeSelectedItems, this, _1, _2));
}
void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
if (inventory_selected.empty()) return;
std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
for (; it != it_end; ++it)
{
LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
remove_inventory_object(item_id, NULL);
}
}
}
bool LLInventoryPanel::attachObject(const LLSD& userdata)
{
// Copy selected item UUIDs to a vector.
@ -1448,6 +1476,11 @@ void LLInventoryPanel::updateSelection()
void LLInventoryPanel::doToSelected(const LLSD& userdata)
{
if (("purge" == userdata.asString()))
{
purgeSelectedItems();
return;
}
LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), userdata.asString());
return;
@ -1482,7 +1515,9 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
}
break;
case KEY_DELETE:
#if LL_DARWIN
case KEY_BACKSPACE:
#endif
// Delete selected items if delete or backspace key hit on the inventory panel
// Note: on Mac laptop keyboards, backspace and delete are one and the same
if (isSelectionRemovable() && (mask == MASK_NONE))

View File

@ -202,6 +202,7 @@ public:
void doCreate(const LLSD& userdata);
bool beginIMSession();
void fileUploadLocation(const LLSD& userdata);
void purgeSelectedItems();
bool attachObject(const LLSD& userdata);
static void idle(void* user_data);
@ -232,6 +233,8 @@ public:
// Clean up stuff when the folder root gets deleted
void clearFolderRoot();
void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response);
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
void onItemsCompletion(); // called when selected items are complete

View File

@ -67,7 +67,8 @@ const std::string LL_IM_FROM("from");
const std::string LL_IM_FROM_ID("from_id");
const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
const static std::string IM_SEPARATOR(": ");
const static char IM_SYMBOL_SEPARATOR(':');
const static std::string IM_SEPARATOR(std::string() + IM_SYMBOL_SEPARATOR + " ");
const static std::string NEW_LINE("\n");
const static std::string NEW_LINE_SPACE_PREFIX("\n ");
const static std::string TWO_SPACES(" ");
@ -838,7 +839,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
}
if (im[LL_IM_TIME].isDefined())
{
{
std::string timestamp = im[LL_IM_TIME].asString();
boost::trim(timestamp);
ostr << '[' << timestamp << ']' << TWO_SPACES;
@ -851,9 +852,29 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
{
std::string from = im[LL_IM_FROM].asString();
boost::trim(from);
if (from.size())
std::size_t found = from.find(IM_SYMBOL_SEPARATOR);
std::size_t len = from.size();
std::size_t start = 0;
while (found != std::string::npos)
{
ostr << from << IM_SEPARATOR;
std::size_t sub_len = found - start;
if (sub_len > 0)
{
ostr << from.substr(start, sub_len);
}
LLURI::encodeCharacter(ostr, IM_SYMBOL_SEPARATOR);
start = found + 1;
found = from.find(IM_SYMBOL_SEPARATOR, start);
}
if (start < len)
{
std::string str_end = from.substr(start, len - start);
ostr << str_end;
}
if (len > 0)
{
ostr << IM_SEPARATOR;
}
}
@ -865,7 +886,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
ostr << im_text;
}
}
}
bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params)
{
@ -912,7 +933,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
if (!boost::regex_match(stuff, name_and_text, NAME_AND_TEXT)) return false;
bool has_name = name_and_text[IDX_NAME].matched;
std::string name = name_and_text[IDX_NAME];
std::string name = LLURI::unescape(name_and_text[IDX_NAME]);
//we don't need a name/text separator
if (has_name && name.length() && name[name.length()-1] == ':')
@ -933,7 +954,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
std::string::size_type divider_pos = stuff.find(NAME_TEXT_DIVIDER);
if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
{
im[LL_IM_FROM] = stuff.substr(0, divider_pos);
im[LL_IM_FROM] = LLURI::unescape(stuff.substr(0, divider_pos));
im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
return true;
}

View File

@ -3626,7 +3626,15 @@ void LLMeshRepository::notifyLoadedMeshes()
//popup queued error messages from background threads
while (!mUploadErrorQ.empty())
{
LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front());
LLSD substitutions(mUploadErrorQ.front());
if (substitutions.has("DETAILS"))
{
LLNotificationsUtil::add("MeshUploadErrorDetails", substitutions);
}
else
{
LLNotificationsUtil::add("MeshUploadError", substitutions);
}
mUploadErrorQ.pop();
}

View File

@ -825,13 +825,14 @@ bool LLRenderMuteList::saveToFile()
LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
return false;
}
for (std::map<LLUUID, S32>::iterator it = sVisuallyMuteSettingsMap.begin(); it != sVisuallyMuteSettingsMap.end(); ++it)
{
if (it->second != 0)
{
std::string id_string;
it->first.toString(id_string);
fprintf(fp, "%d %s\n", (S32)it->second, id_string.c_str());
fprintf(fp, "%d %s [%d]\n", (S32)it->second, id_string.c_str(), (S32)sVisuallyMuteDateMap[it->first]);
}
}
fclose(fp);
@ -854,8 +855,10 @@ bool LLRenderMuteList::loadFromFile()
{
id_buffer[0] = '\0';
S32 setting = 0;
sscanf(buffer, " %d %254s\n", &setting, id_buffer);
S32 time = 0;
sscanf(buffer, " %d %254s [%d]\n", &setting, id_buffer, &time);
sVisuallyMuteSettingsMap[LLUUID(id_buffer)] = setting;
sVisuallyMuteDateMap[LLUUID(id_buffer)] = (time == 0) ? (S32)time_corrected() : time;
}
fclose(fp);
return true;
@ -866,10 +869,15 @@ void LLRenderMuteList::saveVisualMuteSetting(const LLUUID& agent_id, S32 setting
if(setting == 0)
{
sVisuallyMuteSettingsMap.erase(agent_id);
sVisuallyMuteDateMap.erase(agent_id);
}
else
{
sVisuallyMuteSettingsMap[agent_id] = setting;
if (sVisuallyMuteDateMap.find(agent_id) == sVisuallyMuteDateMap.end())
{
sVisuallyMuteDateMap[agent_id] = (S32)time_corrected();
}
}
saveToFile();
notifyObservers();
@ -886,6 +894,17 @@ S32 LLRenderMuteList::getSavedVisualMuteSetting(const LLUUID& agent_id)
return 0;
}
S32 LLRenderMuteList::getVisualMuteDate(const LLUUID& agent_id)
{
std::map<LLUUID, S32>::iterator iter = sVisuallyMuteDateMap.find(agent_id);
if (iter != sVisuallyMuteDateMap.end())
{
return iter->second;
}
return 0;
}
void LLRenderMuteList::addObserver(LLMuteListObserver* observer)
{
mObservers.insert(observer);

View File

@ -184,10 +184,13 @@ public:
S32 getSavedVisualMuteSetting(const LLUUID& agent_id);
void saveVisualMuteSetting(const LLUUID& agent_id, S32 setting);
S32 getVisualMuteDate(const LLUUID& agent_id);
void addObserver(LLMuteListObserver* observer);
void removeObserver(LLMuteListObserver* observer);
std::map<LLUUID, S32> sVisuallyMuteSettingsMap;
std::map<LLUUID, S32> sVisuallyMuteDateMap;
private:
void notifyObservers();

View File

@ -34,6 +34,7 @@
#include "llcommonutils.h"
#include "llvfile.h"
#include "llaccordionctrltab.h"
#include "llappearancemgr.h"
#include "lleconomy.h"
#include "llerror.h"
@ -46,6 +47,8 @@
#include "llinventorymodel.h"
#include "lllocalbitmaps.h"
#include "llnotificationsutil.h"
#include "llpaneloutfitsinventory.h"
#include "lltabcontainer.h"
#include "lltexturectrl.h"
#include "lltrans.h"
#include "llviewercontrol.h"
@ -742,6 +745,33 @@ BOOL LLOutfitGalleryItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
return LLUICtrl::handleRightMouseDown(x, y, mask);
}
BOOL LLOutfitGallery::handleDoubleClick(S32 x, S32 y, MASK mask)
{
LLTabContainer* appearence_tabs = LLPanelOutfitsInventory::findInstance()->getChild<LLTabContainer>("appearance_tabs");
LLPanel* panel = NULL;
LLAccordionCtrl* accordion = NULL;
if (appearence_tabs != NULL)
{
appearence_tabs->selectTabByName("outfitslist_tab");
panel = appearence_tabs->getCurrentPanel();
if (panel != NULL)
{
accordion = panel->getChild<LLAccordionCtrl>("outfits_accordion");
LLOutfitsList* outfit_list = dynamic_cast<LLOutfitsList*>(panel);
if (accordion != NULL && outfit_list != NULL)
{
LLUUID item_id = getSelectedOutfitUUID();
outfit_list->setSelectedOutfitByUUID(item_id);
LLAccordionCtrlTab* tab = accordion->getSelectedTab();
tab->showAndFocusHeader();
return TRUE;
}
}
}
return LLUICtrl::handleDoubleClick(x, y, mask);
}
void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
{
mImageAssetId = image_asset_id;

View File

@ -114,6 +114,9 @@ public:
void onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture);
void onBeforeOutfitSnapshotSave();
void onAfterOutfitSnapshotSave();
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
protected:
/*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
/*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);

View File

@ -311,7 +311,7 @@ void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
tab->setFocus(TRUE);
ChangeOutfitSelection(list, outfit_uuid);
tab->setDisplayChildren(true);
tab->changeOpenClose(false);
}
}
}

View File

@ -123,6 +123,7 @@ void LLPanelBlockedList::onOpen(const LLSD& key)
void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
{
mBlockedList->resetSelection();
mBlockedList->selectItemByUUID(mute_id);
}

View File

@ -131,13 +131,13 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureScaleX, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureScaleY, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureRot, this);
childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureOffsetX, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureOffsetY, this);
childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this);
childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this);
@ -691,6 +691,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
getChildView("radio_material_type")->setEnabled(editable);
getChildView("checkbox_sync_settings")->setEnabled(editable);
childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings"));
updateVisibility();
bool identical = true; // true because it is anded below
@ -1862,12 +1864,39 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
LLSelectedTEMaterial::setNormalOffsetX(self,offsetU);
LLSelectedTEMaterial::setSpecularOffsetX(self,offsetU);
self->getChild<LLSpinCtrl>("TexOffsetU")->forceSetValue(offsetU);
self->sendTextureInfo();
}
//static
void LLPanelFace::syncOffsetY(LLPanelFace* self, F32 offsetV)
{
LLSelectedTEMaterial::setNormalOffsetY(self,offsetV);
LLSelectedTEMaterial::setSpecularOffsetY(self,offsetV);
self->getChild<LLSpinCtrl>("TexOffsetV")->forceSetValue(offsetV);
self->sendTextureInfo();
}
//static
void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
llassert_always(self);
LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU());
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncOffsetX(self,self->getCurrentBumpyOffsetU());
}
else
{
LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU());
}
}
//static
@ -1875,7 +1904,15 @@ void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
llassert_always(self);
LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV());
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncOffsetY(self,self->getCurrentBumpyOffsetV());
}
else
{
LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV());
}
}
//static
@ -1883,7 +1920,15 @@ void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
llassert_always(self);
LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU());
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncOffsetX(self, self->getCurrentShinyOffsetU());
}
else
{
LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU());
}
}
//static
@ -1891,7 +1936,31 @@ void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
llassert_always(self);
LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV());
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncOffsetY(self,self->getCurrentShinyOffsetV());
}
else
{
LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV());
}
}
//static
void LLPanelFace::syncRepeatX(LLPanelFace* self, F32 scaleU)
{
LLSelectedTEMaterial::setNormalRepeatX(self,scaleU);
LLSelectedTEMaterial::setSpecularRepeatX(self,scaleU);
self->sendTextureInfo();
}
//static
void LLPanelFace::syncRepeatY(LLPanelFace* self, F32 scaleV)
{
LLSelectedTEMaterial::setNormalRepeatY(self,scaleV);
LLSelectedTEMaterial::setSpecularRepeatY(self,scaleV);
self->sendTextureInfo();
}
//static
@ -1904,7 +1973,16 @@ void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata)
{
bumpy_scale_u *= 0.5f;
}
LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u);
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
self->getChild<LLSpinCtrl>("TexScaleU")->forceSetValue(self->getCurrentBumpyScaleU());
syncRepeatX(self, bumpy_scale_u);
}
else
{
LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u);
}
}
//static
@ -1917,7 +1995,17 @@ void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata)
{
bumpy_scale_v *= 0.5f;
}
LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v);
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
self->getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(self->getCurrentBumpyScaleV());
syncRepeatY(self, bumpy_scale_v);
}
else
{
LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v);
}
}
//static
@ -1930,7 +2018,16 @@ void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata)
{
shiny_scale_u *= 0.5f;
}
LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u);
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
self->getChild<LLSpinCtrl>("TexScaleU")->forceSetValue(self->getCurrentShinyScaleU());
syncRepeatX(self, shiny_scale_u);
}
else
{
LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u);
}
}
//static
@ -1943,7 +2040,24 @@ void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata)
{
shiny_scale_v *= 0.5f;
}
LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v);
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
self->getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(self->getCurrentShinyScaleV());
syncRepeatY(self, shiny_scale_v);
}
else
{
LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v);
}
}
//static
void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot)
{
LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD);
LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD);
self->sendTextureInfo();
}
//static
@ -1951,7 +2065,16 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
llassert_always(self);
LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD);
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
self->getChild<LLSpinCtrl>("TexRot")->forceSetValue(self->getCurrentBumpyRot());
syncMaterialRot(self, self->getCurrentBumpyRot());
}
else
{
LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD);
}
}
//static
@ -1959,7 +2082,16 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
llassert_always(self);
LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD);
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
self->getChild<LLSpinCtrl>("TexRot")->forceSetValue(self->getCurrentShinyRot());
syncMaterialRot(self, self->getCurrentShinyRot());
}
else
{
LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD);
}
}
//static
@ -1994,6 +2126,92 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureScaleX( LLUICtrl* ctrl, void* userdata )
{
LLPanelFace* self = (LLPanelFace*) userdata;
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
F32 bumpy_scale_u = self->getChild<LLUICtrl>("TexScaleU")->getValue().asReal();
if (self->isIdenticalPlanarTexgen())
{
bumpy_scale_u *= 0.5f;
}
syncRepeatX(self, bumpy_scale_u);
}
else
{
self->sendTextureInfo();
}
self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureScaleY( LLUICtrl* ctrl, void* userdata )
{
LLPanelFace* self = (LLPanelFace*) userdata;
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
F32 bumpy_scale_v = self->getChild<LLUICtrl>("TexScaleV")->getValue().asReal();
if (self->isIdenticalPlanarTexgen())
{
bumpy_scale_v *= 0.5f;
}
syncRepeatY(self, bumpy_scale_v);
}
else
{
self->sendTextureInfo();
}
self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureRot( LLUICtrl* ctrl, void* userdata )
{
LLPanelFace* self = (LLPanelFace*) userdata;
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncMaterialRot(self, self->getChild<LLUICtrl>("TexRot")->getValue().asReal());
}
else
{
self->sendTextureInfo();
}
self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureOffsetX( LLUICtrl* ctrl, void* userdata )
{
LLPanelFace* self = (LLPanelFace*) userdata;
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncOffsetX(self, self->getChild<LLUICtrl>("TexOffsetU")->getValue().asReal());
}
else
{
self->sendTextureInfo();
}
self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureOffsetY( LLUICtrl* ctrl, void* userdata )
{
LLPanelFace* self = (LLPanelFace*) userdata;
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
syncOffsetY(self, self->getChild<LLUICtrl>("TexOffsetV")->getValue().asReal());
}
else
{
self->sendTextureInfo();
}
self->updateUI(true);
}
// Commit the number of repeats per meter
// static
void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
@ -2017,44 +2235,62 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s);
LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t);
LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU");
LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV");
LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU");
LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV");
switch (material_type)
if (gSavedSettings.getBOOL("SyncMaterialSettings"))
{
case MATTYPE_DIFFUSE:
{
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
}
break;
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
case MATTYPE_NORMAL:
{
LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU");
LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV");
bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
}
else
{
switch (material_type)
{
case MATTYPE_DIFFUSE:
{
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
}
break;
case MATTYPE_NORMAL:
{
bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
}
break;
case MATTYPE_SPECULAR:
{
shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
}
break;
default:
llassert(false);
break;
}
break;
case MATTYPE_SPECULAR:
{
LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU");
LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV");
shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
}
break;
default:
llassert(false);
break;
}
// vertical scale and repeats per meter depends on each other, so force set on changes
self->updateUI(true);

View File

@ -162,7 +162,12 @@ protected:
// Callback funcs for individual controls
//
static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata);
static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata);
static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata);
static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata);
static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata);
static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata);
@ -170,6 +175,12 @@ protected:
static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata);
static void syncRepeatX(LLPanelFace* self, F32 scaleU);
static void syncRepeatY(LLPanelFace* self, F32 scaleV);
static void syncOffsetX(LLPanelFace* self, F32 offsetU);
static void syncOffsetY(LLPanelFace* self, F32 offsetV);
static void syncMaterialRot(LLPanelFace* self, F32 rot);
static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata);

View File

@ -1158,6 +1158,26 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
mFilterEditor->setText(item_name);
mFilterEditor->setFocus(TRUE);
}
if (command_name == "replace_links")
{
LLSD params;
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (current_item)
{
LLInvFVBridge* bridge = (LLInvFVBridge*)current_item->getViewModelItem();
if (bridge)
{
LLInventoryObject* obj = bridge->getInventoryObject();
if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER)
{
params = LLSD(obj->getUUID());
}
}
}
LLFloaterReg::showInstance("linkreplace", params);
}
}
void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )

View File

@ -2052,7 +2052,9 @@ BOOL LLPanelObjectInventory::handleKeyHere( KEY key, MASK mask )
switch (key)
{
case KEY_DELETE:
#if LL_DARWIN
case KEY_BACKSPACE:
#endif
// Delete selected items if delete or backspace key hit on the inventory panel
// Note: on Mac laptop keyboards, backspace and delete are one and the same
if (isSelectionRemovable() && mask == MASK_NONE)

View File

@ -1465,7 +1465,17 @@ void LLPanelPeople::onOpen(const LLSD& key)
{
std::string tab_name = key["people_panel_tab_name"];
if (!tab_name.empty())
{
mTabContainer->selectTabByName(tab_name);
if(tab_name == BLOCKED_TAB_NAME)
{
LLPanel* blocked_tab = mTabContainer->getCurrentPanel()->findChild<LLPanel>("panel_block_list_sidetray");
if(blocked_tab)
{
blocked_tab->onOpen(key);
}
}
}
}
bool LLPanelPeople::notifyChildren(const LLSD& info)

View File

@ -56,15 +56,20 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llavataractions.h"
#include "llavatariconctrl.h"
#include "llnamebox.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
#include "llspinctrl.h"
#include "roles_constants.h"
#include "llgroupactions.h"
#include "llgroupiconctrl.h"
#include "lltrans.h"
#include "llinventorymodel.h"
#include "llavatarnamecache.h"
#include "llcachename.h"
U8 string_value_to_click_action(std::string p_value);
std::string click_action_to_string_value( U8 action);
@ -186,10 +191,13 @@ void LLPanelPermissions::disableAll()
getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLStringUtil::null);
getChildView("Creator:")->setEnabled(FALSE);
getChild<LLUICtrl>("Creator Icon")->setVisible(FALSE);
getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null);
getChildView("Creator Name")->setEnabled(FALSE);
getChildView("Owner:")->setEnabled(FALSE);
getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE);
getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE);
getChild<LLUICtrl>("Owner Name")->setValue(LLStringUtil::null);
getChildView("Owner Name")->setEnabled(FALSE);
@ -366,39 +374,87 @@ void LLPanelPermissions::refresh()
// Update creator text field
getChildView("Creator:")->setEnabled(TRUE);
std::string creator_name;
LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
std::string creator_app_link;
LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_app_link);
getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
// Style for creator and owner links (both group and agent)
LLStyle::Params style_params;
LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.color = link_color;
style_params.readonly_color = link_color;
style_params.is_link = true; // link will be added later
const LLFontGL* fontp = getChild<LLTextBox>("Creator Name")->getFont();
style_params.font.name = LLFontGL::nameFromFont(fontp);
style_params.font.size = LLFontGL::sizeFromFont(fontp);
style_params.font.style = "UNDERLINE";
LLAvatarName av_name;
if (LLAvatarNameCache::get(mCreatorID, &av_name))
{
// If name isn't present, this will 'request' it and trigger refresh() again
LLTextBox* text_box = getChild<LLTextBox>("Creator Name");
style_params.link_href = creator_app_link;
text_box->setText(av_name.getCompleteName(), style_params);
}
getChild<LLAvatarIconCtrl>("Creator Icon")->setValue(mCreatorID);
getChild<LLAvatarIconCtrl>("Creator Icon")->setVisible(TRUE);
getChildView("Creator Name")->setEnabled(TRUE);
// Update owner text field
getChildView("Owner:")->setEnabled(TRUE);
std::string owner_name;
const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name);
if (mOwnerID.isNull())
std::string owner_app_link;
const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_app_link);
if (LLSelectMgr::getInstance()->selectIsGroupOwned())
{
if (LLSelectMgr::getInstance()->selectIsGroupOwned())
// Group owned already displayed by selectGetOwner
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mOwnerID);
if (group_data && group_data->isGroupPropertiesDataComplete())
{
// Group owned already displayed by selectGetOwner
LLTextBox* text_box = getChild<LLTextBox>("Owner Name");
style_params.link_href = owner_app_link;
text_box->setText(group_data->mName, style_params);
getChild<LLGroupIconCtrl>("Owner Group Icon")->setIconId(group_data->mInsigniaID);
getChild<LLGroupIconCtrl>("Owner Group Icon")->setVisible(TRUE);
getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE);
}
else
{
// Triggers refresh
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mOwnerID);
}
}
else
{
LLUUID owner_id = mOwnerID;
if (owner_id.isNull())
{
// Display last owner if public
std::string last_owner_name;
LLSelectMgr::getInstance()->selectGetLastOwner(mLastOwnerID, last_owner_name);
std::string last_owner_app_link;
LLSelectMgr::getInstance()->selectGetLastOwner(mLastOwnerID, last_owner_app_link);
// It should never happen that the last owner is null and the owner
// is null, but it seems to be a bug in the simulator right now. JC
if (!mLastOwnerID.isNull() && !last_owner_name.empty())
if (!mLastOwnerID.isNull() && !last_owner_app_link.empty())
{
owner_name.append(", last ");
owner_name.append(last_owner_name);
owner_app_link.append(", last ");
owner_app_link.append(last_owner_app_link);
}
owner_id = mLastOwnerID;
}
if (LLAvatarNameCache::get(owner_id, &av_name))
{
// If name isn't present, this will 'request' it and trigger refresh() again
LLTextBox* text_box = getChild<LLTextBox>("Owner Name");
style_params.link_href = owner_app_link;
text_box->setText(av_name.getCompleteName(), style_params);
}
getChild<LLAvatarIconCtrl>("Owner Icon")->setValue(owner_id);
getChild<LLAvatarIconCtrl>("Owner Icon")->setVisible(TRUE);
getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE);
}
getChild<LLUICtrl>("Owner Name")->setValue(owner_name);
getChildView("Owner Name")->setEnabled(TRUE);
// update group text field

View File

@ -40,6 +40,7 @@
#include "lltoastnotifypanel.h"
#include "lltoastscripttextbox.h"
#include "lltrans.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
#include "llfloaterimsession.h"
@ -61,6 +62,7 @@ LLUUID notification_id_to_object_id(const LLUUID& notification_id)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLScriptFloater::LLScriptFloater(const LLSD& key)
: LLDockableFloater(NULL, true, key)
, mScriptForm(NULL)
@ -346,6 +348,11 @@ void LLScriptFloater::hideToastsIfNeeded()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLScriptFloaterManager::LLScriptFloaterManager()
{
gSavedSettings.getControl("ScriptDialogLimitations")->getCommitSignal()->connect(boost::bind(&clearScriptNotifications));
}
void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
{
if(notification_id.isNull())
@ -365,16 +372,86 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
// LLDialog can spawn only one instance, LLLoadURL and LLGiveInventory can spawn unlimited number of instances
if(OBJ_SCRIPT == obj_type)
{
// If an Object spawns more-than-one floater, only the newest one is shown.
// The previous is automatically closed.
script_notification_map_t::const_iterator it = findUsingObjectId(object_id);
static LLCachedControl<U32> script_dialog_limitations(gSavedSettings, "ScriptDialogLimitations", 0);
script_notification_map_t::const_iterator it = mNotifications.end();
switch (script_dialog_limitations)
{
case SCRIPT_PER_CHANNEL:
{
// If an Object spawns more-than-one floater per channel, only the newest one is shown.
// The previous is automatically closed.
LLNotificationPtr notification = LLNotifications::instance().find(notification_id);
if (notification)
{
it = findUsingObjectIdAndChannel(object_id, notification->getPayload()["chat_channel"].asInteger());
}
break;
}
case SCRIPT_ATTACHMENT_PER_CHANNEL:
{
LLViewerObject* objectp = gObjectList.findObject(object_id);
if (objectp && objectp->getAttachmentItemID().notNull()) //in user inventory
{
LLNotificationPtr notification = LLNotifications::instance().find(notification_id);
if (notification)
{
it = findUsingObjectIdAndChannel(object_id, notification->getPayload()["chat_channel"].asInteger());
}
}
else
{
it = findUsingObjectId(object_id);
}
break;
}
case SCRIPT_HUD_PER_CHANNEL:
{
LLViewerObject* objectp = gObjectList.findObject(object_id);
if (objectp && objectp->isHUDAttachment())
{
LLNotificationPtr notification = LLNotifications::instance().find(notification_id);
if (notification)
{
it = findUsingObjectIdAndChannel(object_id, notification->getPayload()["chat_channel"].asInteger());
}
}
else
{
it = findUsingObjectId(object_id);
}
break;
}
case SCRIPT_HUD_UNCONSTRAINED:
{
LLViewerObject* objectp = gObjectList.findObject(object_id);
if (objectp && objectp->isHUDAttachment())
{
// don't remove existing floaters
break;
}
else
{
it = findUsingObjectId(object_id);
}
break;
}
case SCRIPT_PER_OBJECT:
default:
{
// If an Object spawns more-than-one floater, only the newest one is shown.
// The previous is automatically closed.
it = findUsingObjectId(object_id);
break;
}
}
if(it != mNotifications.end())
{
LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
if (NULL != chiclet_panelp)
{
LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first);
if(NULL != chicletp)
if (NULL != chicletp)
{
// Pass the new_message icon state further.
set_new_message = chicletp->getShowNewMessagesIcon();
@ -383,7 +460,7 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
}
LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first);
if(floater)
if (floater)
{
// Generate chiclet with a "new message" indicator if a docked window was opened but not in focus. See EXT-3142.
set_new_message |= !floater->hasFocus();
@ -579,6 +656,23 @@ LLScriptFloaterManager::script_notification_map_t::const_iterator LLScriptFloate
return mNotifications.end();
}
LLScriptFloaterManager::script_notification_map_t::const_iterator LLScriptFloaterManager::findUsingObjectIdAndChannel(const LLUUID& object_id, S32 im_channel)
{
script_notification_map_t::const_iterator it = mNotifications.begin();
for (; mNotifications.end() != it; ++it)
{
if (object_id == it->second)
{
LLNotificationPtr notification = LLNotifications::instance().find(it->first);
if (notification && (im_channel == notification->getPayload()["chat_channel"].asInteger()))
{
return it;
}
}
}
return mNotifications.end();
}
void LLScriptFloaterManager::saveFloaterPosition(const LLUUID& object_id, const FloaterPositionInfo& fpi)
{
if(object_id.notNull())
@ -612,6 +706,33 @@ void LLScriptFloaterManager::setFloaterVisible(const LLUUID& notification_id, bo
}
}
//static
void LLScriptFloaterManager::clearScriptNotifications()
{
LLScriptFloaterManager* inst = LLScriptFloaterManager::getInstance();
static const object_type_map TYPE_MAP = initObjectTypeMap();
script_notification_map_t::const_iterator ntf_it = inst->mNotifications.begin();
while (inst->mNotifications.end() != ntf_it)
{
LLUUID notification_id = ntf_it->first;
ntf_it++; // onRemoveNotification() erases notification
LLNotificationPtr notification = LLNotifications::instance().find(notification_id);
if (notification)
{
object_type_map::const_iterator map_it = TYPE_MAP.find(notification->getName());
if (map_it != TYPE_MAP.end() && map_it->second == OBJ_SCRIPT)
{
if (notification != NULL && !notification->isCancelled())
{
LLNotificationsUtil::cancel(notification);
}
inst->onRemoveNotification(notification_id);
}
}
}
}
//////////////////////////////////////////////////////////////////
bool LLScriptFloater::isScriptTextbox(LLNotificationPtr notification)

View File

@ -41,7 +41,7 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
// *TODO
// LLScriptFloaterManager and LLScriptFloater will need some refactoring after we
// know how script notifications should look like.
LLSINGLETON_EMPTY_CTOR(LLScriptFloaterManager);
LLSINGLETON(LLScriptFloaterManager);
public:
typedef enum e_object_type
@ -53,6 +53,15 @@ public:
OBJ_UNKNOWN
}EObjectType;
typedef enum e_limitation_type
{
SCRIPT_PER_OBJECT = 0,
SCRIPT_PER_CHANNEL = 1,
SCRIPT_ATTACHMENT_PER_CHANNEL,
SCRIPT_HUD_PER_CHANNEL,
SCRIPT_HUD_UNCONSTRAINED
}ELimitationType;
/**
* Handles new notifications.
* Saves notification and object ids, removes old notification if needed, creates script chiclet
@ -104,6 +113,11 @@ public:
protected:
/**
* Removes all script-dialog notifications
*/
static void clearScriptNotifications();
typedef std::map<std::string, EObjectType> object_type_map;
static object_type_map initObjectTypeMap();
@ -112,6 +126,7 @@ protected:
typedef std::map<LLUUID, LLUUID> script_notification_map_t;
script_notification_map_t::const_iterator findUsingObjectId(const LLUUID& object_id);
script_notification_map_t::const_iterator findUsingObjectIdAndChannel(const LLUUID& object_id, S32 im_channel);
private:

View File

@ -815,40 +815,49 @@ void LLSidepanelItemInfo::onCommitPermissions()
//LL_INFOS() << "LLSidepanelItemInfo::onCommitPermissions()" << LL_ENDL;
LLViewerInventoryItem* item = findItem();
if(!item) return;
LLPermissions perm(item->getPermissions());
BOOL is_group_owned;
LLUUID owner_id;
LLUUID group_id;
LLPermissions perm(item->getPermissions());
perm.getOwnership(owner_id, is_group_owned);
if (is_group_owned && gAgent.hasPowerInGroup(owner_id, GP_OBJECT_MANIPULATE))
{
group_id = owner_id;
}
LLCheckBoxCtrl* CheckShareWithGroup = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
if(CheckShareWithGroup)
{
perm.setGroupBits(gAgent.getID(), gAgent.getGroupID(),
perm.setGroupBits(gAgent.getID(), group_id,
CheckShareWithGroup->get(),
PERM_MODIFY | PERM_MOVE | PERM_COPY);
}
LLCheckBoxCtrl* CheckEveryoneCopy = getChild<LLCheckBoxCtrl>("CheckEveryoneCopy");
if(CheckEveryoneCopy)
{
perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(),
perm.setEveryoneBits(gAgent.getID(), group_id,
CheckEveryoneCopy->get(), PERM_COPY);
}
LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
if(CheckNextOwnerModify)
{
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
perm.setNextOwnerBits(gAgent.getID(), group_id,
CheckNextOwnerModify->get(), PERM_MODIFY);
}
LLCheckBoxCtrl* CheckNextOwnerCopy = getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy");
if(CheckNextOwnerCopy)
{
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
perm.setNextOwnerBits(gAgent.getID(), group_id,
CheckNextOwnerCopy->get(), PERM_COPY);
}
LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer");
if(CheckNextOwnerTransfer)
{
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
perm.setNextOwnerBits(gAgent.getID(), group_id,
CheckNextOwnerTransfer->get(), PERM_TRANSFER);
}
if(perm != item->getPermissions()

View File

@ -51,6 +51,7 @@
#include "llvosky.h"
#include "llcubemap.h"
#include "llviewercontrol.h"
#include "llenvmanager.h"
#include "llvowlsky.h"

View File

@ -1461,6 +1461,7 @@ bool idle_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLEnvManagerNew::getInstance()->usePrefs(); // Load all presets and settings
gSky.init(initial_sun_direction);
LLGLState::checkStates();

View File

@ -53,6 +53,8 @@
void dialog_refresh_all();
static const U32 LL_ASSET_UPLOAD_TIMEOUT_SEC = 60;
LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId,
LLAssetType::EType assetType, std::string name, std::string description,
S32 compressionInfo, LLFolderType::EType destinationType,
@ -678,6 +680,8 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
const LLUUID &id, std::string url, LLResourceUploadInfo::ptr_t uploadInfo)
{
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions);
httpOptions->setTimeout(LL_ASSET_UPLOAD_TIMEOUT_SEC);
LLSD result = uploadInfo->prepareUpload();
uploadInfo->logPreparedUpload();
@ -699,7 +703,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
LLSD body = uploadInfo->generatePostBody();
result = httpAdapter->postAndSuspend(httpRequest, url, body);
result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOptions);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@ -717,7 +721,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
bool success = false;
if (!uploader.empty() && uploadInfo->getAssetId().notNull())
{
result = httpAdapter->postFileAndSuspend(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType());
result = httpAdapter->postFileAndSuspend(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType(), httpOptions);
httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@ -811,14 +815,19 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
}
else
{
if (status.getType() == 499)
switch (status.getType())
{
reason = "The server is experiencing unexpected difficulties.";
}
else
{
reason = "Error in upload request. Please visit "
"http://secondlife.com/support for help fixing this problem.";
case 404:
reason = LLTrans::getString("AssetUploadServerUnreacheble");
break;
case 499:
reason = LLTrans::getString("AssetUploadServerDifficulties");
break;
case 503:
reason = LLTrans::getString("AssetUploadServerUnavaliable");
break;
default:
reason = LLTrans::getString("AssetUploadRequestInvalid");
}
}

View File

@ -83,6 +83,7 @@
#include "llfloaterlagmeter.h"
#include "llfloaterland.h"
#include "llfloaterlandholdings.h"
#include "llfloaterlinkreplace.h"
#include "llfloaterloadprefpreset.h"
#include "llfloatermap.h"
#include "llfloatermarketplacelistings.h"
@ -103,6 +104,7 @@
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
#include "llfloaterpreference.h"
#include "llfloaterpreviewtrash.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
@ -257,6 +259,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
LLFloaterReg::add("linkreplace", "floater_linkreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLinkReplace>);
LLFloaterReg::add("load_pref_preset", "floater_load_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLoadPrefPreset>);
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
@ -307,6 +310,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("preview_scriptedit", "floater_live_lsleditor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLLiveLSLEditor>, "preview");
LLFloaterReg::add("preview_sound", "floater_preview_sound.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewSound>, "preview");
LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview");
LLFloaterReg::add("preview_trash", "floater_preview_trash.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreviewTrash>);
LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>);
LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>);

View File

@ -6042,7 +6042,14 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
return LLMarketplaceData::instance().getListing(llsdBlock["listing_id"].asInteger());
}
}
// Error Notification can come with and without reason
if (notificationID == "JoinGroupError" && llsdBlock.has("reason"))
{
LLNotificationsUtil::add("JoinGroupErrorReason", llsdBlock);
return true;
}
LLNotificationsUtil::add(notificationID, llsdBlock);
return true;
}

View File

@ -6274,6 +6274,24 @@ BOOL LLViewerObject::isTempAttachment() const
return (mID.notNull() && (mID == mAttachmentItemID));
}
BOOL LLViewerObject::isHiglightedOrBeacon() const
{
if (LLFloaterReg::instanceVisible("beacons") && (gPipeline.getRenderBeacons() || gPipeline.getRenderHighlights()))
{
BOOL has_media = (getMediaType() == LLViewerObject::MEDIA_SET);
BOOL is_scripted = !isAvatar() && !getParent() && flagScripted();
BOOL is_physical = !isAvatar() && flagUsePhysics();
return (isParticleSource() && gPipeline.getRenderParticleBeacons())
|| (isAudioSource() && gPipeline.getRenderSoundBeacons())
|| (has_media && gPipeline.getRenderMOAPBeacons())
|| (is_scripted && gPipeline.getRenderScriptedBeacons())
|| (is_scripted && flagHandleTouch() && gPipeline.getRenderScriptedTouchBeacons())
|| (is_physical && gPipeline.getRenderPhysicalBeacons());
}
return FALSE;
}
const LLUUID &LLViewerObject::getAttachmentItemID() const
{

View File

@ -178,6 +178,8 @@ public:
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;
virtual BOOL isHiglightedOrBeacon() const;
virtual void updateRadius() {};
virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()
@ -388,7 +390,7 @@ public:
// Create if necessary
LLAudioSource *getAudioSource(const LLUUID& owner_id);
bool isAudioSource() {return mAudioSourcep != NULL;}
BOOL isAudioSource() const {return mAudioSourcep != NULL;}
U8 getMediaType() const;
void setMediaType(U8 media_type);

View File

@ -1427,122 +1427,128 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
// static
void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user)
{
S32 request_result;
S32 sequence_id;
BOOL snap_selection = FALSE;
S32 self_count = 0;
S32 other_count = 0;
S32 public_count = 0;
S32 local_id;
LLUUID owner_id;
BOOL is_group_owned;
U32 auction_id = 0;
S32 claim_price_per_meter = 0;
S32 rent_price_per_meter = 0;
S32 claim_date = 0;
LLVector3 aabb_min;
LLVector3 aabb_max;
S32 area = 0;
S32 sw_max_prims = 0;
S32 sw_total_prims = 0;
//LLUUID buyer_id;
U8 status = 0;
S32 max_prims = 0;
S32 total_prims = 0;
S32 owner_prims = 0;
S32 group_prims = 0;
S32 other_prims = 0;
S32 selected_prims = 0;
F32 parcel_prim_bonus = 1.f;
BOOL region_push_override = false;
BOOL region_deny_anonymous_override = false;
BOOL region_deny_identified_override = false; // Deprecated
BOOL region_deny_transacted_override = false; // Deprecated
BOOL region_deny_age_unverified_override = false;
S32 request_result;
S32 sequence_id;
BOOL snap_selection = FALSE;
S32 self_count = 0;
S32 other_count = 0;
S32 public_count = 0;
S32 local_id;
LLUUID owner_id;
BOOL is_group_owned;
U32 auction_id = 0;
S32 claim_price_per_meter = 0;
S32 rent_price_per_meter = 0;
S32 claim_date = 0;
LLVector3 aabb_min;
LLVector3 aabb_max;
S32 area = 0;
S32 sw_max_prims = 0;
S32 sw_total_prims = 0;
//LLUUID buyer_id;
U8 status = 0;
S32 max_prims = 0;
S32 total_prims = 0;
S32 owner_prims = 0;
S32 group_prims = 0;
S32 other_prims = 0;
S32 selected_prims = 0;
F32 parcel_prim_bonus = 1.f;
BOOL region_push_override = false;
BOOL region_deny_anonymous_override = false;
BOOL region_deny_identified_override = false; // Deprecated
BOOL region_deny_transacted_override = false; // Deprecated
BOOL region_deny_age_unverified_override = false;
BOOL region_allow_access_override = true;
BOOL agent_parcel_update = false; // updating previous(existing) agent parcel
S32 other_clean_time = 0;
S32 other_clean_time = 0;
LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance();
LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance();
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id);
if (request_result == PARCEL_RESULT_NO_DATA)
{
// no valid parcel data
LL_INFOS() << "no valid parcel data" << LL_ENDL;
return;
}
if (request_result == PARCEL_RESULT_NO_DATA)
{
// no valid parcel data
LL_INFOS() << "no valid parcel data" << LL_ENDL;
return;
}
// Decide where the data will go.
LLParcel* parcel = NULL;
if (sequence_id == SELECTED_PARCEL_SEQ_ID)
{
// ...selected parcels report this sequence id
parcel_mgr.mRequestResult = PARCEL_RESULT_SUCCESS;
parcel = parcel_mgr.mCurrentParcel;
}
else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
{
parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
parcel = parcel_mgr.mHoverParcel;
}
else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
{
parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
parcel = parcel_mgr.mCollisionParcel;
}
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
else
{
LL_INFOS() << "out of order agent parcel sequence id " << sequence_id
<< " last good " << parcel_mgr.mAgentParcelSequenceID
<< LL_ENDL;
return;
}
// Decide where the data will go.
LLParcel* parcel = NULL;
if (sequence_id == SELECTED_PARCEL_SEQ_ID)
{
// ...selected parcels report this sequence id
parcel_mgr.mRequestResult = PARCEL_RESULT_SUCCESS;
parcel = parcel_mgr.mCurrentParcel;
}
else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
{
parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
parcel = parcel_mgr.mHoverParcel;
}
else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
{
parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
parcel = parcel_mgr.mCollisionParcel;
}
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
else
{
LL_INFOS() << "out of order agent parcel sequence id " << sequence_id
<< " last good " << parcel_mgr.mAgentParcelSequenceID
<< LL_ENDL;
return;
}
msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_LocalID, local_id );
msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID, owner_id);
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimDate, claim_date);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimPrice, claim_price_per_meter);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_RentPrice, rent_price_per_meter);
msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_Area, area );
//msg->getUUIDFast( _PREHASH_ParcelData, _PREHASH_BuyerID, buyer_id);
msg->getU8("ParcelData", "Status", status);
msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims );
msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims );
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims );
msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus );
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override );
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override );
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override ); // Deprecated
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override ); // Deprecated
if (msg->getNumberOfBlocksFast(_PREHASH_AgeVerificationBlock))
{
// this block was added later and may not be on older sims, so we have to test its existence first
msg->getBOOLFast(_PREHASH_AgeVerificationBlock, _PREHASH_RegionDenyAgeUnverified, region_deny_age_unverified_override );
}
msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_LocalID, local_id);
msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID, owner_id);
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_ClaimDate, claim_date);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_ClaimPrice, claim_price_per_meter);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RentPrice, rent_price_per_meter);
msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_Area, area);
//msg->getUUIDFast( _PREHASH_ParcelData, _PREHASH_BuyerID, buyer_id);
msg->getU8("ParcelData", "Status", status);
msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims);
msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims);
msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims);
msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus);
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override);
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override);
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override); // Deprecated
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override); // Deprecated
if (msg->getNumberOfBlocksFast(_PREHASH_AgeVerificationBlock))
{
// this block was added later and may not be on older sims, so we have to test its existence first
msg->getBOOLFast(_PREHASH_AgeVerificationBlock, _PREHASH_RegionDenyAgeUnverified, region_deny_age_unverified_override);
}
if (msg->getNumberOfBlocks(_PREHASH_RegionAllowAccessBlock))
{
msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
}
msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
@ -1585,6 +1591,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setRegionPushOverride(region_push_override);
parcel->setRegionDenyAnonymousOverride(region_deny_anonymous_override);
parcel->setRegionDenyAgeUnverifiedOverride(region_deny_age_unverified_override);
parcel->setRegionAllowAccessOverride(region_allow_access_override);
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)

View File

@ -176,7 +176,7 @@ public:
mToolTip = inv_item->getName() + '\n' + inv_item->getDescription();
}
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
if (num_chars == 0)
{
@ -185,7 +185,7 @@ public:
}
else
{
width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str());
width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidthF32(mLabel.c_str());
height = llmax(mImage->getHeight(), mStyle->getFont()->getLineHeight());
}
return false;

View File

@ -119,7 +119,7 @@ const F32 MAX_HOVER_Z = 2.0;
const F32 MIN_HOVER_Z = -2.0;
const F32 MIN_ATTACHMENT_COMPLEXITY = 0.f;
const F32 MAX_ATTACHMENT_COMPLEXITY = 1.0e6f;
const F32 DEFAULT_MAX_ATTACHMENT_COMPLEXITY = 1.0e6f;
using namespace LLAvatarAppearanceDefines;
@ -9018,6 +9018,9 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
* the official viewer for consideration.
*****************************************************************/
static const U32 COMPLEXITY_BODY_PART_COST = 200;
static LLCachedControl<F32> max_complexity_setting(gSavedSettings,"MaxAttachmentComplexity");
F32 max_attachment_complexity = max_complexity_setting;
max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
// Diagnostic list of all textures on our avatar
static std::set<LLUUID> all_textures;
@ -9099,7 +9102,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
<< " children: " << attachment_children_cost
<< LL_ENDL;
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, MAX_ATTACHMENT_COMPLEXITY);
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
}
}
}

View File

@ -3977,7 +3977,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
start_face = face;
end_face = face+1;
}
pick_transparent |= isHiglightedOrBeacon();
bool special_cursor = specialHoverCursor();
for (S32 i = start_face; i < end_face; ++i)
{

View File

@ -427,7 +427,6 @@ void LLWaterParamManager::initSingleton()
{
LL_DEBUGS("Windlight") << "Initializing water" << LL_ENDL;
loadAllPresets();
LLEnvManagerNew::instance().usePrefs();
}
// static

View File

@ -50,8 +50,6 @@
#include "llagent.h"
#include "llviewerregion.h"
#include "lldaycyclemanager.h"
#include "llenvmanager.h"
#include "llwlparamset.h"
#include "llpostprocess.h"
@ -252,13 +250,13 @@ void LLWLParamManager::addAllSkies(const LLWLParamKey::EScope scope, const LLSD&
}
}
void LLWLParamManager::refreshRegionPresets()
void LLWLParamManager::refreshRegionPresets(const LLSD& region_sky_presets)
{
// Remove all region sky presets because they may belong to a previously visited region.
clearParamSetsOfScope(LLEnvKey::SCOPE_REGION);
// Add all sky presets belonging to the current region.
addAllSkies(LLEnvKey::SCOPE_REGION, LLEnvManagerNew::instance().getRegionSettings().getSkyMap());
addAllSkies(LLEnvKey::SCOPE_REGION, region_sky_presets);
}
void LLWLParamManager::loadAllPresets()
@ -487,6 +485,11 @@ bool LLWLParamManager::applyDayCycleParams(const LLSD& params, LLEnvKey::EScope
return true;
}
void LLWLParamManager::setDefaultDay()
{
mDay.loadDayCycleFromFile("Default.xml");
}
bool LLWLParamManager::applySkyParams(const LLSD& params)
{
mAnimator.deactivate();
@ -494,6 +497,12 @@ bool LLWLParamManager::applySkyParams(const LLSD& params)
return true;
}
void LLWLParamManager::setDefaultSky()
{
getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams);
}
void LLWLParamManager::resetAnimator(F32 curTime, bool run)
{
mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate,
@ -672,34 +681,8 @@ void LLWLParamManager::initSingleton()
loadAllPresets();
// load the day
std::string preferred_day = LLEnvManagerNew::instance().getDayCycleName();
if (!LLDayCycleManager::instance().getPreset(preferred_day, mDay))
{
// Fall back to default.
LL_WARNS() << "No day cycle named " << preferred_day << ", falling back to defaults" << LL_ENDL;
mDay.loadDayCycleFromFile("Default.xml");
// *TODO: Fix user preferences accordingly.
}
// *HACK - sets cloud scrolling to what we want... fix this better in the future
std::string sky = LLEnvManagerNew::instance().getSkyPresetName();
if (!getParamSet(LLWLParamKey(sky, LLWLParamKey::SCOPE_LOCAL), mCurParams))
{
LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL;
getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams);
// *TODO: Fix user preferences accordingly.
}
// set it to noon
resetAnimator(0.5, LLEnvManagerNew::instance().getUseDayCycle());
// but use linden time sets it to what the estate is
mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN);
LLEnvManagerNew::instance().usePrefs();
}
// static

View File

@ -29,7 +29,6 @@
#include <list>
#include <map>
#include "llenvmanager.h"
#include "llwlparamset.h"
#include "llwlanimator.h"
#include "llwldaycycle.h"
@ -146,9 +145,14 @@ public:
/// apply specified day cycle, setting time to noon by default
bool applyDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time = 0.5);
/// Apply Default.xml map
void setDefaultDay();
/// apply specified fixed sky params
bool applySkyParams(const LLSD& params);
void setDefaultSky();
// get where the light is pointing
inline LLVector4 getLightDir(void) const;
@ -208,7 +212,7 @@ public:
void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map);
/// refresh region-scope presets
void refreshRegionPresets();
void refreshRegionPresets(const LLSD& region_sky_presets);
// returns all skies referenced by the current day cycle (in mDay), with their final names
// side effect: applies changes to all internal structures! (trashes all unreferenced skies in scope, keys in day cycle rescoped to scope, etc.)

View File

@ -449,7 +449,7 @@ Nur große Parzellen können in der Suche aufgeführt werden.
<spinner label="Online-Zeit:" name="HoursSpin"/>
<panel name="Allowed_layout_panel">
<text label="Immer erlauben" name="AllowedText">
Zulässige Einwohner ([COUNT])
Zulässige Einwohner ([COUNT], max. [MAX])
</text>
<name_list name="AccessList" tool_tip="([LISTED] aufgeführt, [MAX] max)"/>
<button label="Hinzufügen" name="add_allowed"/>
@ -457,7 +457,7 @@ Nur große Parzellen können in der Suche aufgeführt werden.
</panel>
<panel name="Banned_layout_panel">
<text label="Verbannen" name="BanCheck">
Verbannte Einwohner ([COUNT])
Verbannte Einwohner ([COUNT], max. [MAX])
</text>
<name_list name="BannedList" tool_tip="([LISTED] aufgeführt, [MAX] max)"/>
<button label="Hinzufügen" name="add_banned"/>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_avatar_render_settings" title="EINSTELLUNGEN ZUR DARSTELLUNG VON AVATAREN">
<string name="av_never_render" value="Nie"/>
<string name="av_always_render" value="Immer"/>
<filter_editor label="Nach Personen filtern" name="people_filter_input"/>
<menu_button name="plus_btn" tool_tip="Aktionen für ausgewählte Person"/>
<name_list name="render_settings_list">
<name_list.columns label="Name" name="name"/>
<name_list.columns label="Darstellungseinstellung" name="setting"/>
</name_list>
</floater>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_flickr" title="AUF FLICKR HOCHLADEN">
<floater name="floater_flickr" title="AUF FLICKR TEILEN">
<panel name="background">
<tab_container name="tabs">
<panel label="FOTO" name="panel_flickr_photo"/>

View File

@ -13,5 +13,6 @@
<panel label="Privatsphäre" name="im"/>
<panel label="Konfiguration" name="input"/>
<panel label="Erweitert" name="advanced1"/>
<panel label="Uploads" name="uploads"/>
</tab_container>
</floater>

View File

@ -13,6 +13,6 @@
Lesen Sie die folgenden Servicebedingungen und Datenbestimmungen sorgfältig durch. Sie müssen den Servicebedingungen zustimmen, um sich bei [SECOND_LIFE] anmelden zu können.
</text>
<text name="external_tos_required">
Sie müssen sich auf my.secondlife.com anmelden und die Servicebedingungen akzeptieren, bevor Sie fortfahren können. Vielen Dank!
Sie müssen sich unter https://my.secondlife.com anmelden und die Servicebedingungen akzeptieren, bevor Sie fortfahren können. Vielen Dank!
</text>
</floater>

View File

@ -17,8 +17,10 @@
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
<menu_item_call label="Bezahlen" name="Pay..."/>
<menu_item_call label="Objektprofil" name="Object Inspect"/>
<menu_item_check label="Normal darstellen" name="RenderNormally"/>
<menu_item_check label="Nicht darstellen" name="DoNotRender"/>
<menu_item_check label="Komplett darstellen" name="AlwaysRenderFully"/>
<context_menu label="Avatar darstellen" name="Render Avatar">
<menu_item_check label="Standard" name="RenderNormally"/>
<menu_item_check label="Immer" name="AlwaysRenderFully"/>
<menu_item_check label="Nie" name="DoNotRender"/>
</context_menu>
<menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>

View File

@ -16,8 +16,10 @@
<menu_item_call label="XML ausgeben" name="Dump XML"/>
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
<menu_item_call label="Bezahlen" name="Pay..."/>
<menu_item_check label="Normal darstellen" name="RenderNormally"/>
<menu_item_check label="Nicht darstellen" name="DoNotRender"/>
<menu_item_check label="Komplett darstellen" name="AlwaysRenderFully"/>
<context_menu label="Avatar darstellen" name="Render Avatar">
<menu_item_check label="Standard" name="RenderNormally"/>
<menu_item_check label="Immer" name="AlwaysRenderFully"/>
<menu_item_check label="Nie" name="DoNotRender"/>
</context_menu>
<menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Settings">
<menu_item_check label="Standard" name="default"/>
<menu_item_check label="Immer darstellen" name="always_render"/>
<menu_item_check label="Nie darstellen" name="never_render"/>
</context_menu>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="menu_settings_add.xml">
<menu_item_call label="Einwohner immer darstellen..." name="add_avatar_always_render"/>
<menu_item_call label="Einwohner nie darstellen..." name="add_avatar_never_render"/>
</toggleable_menu>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="menu_gesture_gear">
<menu_item_call label="Zu Favoriten hinzufügen/daraus entfernen" name="activate"/>
<menu_item_call label="Ausgewählte Geste aktivieren/deaktivieren" name="activate"/>
<menu_item_call label="Kopieren" name="copy_gesture"/>
<menu_item_call label="Einfügen" name="paste"/>
<menu_item_call label="UUID kopieren" name="copy_uuid"/>

View File

@ -42,6 +42,12 @@
<menu_item_call label="Neues Haar" name="New Hair"/>
<menu_item_call label="Neue Augen" name="New Eyes"/>
</menu>
<menu label="Als Standard verwenden für" name="upload_def">
<menu_item_call label="Hochgeladene Bilder" name="Image uploads"/>
<menu_item_call label="Hochgeladene Sounds" name="Sound uploads"/>
<menu_item_call label="Hochgeladene Animationen" name="Animation uploads"/>
<menu_item_call label="Hochgeladene Modelle" name="Model uploads"/>
</menu>
<menu label="Typ ändern" name="Change Type">
<menu_item_call label="Standard" name="Default"/>
<menu_item_call label="Handschuhe" name="Gloves"/>
@ -60,6 +66,7 @@
<menu_item_call label="Aktuelles Outfit ersetzen" name="Replace Outfit"/>
<menu_item_call label="Zum aktuellen Outfit hinzufügen" name="Add To Outfit"/>
<menu_item_call label="Vom aktuellen Outfit entfernen" name="Remove From Outfit"/>
<menu_item_call label="Outfitliste in Zwischenablage kopieren" name="Copy outfit list to clipboard"/>
<menu_item_call label="Original suchen" name="Find Original"/>
<menu_item_call label="Objekt löschen" name="Purge Item"/>
<menu_item_call label="Objekt wiederherstellen" name="Restore Item"/>
@ -72,7 +79,6 @@
<menu_item_call label="Kopieren" name="Copy"/>
<menu_item_call label="Einfügen" name="Paste"/>
<menu_item_call label="Als Link einfügen" name="Paste As Link"/>
<menu_item_call label="Löschen" name="Remove Link"/>
<menu_item_call label="Löschen" name="Delete"/>
<menu_item_call label="Systemordner löschen" name="Delete System Folder"/>
<menu_item_call label="Konferenz-Chat starten" name="Conference Chat Folder"/>
@ -95,7 +101,6 @@
<menu_item_call label="Bearbeiten" name="Wearable Edit"/>
<menu_item_call label="Hinzufügen" name="Wearable Add"/>
<menu_item_call label="Ausziehen" name="Take Off"/>
<menu_item_call label="In Händler-Outbox kopieren" name="Merchant Copy"/>
<menu_item_call label="In Marktplatz-Auflistungen kopieren" name="Marketplace Copy"/>
<menu_item_call label="In Marktplatz-Auflistungen verschieben" name="Marketplace Move"/>
<menu_item_call label="--keine Optionen--" name="--no options--"/>

View File

@ -2,6 +2,7 @@
<menu_bar name="Login Menu">
<menu label="Ich" name="File">
<menu_item_call label="Einstellungen..." name="Preferences..."/>
<menu_item_check label="Grid-Auswahl anzeigen" name="Show Grid Picker"/>
<menu_item_call label="[APP_NAME] schließen" name="Quit"/>
</menu>
<menu label="Hilfe" name="Help">
@ -33,7 +34,6 @@
<menu_item_check label="Fehler" name="Error"/>
<menu_item_check label="Keine" name="None"/>
</menu>
<menu_item_check label="Grid-Auswahl anzeigen" name="Show Grid Picker"/>
<menu_item_call label="Benachrichtigungs-Konsole anzeigen" name="Show Notifications Console"/>
</menu>
</menu_bar>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="menu_blocked_gear">
<menu_item_call label="Nicht mehr ignorieren" name="unblock"/>
<menu_item_check label="Voice ignorieren" name="BlockVoice"/>
<menu_item_check label="Text ignorieren" name="MuteText"/>
<menu_item_check label="Objektsounds ignorieren" name="BlockObjectSounds"/>
<menu_item_call label="Profil..." name="profile"/>
</toggleable_menu>

View File

@ -44,6 +44,7 @@
<menu_item_check label="Kein Voice-Morphing" name="NoVoiceMorphing"/>
<menu_item_check label="Vorschau..." name="Preview"/>
<menu_item_call label="Abonnieren..." name="Subscribe"/>
<menu_item_call label="Premium-Vorteil..." name="PremiumPerk"/>
</menu>
<menu_item_check label="Gesten..." name="Gestures"/>
<menu_item_check label="Freunde" name="My Friends"/>
@ -57,7 +58,8 @@
<menu_item_call label="Ziele..." name="Destinations"/>
<menu_item_check label="Karte" name="World Map"/>
<menu_item_check label="Minikarte" name="Mini-Map"/>
<menu_item_check label="Suchen" name="Search"/>
<menu_item_call label="Events" name="Events"/>
<menu_item_check label="Suchen..." name="Search"/>
<menu_item_call label="Nach Hause teleportieren" name="Teleport Home"/>
<menu_item_call label="Hier als Zuhause wählen" name="Set Home to Here"/>
<menu_item_call label="Foto" name="Take Snapshot"/>
@ -128,8 +130,10 @@
<menu_item_call label="Kopie nehmen" name="Take Copy"/>
<menu_item_call label="Wieder in Objektinhalt speichern" name="Save Object Back to Object Contents"/>
<menu_item_call label="Objekt zurückgeben" name="Return Object back to Owner"/>
<menu_item_call label="Duplizieren" name="DuplicateObject"/>
</menu>
<menu label="Skripts" name="Scripts">
<menu_item_check label="Skriptwarnungen/Fehler..." name="Script debug"/>
<menu_item_call label="Skripts rekompilieren (Mono)" name="Mono"/>
<menu_item_call label="Skripts rekompilieren (LSL)" name="LSL"/>
<menu_item_call label="Skripts zurücksetzen" name="Reset Scripts"/>

View File

@ -144,8 +144,7 @@ Marktplatzinitialisierung aufgrund eines System- oder Netzwerkfehlers fehlgeschl
<notification name="MerchantTransactionFailed">
Marktplatztransaktion fehlgeschlagen mit Fehler:
Grund: „[ERROR_REASON]“
[ERROR_DESCRIPTION]
[ERROR_REASON][ERROR_DESCRIPTION]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="MerchantUnprocessableEntity">
@ -769,6 +768,9 @@ Stellen Sie sicher, dass kein Objekt gesperrt ist und alle Objekte Ihnen gehöre
<notification name="CannotLinkPermanent">
Objekte können nicht über Regionsgrenzen hinweg verknüpft werden.
</notification>
<notification name="CannotLinkAcrossRegions">
Objekte können nicht über Regionsgrenzen hinweg verknüpft werden.
</notification>
<notification name="CannotLinkDifferentOwners">
Verknüpfung nicht möglich, da nicht alle Objekte denselben Eigentümer haben.
@ -1798,7 +1800,6 @@ Diese Gruppe verlassen?
Nicht-stören-Modus ist aktiviert: Sie erhalten keine Benachrichtigung über eingehende Kommunikation.
- Andere Einwohner erhalten Ihre Nicht-stören-Antwort (festgelegt in Einstellungen &gt; Allgemein).
- Teleport-Angebote werden abgelehnt.
- Voice-Anrufe werden abgelehnt.
<usetemplate ignoretext="Ich ändere meinen Status zu „Nicht stören“" name="okignore" yestext="OK"/>
</notification>
@ -2568,9 +2569,6 @@ Von einer Webseite zu diesem Formular linken, um anderen leichten Zugang zu dies
<notification name="Cancelled">
Abgebrochen
</notification>
<notification name="CancelledSit">
Sitzen beendet
</notification>
<notification name="CancelledAttach">
Anhängen abgebrochen
</notification>
@ -3897,32 +3895,32 @@ Warten Sie kurz und versuchen Sie es noch einmal.
<notification name="AvatarEjectFailed">
Hinauswerfen fehlgeschlagen, da Sie keine Admin-Berechtigung für diese Parzelle haben.
</notification>
<notification name="CantMoveObjectParcelFull">
Objekt „[OBJECT_NAME]“ kann nicht nach
[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da die Parzelle voll ist.
<notification name="CMOParcelFull">
Objekt „[O]“ kann nicht nach
[P] in Region [R] verschoben werden, da die Parzelle voll ist.
</notification>
<notification name="CantMoveObjectParcelPerms">
Objekt „[OBJECT_NAME]“ kann nicht nach
[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da Ihre Objekte auf dieser Parzelle nicht gestattet sind.
<notification name="CMOParcelPerms">
Objekt „[O]“ kann nicht nach
[P] in Region [R] verschoben werden, da Ihre Objekte auf dieser Parzelle nicht gestattet sind.
</notification>
<notification name="CantMoveObjectParcelResources">
Objekt „[OBJECT_NAME]“ kann nicht nach
[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da nicht genügend Ressourcen für dieses Objekt auf dieser Parzelle vorhanden sind.
<notification name="CMOParcelResources">
Objekt „[O]“ kann nicht nach
[P] in Region [R] verschoben werden, da nicht genügend Ressourcen für dieses Objekt auf dieser Parzelle vorhanden sind.
</notification>
<notification name="NoParcelPermsNoObject">
Kopiervorgang fehlgeschlagen, da Sie keinen Zugriff auf diese Parzelle haben.
</notification>
<notification name="CantMoveObjectRegionVersion">
Objekt „[OBJECT_NAME]“ kann nicht nach
[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da die andere Region eine ältere Version verwendet, die das Empfangen dieses Objekts per Regionswechsel nicht unterstützt.
<notification name="CMORegionVersion">
Objekt „[O]“ kann nicht nach
[P] in Region [R] verschoben werden, da die andere Region eine ältere Version verwendet, die das Empfangen dieses Objekts per Regionswechsel nicht unterstützt.
</notification>
<notification name="CantMoveObjectNavMesh">
Objekt „[OBJECT_NAME]“ kann nicht nach
[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da Sie das Navmesh nicht regionsübergreifend modifizieren können.
<notification name="CMONavMesh">
Objekt „[O]“ kann nicht nach
[P] in Region [R] verschoben werden, da Sie das Navmesh nicht regionsübergreifend modifizieren können.
</notification>
<notification name="CantMoveObjectWTF">
Objekt „[OBJECT_NAME]“ kann nicht nach
[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da ein unbekannter Fehler vorliegt. ([FAILURE_TYPE])
<notification name="CMOWTF">
Objekt „[O]“ kann nicht nach
[P] in Region [R] verschoben werden, da ein unbekannter Fehler vorliegt. ([F])
</notification>
<notification name="NoPermModifyObject">
Ihnen fehlt die Berechtigung zum Modifizieren dieses Objekts.

View File

@ -7,5 +7,8 @@
<menu_button name="plus_btn" tool_tip="Einwohner oder Objekt zum ignorieren auswählen"/>
<button name="unblock_btn" tool_tip="Einwohner oder Objekt aus der Liste der ignorierten Einwohner oder Objekte entfernen"/>
</panel>
<text name="block_limit">
[COUNT] Einträge in Ihrer Liste der ignorierten Einwohner. Höchstwert: [LIMIT].
</text>
<block_list name="blocked" tool_tip="Liste der zur Zeit ignorierten Einwohner" width="290"/>
</panel>

View File

@ -30,6 +30,6 @@ Für Markierungen, die aus mehreren Wörtern bestehen, &quot;&quot; verwenden.
<combo_box.item label="Moderate Flickr-Einstufung" name="ModerateRating"/>
<combo_box.item label="Beschränkte Flickr-Einstufung" name="RestrictedRating"/>
</combo_box>
<button label="Hochladen" name="post_photo_btn"/>
<button label="Teilen" name="post_photo_btn"/>
<button label="Abbrechen" name="cancel_photo_btn"/>
</panel>

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="instant_message" name="panel_notify_textbox">
<string name="message_max_lines_count" value="7"/>
<panel label="info_panel" name="info_panel">
<text_editor name="message" value="message"/>
<string name="message_max_lines_count" value="14"/>
<panel label="info_panel" name="info_panel"/>
<panel label="info_panel" name="textbox_panel">
<text_editor name="message" value="Nachricht"/>
</panel>
<panel label="control_panel" name="control_panel">
<button label="Senden" name="btn_submit"/>

Some files were not shown because too many files have changed in this diff Show More