Merge branch 'master' into DRTVWR-539

master
Mnikolenko Productengine 2022-09-21 18:36:49 +03:00
commit 85504f085e
501 changed files with 17406 additions and 8713 deletions

View File

@ -482,9 +482,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2653c3627fd8687ff9e003425fd14834</string>
<string>439d92ec73f0500ba1671faad2bd8090</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90199/821852/dullahan-1.12.3.202111032211_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-565428.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104637/916643/dullahan-1.12.4.202209142017_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-575005.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -494,9 +494,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b4003772562a5dd40bc112eec7cba5f5</string>
<string>2a7c01da15de77bc1fd1863327174d5e</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90201/821871/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-565428.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104638/916654/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-575005.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -506,16 +506,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d9030d7a7390b3bda7de2adcc27e535a</string>
<string>d06bee9b2517fbb09ba1a65e6d675361</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90200/821876/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-565428.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104639/916659/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-575005.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
<string>1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
</map>
<key>expat</key>
<map>
@ -2393,9 +2393,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>6ce3cbaed968a69fb7a2cca80220874d</string>
<string>b583668b28fde0490e6953f10e93e4ab</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80380/758537/slvoice-4.10.0000.32327.5fc3fe7c.558436-darwin64-558436.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98681/871545/slvoice-4.10.0000.32327.5fc3fe7c.571099-darwin64-571099.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2417,9 +2417,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>2eb38c5eff4d0f18fbb89d0c30c4f0a4</string>
<string>6e0ed41653955afe8eeb8945776cf07b</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80382/758550/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows-558436.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98683/871560/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows-571099.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -2429,16 +2429,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>9ee8f3cbc5369c598a998c61961ed16d</string>
<string>c39735851fd05c194d0be09b8f9e8cb7</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80381/758551/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows64-558436.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98682/871552/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows64-571099.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>4.10.0000.32327.5fc3fe7c.558436</string>
<string>4.10.0000.32327.5fc3fe7c.571099</string>
</map>
<key>threejs</key>
<map>

View File

@ -223,6 +223,7 @@ Ansariel Hiller
MAINT-8723
SL-10385
SL-10891
SL-10675
SL-13364
SL-13858
SL-13697
@ -820,6 +821,7 @@ Jonathan Yap
Kadah Coba
STORM-1060
STORM-1843
SL-10675
Jondan Lundquist
Joosten Briebers
MAINT-7074

View File

@ -276,7 +276,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
{
// The source is done playing, clean it up.
delete sourcep;
mAllSources.erase(iter++);
iter = mAllSources.erase(iter);
continue;
}
@ -827,7 +827,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
addAudioSource(asp);
if (pos_global.isExactlyZero())
{
asp->setAmbient(true);
// For sound preview and UI
asp->setForcedPriority(true);
}
else
{
@ -1273,7 +1274,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mPriority(0.f),
mGain(gain),
mSourceMuted(false),
mAmbient(false),
mForcedPriority(false),
mLoop(false),
mSyncMaster(false),
mSyncSlave(false),
@ -1339,7 +1340,7 @@ void LLAudioSource::update()
void LLAudioSource::updatePriority()
{
if (isAmbient())
if (isForcedPriority())
{
mPriority = 1.f;
}

View File

@ -266,8 +266,8 @@ public:
void addAudioData(LLAudioData *adp, bool set_current = TRUE);
void setAmbient(const bool ambient) { mAmbient = ambient; }
bool isAmbient() const { return mAmbient; }
void setForcedPriority(const bool ambient) { mForcedPriority = ambient; }
bool isForcedPriority() const { return mForcedPriority; }
void setLoop(const bool loop) { mLoop = loop; }
bool isLoop() const { return mLoop; }
@ -326,7 +326,7 @@ protected:
F32 mPriority;
F32 mGain;
bool mSourceMuted;
bool mAmbient;
bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI
bool mLoop;
bool mSyncMaster;
bool mSyncSlave;

View File

@ -519,9 +519,9 @@ void LLAudioChannelFMODSTUDIO::update3DPosition()
return;
}
if (mCurrentSourcep->isAmbient())
if (mCurrentSourcep->isForcedPriority())
{
// Ambient sound, don't need to do any positional updates.
// Prioritized UI and preview sounds don't need to do any positional updates.
set3DMode(false);
}
else

View File

@ -297,7 +297,7 @@ void LLAudioChannelOpenAL::update3DPosition()
{
return;
}
if (mCurrentSourcep->isAmbient())
if (mCurrentSourcep->isForcedPriority())
{
alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);

View File

@ -70,7 +70,11 @@ mRetryCount(0)
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
if (result != FMOD_OK)
{
LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
}
// Here's where we set the size of the network buffer and some buffering
// parameters. In this case we want a network buffer of 16k, we want it
@ -134,7 +138,7 @@ void LLStreamingAudio_FMODSTUDIO::killDeadStreams()
{
LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
delete streamp;
mDeadStreams.erase(iter++);
iter = mDeadStreams.erase(iter);
}
else
{
@ -404,7 +408,11 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
if (mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
if (result != FMOD_OK)
{
LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
}
return mStreamChannel;
}
@ -445,16 +453,29 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream()
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
if (result != FMOD_OK)
{
LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
}
return state;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
FMOD_RESULT result = mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
if (result != FMOD_OK)
{
LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
return;
}
FMOD_ADVANCEDSETTINGS settings;
memset(&settings, 0, sizeof(settings));
settings.cbSize = sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
mSystem->setAdvancedSettings(&settings);
result = mSystem->setAdvancedSettings(&settings);
if (result != FMOD_OK)
{
LL_WARNS("FMOD") << "setAdvancedSettings error: " << FMOD_ErrorString(result) << LL_ENDL;
}
}

View File

@ -44,6 +44,14 @@ using namespace std;
#define INCHES_TO_METERS 0.02540005f
/// The .bvh does not have a formal spec, and different readers interpret things in their own way.
/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation.
const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1;
/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards.
/// I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point..
/// Thus there are two frame of the total that do not contribute to the total running time of the animation.
const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1;
const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f;
const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f;
@ -865,7 +873,10 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
return E_ST_NO_FRAME_TIME;
}
mDuration = (F32)mNumFrames * mFrameTime;
// If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime.
// If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the
// behavior is not defined. In this case, retain historical undefined behavior.
mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime;
if (!mLoop)
{
mLoopOutPoint = mDuration;
@ -1355,12 +1366,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
S32 outcount = 0;
S32 frame = 1;
S32 frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
if ((frame == 1) && joint->mRelativeRotationKey)
if ((frame == 0) && joint->mRelativeRotationKey)
{
first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
@ -1373,7 +1385,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
time = (F32)frame * mFrameTime;
time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
if (mergeParent)
{
@ -1433,12 +1445,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLVector3 relPos = joint->mRelativePosition;
LLVector3 relKey;
frame = 1;
frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
if ((frame == 1) && joint->mRelativePositionKey)
if ((frame == 0) && joint->mRelativePositionKey)
{
relKey.setVec(ki->mPos);
}
@ -1449,7 +1461,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
time = (F32)frame * mFrameTime;
time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;
LLVector3 outPos = inPos * frameRot * offsetRot;

View File

@ -116,14 +116,20 @@ void LLAlignedArray<T, alignment>::resize(U32 size)
template <class T, U32 alignment>
T& LLAlignedArray<T, alignment>::operator[](int idx)
{
llassert(idx < mElementCount);
if(idx >= mElementCount || idx < 0)
{
LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
}
return mArray[idx];
}
template <class T, U32 alignment>
const T& LLAlignedArray<T, alignment>::operator[](int idx) const
{
llassert(idx < mElementCount);
if (idx >= mElementCount || idx < 0)
{
LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
}
return mArray[idx];
}

View File

@ -35,6 +35,7 @@
// STL headers
// std headers
#include <atomic>
#include <stdexcept>
// external library headers
#include <boost/bind.hpp>
#include <boost/fiber/fiber.hpp>
@ -214,6 +215,22 @@ std::string LLCoros::logname()
return data.mName.empty()? data.getKey() : data.mName;
}
void LLCoros::saveException(const std::string& name, std::exception_ptr exc)
{
mExceptionQueue.emplace(name, exc);
}
void LLCoros::rethrow()
{
if (! mExceptionQueue.empty())
{
ExceptionData front = mExceptionQueue.front();
mExceptionQueue.pop();
LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL;
std::rethrow_exception(front.exception);
}
}
void LLCoros::setStackSize(S32 stacksize)
{
LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
void LLCoros::winlevel(const std::string& name, const callable_t& callable)
void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
{
__try
{
toplevelTryWrapper(name, callable);
LLCoros::toplevelTryWrapper(name, callable);
}
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)
throw std::exception(integer_string);
}
}
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
// crash, hopefully informatively.
// crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
#else
// Stash any OTHER kind of uncaught exception in the rethrow() queue
// to be rethrown by the main fiber.
LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
<< name << LL_ENDL;
LLCoros::instance().saveException(name, std::current_exception());
#endif
}
}
@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
// Can not use __try in functions that require unwinding, so use one more wrapper
winlevel(name, callable);
// Because SEH can's have unwinding, need to call a wrapper
// 'try' is inside SEH handling to not catch LLContinue
sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif

View File

@ -38,6 +38,8 @@
#include "llinstancetracker.h"
#include <boost/function.hpp>
#include <string>
#include <exception>
#include <queue>
// e.g. #include LLCOROS_MUTEX_HEADER
#define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp>
@ -156,6 +158,19 @@ public:
* LLCoros::launch()).
*/
static std::string getName();
/**
* rethrow() is called by the thread's main fiber to propagate an
* exception from any coroutine into the main fiber, where it can engage
* the normal unhandled-exception machinery, up to and including crash
* reporting.
*
* LLCoros maintains a queue of otherwise-uncaught exceptions from
* terminated coroutines. Each call to rethrow() pops the first of those
* and rethrows it. When the queue is empty (normal case), rethrow() is a
* no-op.
*/
void rethrow();
/**
* This variation returns a name suitable for log messages: the explicit
@ -292,13 +307,27 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
#if LL_WINDOWS
void winlevel(const std::string& name, const callable_t& callable);
#endif
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
void toplevel(std::string name, callable_t callable);
#if LL_WINDOWS
void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
#endif
void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
void saveException(const std::string& name, std::exception_ptr exc);
struct ExceptionData
{
ExceptionData(const std::string& nm, std::exception_ptr exc):
name(nm),
exception(exc)
{}
// name of coroutine that originally threw this exception
std::string name;
// the thrown exception
std::exception_ptr exception;
};
std::queue<ExceptionData> mExceptionQueue;
S32 mStackSize;

View File

@ -118,7 +118,11 @@ namespace
eMONTIOR_MWAIT=33,
eCPLDebugStore=34,
eThermalMonitor2=35,
eAltivec=36
eAltivec=36,
eSSE3S_Features = 37,
eSSE4_1_Features = 38,
eSSE4_2_Features = 39,
eSSE4a_Features = 40,
};
const char* cpu_feature_names[] =
@ -161,7 +165,11 @@ namespace
"CPL Qualified Debug Store",
"Thermal Monitor 2",
"Altivec"
"Altivec",
"SSE3S Instructions",
"SSE4.1 Instructions",
"SSE4.2 Instructions",
"SSE4a Instructions",
};
std::string intel_CPUFamilyName(int composed_family)
@ -250,6 +258,31 @@ public:
return hasExtension(cpu_feature_names[eSSE2_Ext]);
}
bool hasSSE3() const
{
return hasExtension(cpu_feature_names[eSSE3_Features]);
}
bool hasSSE3S() const
{
return hasExtension(cpu_feature_names[eSSE3S_Features]);
}
bool hasSSE41() const
{
return hasExtension(cpu_feature_names[eSSE4_1_Features]);
}
bool hasSSE42() const
{
return hasExtension(cpu_feature_names[eSSE4_2_Features]);
}
bool hasSSE4a() const
{
return hasExtension(cpu_feature_names[eSSE4a_Features]);
}
bool hasAltivec() const
{
return hasExtension("Altivec");
@ -473,6 +506,12 @@ private:
*((int*)(cpu_vendor+4)) = cpu_info[3];
*((int*)(cpu_vendor+8)) = cpu_info[2];
setInfo(eVendor, cpu_vendor);
std::string cmp_vendor(cpu_vendor);
bool is_amd = false;
if (cmp_vendor == "AuthenticAMD")
{
is_amd = true;
}
// Get the information associated with each valid Id
for(unsigned int i=0; i<=ids; ++i)
@ -504,6 +543,7 @@ private:
if(cpu_info[2] & 0x8)
{
// intel specific SSE3 suplements
setExtension(cpu_feature_names[eMONTIOR_MWAIT]);
}
@ -516,7 +556,22 @@ private:
{
setExtension(cpu_feature_names[eThermalMonitor2]);
}
if (cpu_info[2] & 0x200)
{
setExtension(cpu_feature_names[eSSE3S_Features]);
}
if (cpu_info[2] & 0x80000)
{
setExtension(cpu_feature_names[eSSE4_1_Features]);
}
if (cpu_info[2] & 0x100000)
{
setExtension(cpu_feature_names[eSSE4_2_Features]);
}
unsigned int feature_info = (unsigned int) cpu_info[3];
for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
{
@ -543,8 +598,17 @@ private:
__cpuid(cpu_info, i);
// Interpret CPU brand string and cache information.
if (i == 0x80000002)
memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
if (i == 0x80000001)
{
if (is_amd)
{
setExtension(cpu_feature_names[eSSE4a_Features]);
}
}
else if (i == 0x80000002)
{
memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
}
else if (i == 0x80000003)
memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info));
else if (i == 0x80000004)
@ -690,6 +754,41 @@ private:
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
setConfig(eExtFeatureBits, ext_feature_infos[0]);
char cpu_features[1024];
len = sizeof(cpu_features);
memset(cpu_features, 0, len);
sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0);
std::string cpu_features_str(cpu_features);
cpu_features_str = " " + cpu_features_str + " ";
if (cpu_features_str.find(" SSE3 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE3_Features]);
}
if (cpu_features_str.find(" SSSE3 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE3S_Features]);
}
if (cpu_features_str.find(" SSE4.1 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE4_1_Features]);
}
if (cpu_features_str.find(" SSE4.2 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE4_2_Features]);
}
if (cpu_features_str.find(" SSE4A ") != std::string::npos)
{
// Not supposed to happen?
setExtension(cpu_feature_names[eSSE4a_Features]);
}
}
};
@ -800,6 +899,31 @@ private:
{
setExtension(cpu_feature_names[eSSE2_Ext]);
}
if (flags.find(" pni ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE3_Features]);
}
if (flags.find(" ssse3 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE3S_Features]);
}
if (flags.find(" sse4_1 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE4_1_Features]);
}
if (flags.find(" sse4_2 ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE4_2_Features]);
}
if (flags.find(" sse4a ") != std::string::npos)
{
setExtension(cpu_feature_names[eSSE4a_Features]);
}
# endif // LL_X86
}
@ -860,6 +984,11 @@ LLProcessorInfo::~LLProcessorInfo() {}
F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); }
bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }

View File

@ -54,6 +54,11 @@ public:
F64MegahertzImplicit getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasSSE3() const;
bool hasSSE3S() const;
bool hasSSE41() const;
bool hasSSE42() const;
bool hasSSE4a() const;
bool hasAltivec() const;
std::string getCPUFamilyName() const;
std::string getCPUBrandName() const;

View File

@ -597,6 +597,11 @@ LLCPUInfo::LLCPUInfo()
// proc.WriteInfoTextFile("procInfo.txt");
mHasSSE = proc.hasSSE();
mHasSSE2 = proc.hasSSE2();
mHasSSE3 = proc.hasSSE3();
mHasSSE3S = proc.hasSSE3S();
mHasSSE41 = proc.hasSSE41();
mHasSSE42 = proc.hasSSE42();
mHasSSE4a = proc.hasSSE4a();
mHasAltivec = proc.hasAltivec();
mCPUMHz = (F64)proc.getCPUFrequency();
mFamily = proc.getCPUFamilyName();
@ -609,6 +614,35 @@ LLCPUInfo::LLCPUInfo()
}
mCPUString = out.str();
LLStringUtil::trim(mCPUString);
if (mHasSSE)
{
mSSEVersions.append("1");
}
if (mHasSSE2)
{
mSSEVersions.append("2");
}
if (mHasSSE3)
{
mSSEVersions.append("3");
}
if (mHasSSE3S)
{
mSSEVersions.append("3S");
}
if (mHasSSE41)
{
mSSEVersions.append("4.1");
}
if (mHasSSE42)
{
mSSEVersions.append("4.2");
}
if (mHasSSE4a)
{
mSSEVersions.append("4a");
}
}
bool LLCPUInfo::hasAltivec() const
@ -626,6 +660,31 @@ bool LLCPUInfo::hasSSE2() const
return mHasSSE2;
}
bool LLCPUInfo::hasSSE3() const
{
return mHasSSE3;
}
bool LLCPUInfo::hasSSE3S() const
{
return mHasSSE3S;
}
bool LLCPUInfo::hasSSE41() const
{
return mHasSSE41;
}
bool LLCPUInfo::hasSSE42() const
{
return mHasSSE42;
}
bool LLCPUInfo::hasSSE4a() const
{
return mHasSSE4a;
}
F64 LLCPUInfo::getMHz() const
{
return mCPUMHz;
@ -636,6 +695,11 @@ std::string LLCPUInfo::getCPUString() const
return mCPUString;
}
const LLSD& LLCPUInfo::getSSEVersions() const
{
return mSSEVersions;
}
void LLCPUInfo::stream(std::ostream& s) const
{
// gather machine information.
@ -645,6 +709,11 @@ void LLCPUInfo::stream(std::ostream& s) const
// CPU's attributes regardless of platform
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl;
s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl;
s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl;
s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl;
s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl;
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
s << "->mCPUMHz: " << mCPUMHz << std::endl;
s << "->mCPUString: " << mCPUString << std::endl;

View File

@ -80,10 +80,16 @@ public:
void stream(std::ostream& s) const;
std::string getCPUString() const;
const LLSD& getSSEVersions() const;
bool hasAltivec() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasSSE3() const;
bool hasSSE3S() const;
bool hasSSE41() const;
bool hasSSE42() const;
bool hasSSE4a() const;
F64 getMHz() const;
// Family is "AMD Duron" or "Intel Pentium Pro"
@ -92,10 +98,16 @@ public:
private:
bool mHasSSE;
bool mHasSSE2;
bool mHasSSE3;
bool mHasSSE3S;
bool mHasSSE41;
bool mHasSSE42;
bool mHasSSE4a;
bool mHasAltivec;
F64 mCPUMHz;
std::string mFamily;
std::string mCPUString;
LLSD mSSEVersions;
};
//=============================================================================

View File

@ -354,6 +354,38 @@ void LLDiskCache::clearCache()
}
}
void LLDiskCache::removeOldVFSFiles()
{
//VFS files won't be created, so consider removing this code later
static const char CACHE_FORMAT[] = "inv.llsd";
static const char DB_FORMAT[] = "db2.x";
boost::system::error_code ec;
#if LL_WINDOWS
std::wstring cache_path(utf8str_to_utf16str(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")));
#else
std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""));
#endif
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
{
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
{
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
{
if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
(entry.path().string().find(DB_FORMAT) != std::string::npos))
{
boost::filesystem::remove(entry, ec);
if (ec.failed())
{
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
}
}
}
}
}
}
uintmax_t LLDiskCache::dirFileSize(const std::string dir)
{
uintmax_t total_file_size = 0;

View File

@ -140,6 +140,8 @@ class LLDiskCache :
*/
const std::string getCacheInfo();
void removeOldVFSFiles();
private:
/**
* Utility function to gather the total size the files in a given

View File

@ -234,6 +234,8 @@ void LLParcel::init(const LLUUID &owner_id,
setRegionAllowEnvironmentOverride(FALSE);
setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION);
setObscureMOAP(false);
}
void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)
@ -540,6 +542,7 @@ void LLParcel::packMessage(LLSD& msg)
msg["see_avs"] = (LLSD::Boolean) getSeeAVs();
msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds();
msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds();
msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP();
}

View File

@ -306,6 +306,7 @@ public:
void setRestrictPushObject(BOOL b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); }
void setAllowGroupAVSounds(BOOL b) { mAllowGroupAVSounds = b; }
void setAllowAnyAVSounds(BOOL b) { mAllowAnyAVSounds = b; }
void setObscureMOAP(bool b) { mObscureMOAP = b; }
void setDrawDistance(F32 dist) { mDrawDistance = dist; }
void setSalePrice(S32 price) { mSalePrice = price; }
@ -517,6 +518,8 @@ public:
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; }
bool getObscureMOAP() const { return mObscureMOAP; }
F32 getDrawDistance() const { return mDrawDistance; }
S32 getSalePrice() const { return mSalePrice; }
@ -670,6 +673,7 @@ protected:
BOOL mRegionAllowEnvironmentOverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
bool mObscureMOAP;
S32 mCurrentEnvironmentVersion;
bool mIsDefaultDayCycle;

View File

@ -684,7 +684,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
static LLAlignedArray<LLVector4a,64> pt;
static thread_local LLAlignedArray<LLVector4a,64> pt;
pt.resize(mTotal) ;
for (S32 i=mTotalOut;i<mTotal;i++)
@ -6674,13 +6674,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
else
{
// Get s value for tex-coord.
if (!flat)
S32 index = mBeginS + s;
if (index >= profile.size())
{
// edge?
ss = flat ? 1.f - begin_stex : 1.f;
}
else if (!flat)
{
ss = profile[mBeginS + s][2];
ss = profile[index][2];
}
else
{
ss = profile[mBeginS + s][2] - begin_stex;
ss = profile[index][2] - begin_stex;
}
}
@ -6866,7 +6872,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* norm = mNormals;
static LLAlignedArray<LLVector4a, 64> triangle_normals;
static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;
try
{
triangle_normals.resize(count);

View File

@ -196,6 +196,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
}
}
catch (const LLCoros::Stop&)
{
LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL;
}
catch (...)
{
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()

View File

@ -32,7 +32,6 @@
#include "llcoros.h"
#include "llcorehttputil.h"
#include "lluuid.h"
#include <boost/smart_ptr/shared_ptr.hpp>
class LLCoprocedurePool;
@ -84,7 +83,7 @@ public:
private:
typedef boost::shared_ptr<LLCoprocedurePool> poolPtr_t;
typedef std::shared_ptr<LLCoprocedurePool> poolPtr_t;
typedef std::map<std::string, poolPtr_t> poolMap_t;
poolMap_t mPoolMap;

View File

@ -1386,6 +1386,7 @@ char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getIns
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock");
char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion");
char const* const _PREHASH_ParcelExtendedFlags = LLMessageStringTable::getInstance()->getString("ParcelExtendedFlags");
char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");

View File

@ -1386,6 +1386,7 @@ extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_ParcelEnvironmentBlock;
extern char const* const _PREHASH_ParcelEnvironmentVersion;
extern char const* const _PREHASH_ParcelExtendedFlags;
extern char const* const _PREHASH_RegionAllowEnvironmentOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;

View File

@ -1549,6 +1549,7 @@ void LLPluginClassMedia::seek(float time)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
message.setValueReal("time", time);
mCurrentTime = time; // assume that it worked and we will receive an update later
sendMessage(message);
}

View File

@ -999,7 +999,7 @@ void LLPluginProcessParent::poll(F64 timeout)
while (itClean != sInstances.end())
{
if ((*itClean).second->isDone())
sInstances.erase(itClean++);
itClean = sInstances.erase(itClean);
else
++itClean;
}

View File

@ -843,7 +843,7 @@ LLSD LLModel::writeModel(
{
LLVector3 pos(face.mPositions[j].getF32ptr());
weight_list& weights = high->getJointInfluences(pos);
weight_list& weights = model[idx]->getJointInfluences(pos);
S32 count = 0;
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
@ -1553,6 +1553,25 @@ void LLMeshSkinInfo::updateHash()
mHash = digest[0];
}
U32 LLMeshSkinInfo::sizeBytes() const
{
U32 res = sizeof(LLUUID); // mMeshID
res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size();
for (U32 i = 0; i < mJointNames.size(); ++i)
{
res += mJointNames[i].size(); // actual size, not capacity
}
res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size();
res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size();
res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size();
res += 16 * sizeof(float); //mBindShapeMatrix
res += sizeof(float) + 3 * sizeof(bool);
return res;
}
LLModel::Decomposition::Decomposition(LLSD& data)
{
fromLLSD(data);
@ -1659,6 +1678,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
}
}
U32 LLModel::Decomposition::sizeBytes() const
{
U32 res = sizeof(LLUUID); // mMeshID
res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size();
for (U32 i = 0; i < mHull.size(); ++i)
{
res += mHull[i].size() * sizeof(LLVector3);
}
res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size();
res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size();
for (U32 i = 0; i < mMesh.size(); ++i)
{
res += mMesh[i].sizeBytes();
}
res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2;
res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes();
return res;
}
bool LLModel::Decomposition::hasHullList() const
{
return !mHull.empty() ;

View File

@ -50,6 +50,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash();
U32 sizeBytes() const;
LLUUID mMeshID;
std::vector<std::string> mJointNames;
@ -112,6 +113,14 @@ public:
{
return mPositions.empty();
}
U32 sizeBytes() const
{
U32 res = sizeof(std::vector<LLVector3>) * 2;
res += sizeof(LLVector3) * mPositions.size();
res += sizeof(LLVector3) * mNormals.size();
return res;
}
};
class Decomposition
@ -122,6 +131,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
bool hasHullList() const;
U32 sizeBytes() const;
void merge(const Decomposition* rhs);

View File

@ -1248,7 +1248,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
scratch = new U32[width * height];
scratch = new(std::nothrow) U32[width * height];
if (!scratch)
{
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
}
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@ -1268,7 +1273,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
scratch = new U32[width * height];
scratch = new(std::nothrow) U32[width * height];
if (!scratch)
{
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
}
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@ -1291,7 +1301,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
scratch = new U32[width * height];
scratch = new(std::nothrow) U32[width * height];
if (!scratch)
{
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
}
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)

View File

@ -259,6 +259,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
mLegacyHeaderHeight(p.legacy_header_height),
mDefaultRectForGroup(true),
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
@ -761,17 +762,13 @@ void LLFloater::closeFloater(bool app_quitting)
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); )
{
LLFloater* floaterp = dependent_it->get();
if (floaterp)
{
++dependent_it;
floaterp->closeFloater(app_quitting);
}
else
{
mDependents.erase(dependent_it++);
}
dependent_it = mDependents.erase(dependent_it);
if (floaterp)
{
floaterp->mDependeeHandle = LLHandle<LLFloater>();
floaterp->closeFloater(app_quitting);
}
}
cleanupHandles();
@ -906,7 +903,10 @@ bool LLFloater::applyRectControl()
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
mRectControl.clear();
if (mDefaultRectForGroup)
{
mRectControl.clear();
}
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
else
@ -1439,7 +1439,7 @@ void LLFloater::cleanupHandles()
LLFloater* floaterp = dependent_it->get();
if (!floaterp)
{
mDependents.erase(dependent_it++);
dependent_it = mDependents.erase(dependent_it);
}
else
{
@ -3481,8 +3481,15 @@ void LLFloater::stackWith(LLFloater& other)
}
next_rect.translate(floater_offset, -floater_offset);
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
const LLRect& rect = getControlGroup()->getRect(mRectControl);
if (rect.notEmpty() && !mDefaultRectForGroup && mResizable)
{
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
}
else
{
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
}
setShape(next_rect);
if (!other.getHost())

View File

@ -454,6 +454,7 @@ public:
protected:
bool mSaveRect;
bool mDefaultRectForGroup;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;

View File

@ -35,6 +35,7 @@
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluiimage.h"
#include "llwindow.h"
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()
: image("image_name"),
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
interactable("interactable", false),
scale_image("scale_image"),
min_width("min_width", 0),
min_height("min_height", 0)
@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
mColor(p.color()),
mImagep(p.image),
mUseDrawContextAlpha(p.use_draw_context_alpha),
mInteractable(p.interactable),
mPriority(0),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
@ -81,6 +84,16 @@ void LLIconCtrl::draw()
LLUICtrl::draw();
}
BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
{
if (mInteractable && getEnabled())
{
getWindow()->setCursor(UI_CURSOR_HAND);
return TRUE;
}
return LLUICtrl::handleHover(x, y, mask);
}
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value)

View File

@ -48,7 +48,8 @@ public:
{
Optional<LLUIImage*> image;
Optional<LLUIColor> color;
Optional<bool> use_draw_context_alpha;
Optional<bool> use_draw_context_alpha,
interactable;
Optional<S32> min_width,
min_height;
Ignored scale_image;
@ -67,6 +68,9 @@ public:
// llview overrides
virtual void draw();
// llview overrides
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
// lluictrl overrides
virtual void setValue(const LLSD& value );
@ -88,6 +92,7 @@ protected:
// If set to true (default), use the draw context transparency.
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
bool mUseDrawContextAlpha;
bool mInteractable;
private:
LLUIColor mColor;

View File

@ -40,6 +40,7 @@ void LLMenuButton::MenuPositions::declareValues()
declare("topleft", MP_TOP_LEFT);
declare("topright", MP_TOP_RIGHT);
declare("bottomleft", MP_BOTTOM_LEFT);
declare("bottomright", MP_BOTTOM_RIGHT);
}
LLMenuButton::Params::Params()
@ -212,6 +213,13 @@ void LLMenuButton::updateMenuOrigin()
mY = rect.mBottom;
break;
}
case MP_BOTTOM_RIGHT:
{
const LLRect& menu_rect = menu->getRect();
mX = rect.mRight - menu_rect.getWidth();
mY = rect.mBottom;
break;
}
}
}

View File

@ -41,7 +41,8 @@ public:
{
MP_TOP_LEFT,
MP_TOP_RIGHT,
MP_BOTTOM_LEFT
MP_BOTTOM_LEFT,
MP_BOTTOM_RIGHT
} EMenuPosition;
struct MenuPositions

View File

@ -3960,8 +3960,8 @@ void LLTearOffMenu::draw()
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
mMenu->needsArrange();
}
mMenu->needsArrange();
LLFloater::draw();
}

View File

@ -100,7 +100,10 @@ void LLModalDialog::onOpen(const LLSD& key)
if (!sModalStack.empty())
{
LLModalDialog* front = sModalStack.front();
front->setVisible(FALSE);
if (front != this)
{
front->setVisible(FALSE);
}
}
// This is a modal dialog. It sucks up all mouse and keyboard operations.
@ -108,7 +111,14 @@ void LLModalDialog::onOpen(const LLSD& key)
LLUI::getInstance()->addPopup(this);
setFocus(TRUE);
sModalStack.push_front( this );
std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
if (iter != sModalStack.end())
{
// if already present, we want to move it to front.
sModalStack.erase(iter);
}
sModalStack.push_front(this);
}
}

View File

@ -1388,6 +1388,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
return found;
}
U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus)
{
return searchItems(utf8str_to_wstring(substring), case_sensitive, focus);
}
U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus)
{
U32 found = 0;
LLWString substring_trimmed(substring);
S32 len = substring_trimmed.size();
if (0 == len)
{
// at the moment search for empty element is not supported
return 0;
}
else
{
deselectAllItems(TRUE);
if (!case_sensitive)
{
// do comparisons in lower case
LLWStringUtil::toLower(substring_trimmed);
}
for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
LLScrollListItem* item = *iter;
// Only select enabled items with matching names
if (!item->getEnabled())
{
continue;
}
LLScrollListCell* cellp = item->getColumn(getSearchColumn());
if (!cellp)
{
continue;
}
LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
if (!case_sensitive)
{
LLWStringUtil::toLower(item_label);
}
// remove extraneous whitespace from searchable label
LLWStringUtil::trim(item_label);
size_t found_iter = item_label.find(substring_trimmed);
if (found_iter != std::string::npos)
{
// find offset of matching text
cellp->highlightText(found_iter, substring_trimmed.size());
selectItem(item, -1, FALSE);
found++;
if (!mAllowMultipleSelection)
{
break;
}
}
}
}
if (focus && found != 0)
{
mNeedsScroll = true;
}
if (mCommitOnSelectionChange)
{
commitIfChanged();
}
return found;
}
const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const
{
LLScrollListItem* item;
@ -1912,6 +1990,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@ -1975,6 +2054,15 @@ void LLScrollListCtrl::removeFriend(std::string id)
LLUrlAction::removeFriend(slurl);
}
void LLScrollListCtrl::reportAbuse(std::string id, bool is_group)
{
if (!is_group)
{
std::string slurl = "secondlife:///app/agent/" + id + "/about";
LLUrlAction::reportAbuse(slurl);
}
}
void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
{
// open the resident's details or the group details

View File

@ -267,6 +267,14 @@ public:
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
// If multi select is on, select all element that include substring,
// otherwise select first match only.
// If focus is true will scroll to selection.
// Returns number of results.
// Note: at the moment search happens in one go and is expensive
U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true);
U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true);
// DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
@ -325,6 +333,7 @@ public:
// support right-click context menus for avatar/group lists
enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
ContextMenuType getContextMenuType() { return mContextMenuType; }
// Overridden from LLView
/*virtual*/ void draw();
@ -460,6 +469,7 @@ private:
static void sendIM(std::string id);
static void addFriend(std::string id);
static void removeFriend(std::string id);
static void reportAbuse(std::string id, bool is_group);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);

View File

@ -402,9 +402,13 @@ void LLTabContainer::draw()
S32 cur_scroll_pos = getScrollPos();
if (cur_scroll_pos > 0)
{
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
if (!mIsVertical)
if (mIsVertical)
{
target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
}
else
{
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@ -1189,13 +1193,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
updateMaxScrollPos();
if( select )
{
selectLastTab();
mScrollPos = mMaxScrollPos;
}
updateMaxScrollPos();
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
@ -2079,9 +2085,9 @@ void LLTabContainer::updateMaxScrollPos()
if( tab_total_height > available_height )
{
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;
S32 additional_needed = tab_total_height - available_height_with_arrows;
setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );
no_scroll = FALSE;
}
}

View File

@ -163,6 +163,7 @@ LLTextBase::Params::Params()
font_shadow("font_shadow"),
wrap("wrap"),
trusted_content("trusted_content", true),
always_show_icons("always_show_icons", false),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
force_urls_external("force_urls_external", false),
@ -212,6 +213,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mClip(p.clip),
mClipPartial(p.clip_partial && !p.allow_scroll),
mTrustedContent(p.trusted_content),
mAlwaysShowIcons(p.always_show_icons),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@ -448,8 +450,48 @@ void LLTextBase::drawSelectionBackground()
++rect_it)
{
LLRect selection_rect = *rect_it;
selection_rect = *rect_it;
selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
if (mScroller)
{
// If scroller is On content_display_rect has correct rect and safe to use as is
// Note: we might need to account for border
selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
}
else
{
// If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
// and we have to acount for offset depending on position
S32 v_delta = 0;
S32 h_delta = 0;
switch (mVAlign)
{
case LLFontGL::TOP:
v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
break;
case LLFontGL::VCENTER:
v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
break;
case LLFontGL::BOTTOM:
v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
break;
default:
break;
}
switch (mHAlign)
{
case LLFontGL::LEFT:
h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
break;
case LLFontGL::HCENTER:
h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
break;
case LLFontGL::RIGHT:
h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
break;
default:
break;
}
selection_rect.translate(h_delta, v_delta);
}
gl_rect_2d(selection_rect, selection_color);
}
}
@ -2007,6 +2049,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
@ -2116,7 +2159,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons))
{
start = match.getStart();
end = match.getEnd()+1;
@ -2141,7 +2184,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// add icon before url if need
LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
{
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));

View File

@ -321,7 +321,8 @@ public:
parse_highlights,
clip,
clip_partial,
trusted_content;
trusted_content,
always_show_icons;
Optional<S32> v_pad,
h_pad;
@ -369,6 +370,8 @@ public:
virtual void onFocusReceived();
virtual void onFocusLost();
void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
@ -702,6 +705,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipTripleClick;
bool mAlwaysShowIcons;
bool mSkipLinkUnderline;
// support widgets

View File

@ -196,6 +196,7 @@ public:
const LLUUID& getSourceID() const { return mSourceID; }
const LLTextSegmentPtr getPreviousSegment() const;
const LLTextSegmentPtr getLastSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void setShowContextMenu(bool show) { mShowContextMenu = show; }

View File

@ -76,22 +76,6 @@ void LLTextUtil::textboxSetGreyedVal(LLTextBox *txtbox, const LLStyle::Params& n
txtbox->appendText(text.substr(greyed_begin + greyed_len), false, normal_style);
}
const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
{
static const std::string PHONE_SEPARATOR = LLUI::getInstance()->mSettingGroups["config"]->getString("AvalinePhoneSeparator");
static const S32 PHONE_PART_LEN = 2;
static std::string formatted_phone_str;
formatted_phone_str = phone_str;
S32 separator_pos = (S32)(formatted_phone_str.size()) - PHONE_PART_LEN;
for (; separator_pos >= PHONE_PART_LEN; separator_pos -= PHONE_PART_LEN)
{
formatted_phone_str.insert(separator_pos, PHONE_SEPARATOR);
}
return formatted_phone_str;
}
bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted)
{
if (match == 0 || text_base == 0)

View File

@ -58,18 +58,6 @@ namespace LLTextUtil
const std::string& text,
const std::string& greyed);
/**
* Formats passed phone number to be more human readable.
*
* It just divides the number on parts by two digits from right to left. The first left part
* can have 2 or 3 digits, i.e. +44-33-33-44-55-66 or 12-34-56-78-90. Separator is set in
* application settings (AvalinePhoneSeparator)
*
* @param[in] phone_str string with original phone number
* @return reference to string with formatted phone number
*/
const std::string& formatPhoneNumber(const std::string& phone_str);
/**
* Adds icon before url if need.
*

View File

@ -222,6 +222,15 @@ void LLUrlAction::removeFriend(std::string url)
}
}
void LLUrlAction::reportAbuse(std::string url)
{
std::string id_str = getUserID(url);
if (LLUUID::validate(id_str))
{
executeSLURL("secondlife:///app/agent/" + id_str + "/reportAbuse");
}
}
void LLUrlAction::blockObject(std::string url)
{
std::string object_id = getObjectId(url);

View File

@ -82,6 +82,7 @@ public:
static void sendIM(std::string url);
static void addFriend(std::string url);
static void removeFriend(std::string url);
static void reportAbuse(std::string url);
static void blockObject(std::string url);
static void unblockObject(std::string url);

View File

@ -148,6 +148,22 @@ void LLKeyboard::addKeyName(KEY key, const std::string& name)
sNamesToKeys[nameuc] = key;
}
void LLKeyboard::resetKeyDownAndHandle()
{
MASK mask = currentMask(FALSE);
for (S32 i = 0; i < KEY_COUNT; i++)
{
if (mKeyLevel[i])
{
mKeyDown[i] = FALSE;
mKeyLevel[i] = FALSE;
mKeyUp[i] = TRUE;
mCurTranslatedKey = (KEY)i;
mCallbacks->handleTranslatedKeyUp(i, mask);
}
}
}
// BUG this has to be called when an OS dialog is shown, otherwise modifier key state
// is wrong because the keyup event is never received by the main window. JC
void LLKeyboard::resetKeys()

View File

@ -58,7 +58,8 @@ public:
LLKeyboard();
virtual ~LLKeyboard();
void resetKeys();
void resetKeyDownAndHandle();
void resetKeys();
F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; }

View File

@ -495,14 +495,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch);
bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]);
unichar ch;
if (acceptsText &&
!mMarkedTextAllowed &&
!(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow
![(LLAppDelegate*)[NSApp delegate] romanScript] &&
(ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' &&
ch > ' ' &&
ch != NSDeleteCharacter &&
(ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h)
{

View File

@ -100,13 +100,13 @@ const unsigned short *copyFromPBoard()
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
[NSString stringWithFormat:@"%s", fullpath]
[NSString stringWithUTF8String:fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];

View File

@ -1668,7 +1668,7 @@ void LLWindowMacOSX::hideCursor()
void LLWindowMacOSX::showCursor()
{
if(mCursorHidden)
if(mCursorHidden || !isCGCursorVisible())
{
// LL_INFOS() << "showCursor: showing" << LL_ENDL;
mCursorHidden = FALSE;

View File

@ -34,6 +34,7 @@
#include "llplugininstance.h"
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"
#include "llstring.h"
#include "volume_catcher.h"
#include "media_plugin_base.h"
@ -55,7 +56,7 @@ private:
bool init();
void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
void onCustomSchemeURLCallback(std::string url);
void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect);
void onConsoleMessageCallback(std::string message, std::string source, int line);
void onStatusMessageCallback(std::string value);
void onTitleChangeCallback(std::string title);
@ -299,11 +300,18 @@ void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
message.setValue("uri", url);
message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
message.setValue("uri", url);
// indicate if this interaction was from a user click (okay on a SLAPP) or
// via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP)
const std::string nav_type = user_gesture ? "clicked" : "navigated";
message.setValue("nav_type", nav_type);
message.setValueBoolean("is_redirect", is_redirect);
sendMessage(message);
}
@ -592,7 +600,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
// event callbacks from Dullahan
mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
@ -616,9 +624,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
// dir as the executable that loaded it (SLPlugin.exe). The code in
// Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
char cur_dir_str[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
settings.host_process_path = std::string(cur_dir_str);
std::vector<wchar_t> buffer(MAX_PATH + 1);
GetCurrentDirectoryW(MAX_PATH, &buffer[0]);
settings.host_process_path = ll_convert_wide_to_string(&buffer[0]);
#endif
settings.accept_language_list = mHostLanguage;

View File

@ -73,6 +73,7 @@ private:
static void display(void* data, void* id);
/*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */;
void setDurationDirty();
static void eventCallbacks(const libvlc_event_t* event, void* ptr);
@ -93,8 +94,8 @@ private:
bool mIsLooping;
float mCurTime;
float mDuration;
F64 mCurTime;
F64 mDuration;
EStatus mVlcStatus;
};
@ -213,6 +214,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom)
sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
// *virtual*
void MediaPluginLibVLC::setDurationDirty()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
message.setValueReal("current_time", mCurTime);
message.setValueReal("duration", mDuration);
message.setValueReal("current_rate", 1.0f);
sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
@ -233,6 +247,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f;
parent->mVlcStatus = STATUS_PLAYING;
parent->setVolumeVLC();
parent->setDurationDirty();
break;
case libvlc_MediaPlayerPaused:
@ -245,6 +260,8 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerEndReached:
parent->mVlcStatus = STATUS_DONE;
parent->mCurTime = parent->mDuration;
parent->setDurationDirty();
break;
case libvlc_MediaPlayerEncounteredError:
@ -253,6 +270,11 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerTimeChanged:
parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f;
if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer))
{
parent->mVlcStatus = STATUS_PLAYING;
}
parent->setDurationDirty();
break;
case libvlc_MediaPlayerPositionChanged:
@ -260,6 +282,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerLengthChanged:
parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f;
parent->setDurationDirty();
break;
case libvlc_MediaPlayerTitleChanged:
@ -562,7 +585,24 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
mTextureWidth = texture_width;
mTextureHeight = texture_height;
libvlc_time_t time = 1000.0 * mCurTime;
playMedia();
if (mLibVLCMediaPlayer)
{
libvlc_media_player_set_time(mLibVLCMediaPlayer, time);
time = libvlc_media_player_get_time(mLibVLCMediaPlayer);
if (time < 0)
{
// -1 if there is no media
mCurTime = 0;
}
else
{
mCurTime = (F64)time / 1000.0;
}
}
};
};
@ -594,6 +634,13 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
{
if (mLibVLCMediaPlayer)
{
if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer))
{
// stop or vlc will ignore 'play', it will just
// make an MediaPlayerEndReached event even if
// seek was used
libvlc_media_player_stop(mLibVLCMediaPlayer);
}
libvlc_media_player_play(mLibVLCMediaPlayer);
}
}
@ -606,15 +653,32 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
}
else if (message_name == "seek")
{
if (mDuration > 0)
{
F64 normalized_offset = message_in.getValueReal("time") / mDuration;
libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset);
}
if (mLibVLCMediaPlayer)
{
libvlc_time_t time = 1000.0 * message_in.getValueReal("time");
libvlc_media_player_set_time(mLibVLCMediaPlayer, time);
time = libvlc_media_player_get_time(mLibVLCMediaPlayer);
if (time < 0)
{
// -1 if there is no media
mCurTime = 0;
}
else
{
mCurTime = (F64)time / 1000.0;
}
if (!libvlc_media_player_is_playing(mLibVLCMediaPlayer))
{
// if paused, won't trigger update, update now
setDurationDirty();
}
}
}
else if (message_name == "set_loop")
{
mIsLooping = true;
bool loop = message_in.getValueBoolean("loop");
mIsLooping = loop;
}
else if (message_name == "set_volume")
{

View File

@ -234,12 +234,14 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloaterenvironmentadjust.cpp
@ -296,10 +298,12 @@ set(viewer_SOURCE_FILES
llfloaterperformance.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferencesgraphicsadvanced.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@ -332,7 +336,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@ -478,7 +481,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@ -488,8 +490,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
llpanelpick.cpp
llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@ -498,6 +498,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
llpanelprofileclassifieds.cpp
llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@ -659,6 +661,7 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@ -872,12 +875,14 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloaterenvironmentadjust.h
@ -937,10 +942,12 @@ set(viewer_HEADER_FILES
llfloaterperformance.h
llfloaterperms.h
llfloaterpostprocess.h
llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferencesgraphicsadvanced.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@ -973,7 +980,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@ -1109,7 +1115,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@ -1119,8 +1124,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
llpanelpick.h
llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@ -1129,6 +1132,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
llpanelprofileclassifieds.h
llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
@ -1291,6 +1296,7 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h

View File

@ -1 +1 @@
6.6.3
6.6.5

View File

@ -167,10 +167,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
execute_parameters="picks"
is_running_function="Floater.IsOpen"
is_running_parameters="picks"
execute_function="Avatar.TogglePicks"
is_running_function="Avatar.IsPicksTabOpen"
/>
<command name="places"
available_in_toybox="true"

View File

@ -544,17 +544,6 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>AvalinePhoneSeparator</key>
<map>
<key>Comment</key>
<string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>-</string>
</map>
<key>AvatarAxisDeadZone0</key>
<map>
<key>Comment</key>
@ -4758,7 +4747,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
<string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@ -5806,6 +5795,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>DiskCacheVersion</key>
<map>
<key>Comment</key>
<string>Version number of disk cache</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LocalFileSystemBrowsingEnabled</key>
<map>
<key>Comment</key>
@ -15769,6 +15769,17 @@
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>AllowSelectAvatar</key>
<map>
<key>Comment</key>
<string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>WebProfileFloaterRect</key>
<map>

View File

@ -716,6 +716,9 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
if ((getControlFlags() & mask) == mask)
{
// Rotation into both directions should cancel out
// But keep sending controls to simulator,
// it's needed for script based controls
gAgentCamera.setYawKey(0);
}

View File

@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
private:
void onServerRespond(LLAvatarPicks* picks);
private:
/**
* Sets number of Picks.
*/

View File

@ -1450,6 +1450,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
// if one of our coroutines threw an uncaught exception, rethrow it now
LLCoros::instance().rethrow();
}
if (!LLApp::isExiting())
@ -3291,9 +3293,18 @@ LLSD LLAppViewer::getViewerInfo() const
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
if(LLVoiceClient::getInstance()->voiceEnabled())
{
LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
const std::string build_version = version.mBuildVersion;
std::ostringstream version_string;
version_string << version.serverType << " " << version.serverVersion << std::endl;
if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
version.serverVersion.begin()))
{ // Normal case: Show type and build version.
version_string << version.serverType << " " << build_version << std::endl;
}
else
{ // Mismatch: Show both versions.
version_string << version.serverVersion << "/" << build_version << std::endl;
}
info["VOICE_VERSION"] = version_string.str();
}
else
@ -4256,6 +4267,15 @@ U32 LLAppViewer::getTextureCacheVersion()
return TEXTURE_CACHE_VERSION ;
}
//static
U32 LLAppViewer::getDiskCacheVersion()
{
// Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
const U32 DISK_CACHE_VERSION = 1;
return DISK_CACHE_VERSION ;
}
//static
U32 LLAppViewer::getObjectCacheVersion()
{
@ -4285,12 +4305,16 @@ bool LLAppViewer::initCache()
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
bool texture_cache_mismatch = false;
bool remove_vfs_files = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
//texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
remove_vfs_files = true;
}
}
@ -4336,7 +4360,19 @@ bool LLAppViewer::initCache()
if (!read_only)
{
if (mPurgeCache)
if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
{
LLDiskCache::getInstance()->clearCache();
remove_vfs_files = true;
gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion());
}
if (remove_vfs_files)
{
LLDiskCache::getInstance()->removeOldVFSFiles();
}
if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
@ -5418,7 +5454,7 @@ void LLAppViewer::disconnectViewer()
gFloaterView->restoreAll();
}
if (LLSelectMgr::getInstance())
if (LLSelectMgr::instanceExists())
{
LLSelectMgr::getInstance()->deselectAll();
}

View File

@ -130,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@ -153,16 +154,16 @@ public:
void removeMarkerFiles();
void removeDumpDir();
// LLAppViewer testing helpers.
// *NOTE: These will potentially crash the viewer. Only for debugging.
virtual void forceErrorLLError();
virtual void forceErrorBreakpoint();
virtual void forceErrorBadMemoryAccess();
virtual void forceErrorInfiniteLoop();
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
virtual void forceErrorCoroutineCrash();
virtual void forceErrorThreadCrash();
// LLAppViewer testing helpers.
// *NOTE: These will potentially crash the viewer. Only for debugging.
virtual void forceErrorLLError();
virtual void forceErrorBreakpoint();
virtual void forceErrorBadMemoryAccess();
virtual void forceErrorInfiniteLoop();
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
virtual void forceErrorCoroutineCrash();
virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,

View File

@ -48,6 +48,7 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterpay.h"
#include "llfloaterprofile.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
@ -62,11 +63,14 @@
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llpaneloutfitedit.h"
#include "llpanelprofile.h"
#include "llparcel.h"
#include "llrecentpeople.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
#include "llviewernetwork.h" //LLGridManager
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lltrans.h"
#include "llcallingcard.h"
@ -81,6 +85,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
std::string getProfileURL(const std::string& agent_name, bool feed_only)
{
std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
LLSD subs;
subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
subs["AGENT_NAME"] = agent_name;
subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
url = LLWeb::expandURLSubstitutions(url, subs);
LLStringUtil::toLower(url);
return url;
}
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@ -316,57 +333,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
make_ui_sound("UISndStartIM");
}
static const char* get_profile_floater_name(const LLUUID& avatar_id)
{
// Use different floater XML for our profile to be able to save its rect.
return avatar_id == gAgentID ? "my_profile" : "profile";
}
static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
{
std::string url = getProfileURL(av_name.getAccountName());
// PROFILES: open in webkit window
LLFloaterWebContent::Params p;
p.url(url).id(agent_id.asString());
LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
}
// static
void LLAvatarActions::showProfile(const LLUUID& id)
void LLAvatarActions::showProfile(const LLUUID& avatar_id)
{
if (id.notNull())
if (avatar_id.notNull())
{
LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
}
}
// static
void LLAvatarActions::showPicks(const LLUUID& avatar_id)
{
if (avatar_id.notNull())
{
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
if (profilefloater)
{
profilefloater->showPick();
}
}
}
// static
void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
{
if (avatar_id.notNull())
{
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
if (profilefloater)
{
profilefloater->showPick(pick_id);
}
}
}
// static
void LLAvatarActions::createPick()
{
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
LLViewerRegion* region = gAgent.getRegion();
if (profilefloater && region)
{
LLPickData data;
data.pos_global = gAgent.getPositionGlobal();
data.sim_name = region->getName();
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
data.name = parcel->getName();
data.desc = parcel->getDesc();
data.snapshot_id = parcel->getSnapshotID();
data.parcel_id = parcel->getID();
}
else
{
data.name = region->getName();
}
profilefloater->createPick(data);
}
}
// static
bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
{
if (avatar_id.notNull())
{
LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
if (profilefloater)
{
return profilefloater->isPickTabSelected();
}
}
return false;
}
// static
void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
{
if (avatar_id.notNull())
{
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
if (profilefloater)
{
profilefloater->showClassified();
}
}
}
// static
void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
{
if (avatar_id.notNull())
{
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
if (profilefloater)
{
profilefloater->showClassified(classified_id, edit);
}
}
}
// static
void LLAvatarActions::createClassified()
{
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
if (profilefloater)
{
profilefloater->createClassified();
}
}
//static
bool LLAvatarActions::profileVisible(const LLUUID& id)
bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
{
LLSD sd;
sd["id"] = id;
LLFloater* browser = getProfileFloater(id);
return browser && browser->isShown();
sd["id"] = avatar_id;
LLFloater* floater = getProfileFloater(avatar_id);
return floater && floater->isShown();
}
//static
LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
{
LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*>
(LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
return browser;
LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
return floater;
}
//static
void LLAvatarActions::hideProfile(const LLUUID& id)
void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
{
LLSD sd;
sd["id"] = id;
LLFloater* browser = getProfileFloater(id);
if (browser)
sd["id"] = avatar_id;
LLFloater* floater = getProfileFloater(avatar_id);
if (floater)
{
browser->closeFloater();
floater->closeFloater();
}
}
@ -990,7 +1094,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// static
void LLAvatarActions::toggleBlock(const LLUUID& id)
bool LLAvatarActions::toggleBlock(const LLUUID& id)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@ -1000,10 +1104,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
{
LLMuteList::getInstance()->remove(mute);
return false;
}
else
{
LLMuteList::getInstance()->add(mute);
return true;
}
}

View File

@ -38,6 +38,8 @@ class LLInventoryPanel;
class LLFloater;
class LLView;
std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@ -91,13 +93,20 @@ public:
*/
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
/**
* Show avatar profile.
*/
static void showProfile(const LLUUID& id);
static void hideProfile(const LLUUID& id);
static bool profileVisible(const LLUUID& id);
static LLFloater* getProfileFloater(const LLUUID& id);
/**
* Show avatar profile.
*/
static void showProfile(const LLUUID& avatar_id);
static void showPicks(const LLUUID& avatar_id);
static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
static void createPick();
static void showClassifieds(const LLUUID& avatar_id);
static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
static void createClassified();
static void hideProfile(const LLUUID& avatar_id);
static bool profileVisible(const LLUUID& avatar_id);
static bool isPickTabSelected(const LLUUID& avatar_id);
static LLFloater* getProfileFloater(const LLUUID& avatar_id);
/**
* Show avatar on world map.
@ -126,9 +135,10 @@ public:
static void shareWithAvatars(LLView * panel);
/**
* Block/unblock the avatar.
* Block/unblock the avatar by id.
* Returns true if blocked, returns false if unblocked
*/
static void toggleBlock(const LLUUID& id);
static bool toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.

View File

@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/)
}
}
void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name)
{
LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL;
LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
item->setAvatarId(item_id, session_id, true, false);
item->setName(item_name);
item->showLastInteractionTime(mShowLastInteractionTime);
item->showSpeakingIndicator(mShowSpeakingIndicator);
item->setOnline(false);
addItem(item, item_id);
mIDs.push_back(item_id);
sort();
}
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
@ -296,18 +281,10 @@ void LLAvatarList::refresh()
{
// *NOTE: If you change the UI to show a different string,
// be sure to change the filter code below.
if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
{
const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
}
else
{
std::string display_name = getAvatarName(av_name);
addNewItem(buddy_id,
display_name.empty() ? waiting_str : display_name,
LLAvatarTracker::instance().isBuddyOnline(buddy_id));
}
std::string display_name = getAvatarName(av_name);
addNewItem(buddy_id,
display_name.empty() ? waiting_str : display_name,
LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
if ( mContextMenu && !isAvalineItemSelected())
if ( mContextMenu)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
bool LLAvatarList::isAvalineItemSelected()
{
std::vector<LLPanel*> selected_items;
getSelectedItems(selected_items);
std::vector<LLPanel*>::iterator it = selected_items.begin();
for(; it != selected_items.end(); ++it)
{
if (dynamic_cast<LLAvalineListItem*>(*it))
return true;
}
return false;
}
void LLAvatarList::setVisible(BOOL visible)
{
if ( visible == FALSE && mContextMenu )
@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_
}
return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);
}
/************************************************************************/
/* class LLAvalineListItem */
/************************************************************************/
LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false)
, mIsHideNumber(hide_number)
{
// should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
buildFromFile( "panel_avatar_list_item.xml");
}
BOOL LLAvalineListItem::postBuild()
{
BOOL rv = LLAvatarListItem::postBuild();
if (rv)
{
setOnline(true);
showLastInteractionTime(false);
setShowProfileBtn(false);
setShowInfoBtn(false);
mAvatarIcon->setValue("Avaline_Icon");
mAvatarIcon->setToolTip(std::string(""));
}
return rv;
}
// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number
void LLAvalineListItem::setName(const std::string& name)
{
if (mIsHideNumber)
{
static U32 order = 0;
typedef std::map<LLUUID, U32> avaline_callers_nums_t;
static avaline_callers_nums_t mAvalineCallersNums;
llassert(getAvatarId() != LLUUID::null);
const LLUUID &uuid = getAvatarId();
if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end())
{
mAvalineCallersNums[uuid] = ++order;
LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL;
}
LLStringUtil::format_map_t args;
args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]);
std::string hidden_name = LLTrans::getString("AvalineCaller", args);
LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL;
LLAvatarListItem::setAvatarName(hidden_name);
LLAvatarListItem::setAvatarToolTip(hidden_name);
}
else
{
const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
LLAvatarListItem::setAvatarName(formatted_phone);
LLAvatarListItem::setAvatarToolTip(formatted_phone);
}
}

View File

@ -98,7 +98,6 @@ public:
virtual S32 notifyParent(const LLSD& info);
void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
void setShowCompleteName(bool show) { mShowCompleteName = show;};
@ -118,8 +117,6 @@ protected:
private:
bool isAvalineItemSelected();
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@ -189,27 +186,4 @@ protected:
virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
};
/**
* Represents Avaline caller in Avatar list in Voice Control Panel and group chats.
*/
class LLAvalineListItem : public LLAvatarListItem
{
public:
/**
* Constructor
*
* @param hide_number - flag indicating if number should be hidden.
* In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc.
*/
LLAvalineListItem(bool hide_number = true);
/*virtual*/ BOOL postBuild();
/*virtual*/ void setName(const std::string& name);
private:
bool mIsHideNumber;
};
#endif // LL_LLAVATARLIST_H

View File

@ -36,6 +36,7 @@
#include "llstartup.h"
// Linden library includes
#include "llavataractions.h" // for getProfileUrl
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
}
}
void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
// this is the startup state when send_complete_agent_movement() message is sent.
// Before this messages won't work so don't bother trying
if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
{
return;
}
if (avatar_id.isNull())
{
return;
}
// Suppress duplicate requests while waiting for a response from the network
if (isPendingRequest(avatar_id, type))
{
// waiting for a response, don't re-request
return;
}
// indicate we're going to make a request
addPendingRequest(avatar_id, type);
std::vector<std::string> strings;
strings.push_back( avatar_id.asString() );
send_generic_message(method, strings);
std::string cap;
switch (type)
{
case APT_PROPERTIES:
// indicate we're going to make a request
sendAvatarPropertiesRequestMessage(avatar_id);
// can use getRegionCapability("AgentProfile"), but it is heavy
// initAgentProfileCapRequest(avatar_id, cap);
break;
case APT_PICKS:
case APT_GROUPS:
case APT_NOTES:
if (cap.empty())
{
// indicate we're going to make a request
sendGenericRequest(avatar_id, type, method);
}
else
{
initAgentProfileCapRequest(avatar_id, cap);
}
break;
default:
sendGenericRequest(avatar_id, type, method);
break;
}
}
void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
// indicate we're going to make a request
addPendingRequest(avatar_id, type);
std::vector<std::string> strings;
strings.push_back(avatar_id.asString());
send_generic_message(method, strings);
}
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
{
addPendingRequest(avatar_id, APT_PROPERTIES);
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
gAgent.sendReliableMessage();
}
void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
{
addPendingRequest(avatar_id, APT_PROPERTIES);
addPendingRequest(avatar_id, APT_PICKS);
addPendingRequest(avatar_id, APT_GROUPS);
addPendingRequest(avatar_id, APT_NOTES);
LLCoros::instance().launch("requestAgentUserInfoCoro",
boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
}
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
{
// this is the startup state when send_complete_agent_movement() message is sent.
// Before this, the AvatarPropertiesRequest message
// won't work so don't bother trying
if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
{
return;
}
if (isPendingRequest(avatar_id, APT_PROPERTIES))
{
// waiting for a response, don't re-request
return;
}
// indicate we're going to make a request
addPendingRequest(avatar_id, APT_PROPERTIES);
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
msg->nextBlockFast( _PREHASH_AgentData);
msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
gAgent.sendReliableMessage();
sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
}
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
return;
}
LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
// This value is required by sendAvatarPropertiesUpdate method.
//A profile should never be mature. (From the original code)
@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
// static
void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpHeaders::ptr_t httpHeaders;
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setFollowRedirects(true);
std::string finalUrl = cap_url + "/" + agent_id.asString();
LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status
|| !result.has("id")
|| agent_id != result["id"].asUUID())
{
LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
LLAvatarPropertiesProcessor* self = getInstance();
self->removePendingRequest(agent_id, APT_PROPERTIES);
self->removePendingRequest(agent_id, APT_PICKS);
self->removePendingRequest(agent_id, APT_GROUPS);
self->removePendingRequest(agent_id, APT_NOTES);
return;
}
// Avatar Data
LLAvatarData avatar_data;
std::string birth_date;
avatar_data.agent_id = agent_id;
avatar_data.avatar_id = agent_id;
avatar_data.image_id = result["sl_image_id"].asUUID();
avatar_data.fl_image_id = result["fl_image_id"].asUUID();
avatar_data.partner_id = result["partner_id"].asUUID();
avatar_data.about_text = result["sl_about_text"].asString();
avatar_data.fl_about_text = result["fl_about_text"].asString();
avatar_data.born_on = result["member_since"].asDate();
avatar_data.profile_url = getProfileURL(agent_id.asString());
avatar_data.flags = 0;
avatar_data.caption_index = 0;
LLAvatarPropertiesProcessor* self = getInstance();
// Request processed, no longer pending
self->removePendingRequest(agent_id, APT_PROPERTIES);
self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
// Picks
LLSD picks_array = result["picks"];
LLAvatarPicks avatar_picks;
avatar_picks.agent_id = agent_id; // Not in use?
avatar_picks.target_id = agent_id;
for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
{
const LLSD& pick_data = *it;
avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
}
// Request processed, no longer pending
self->removePendingRequest(agent_id, APT_PICKS);
self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
// Groups
LLSD groups_array = result["groups"];
LLAvatarGroups avatar_groups;
avatar_groups.agent_id = agent_id; // Not in use?
avatar_groups.avatar_id = agent_id; // target_id
for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
{
const LLSD& group_info = *it;
LLAvatarGroups::LLGroupData group_data;
group_data.group_powers = 0; // Not in use?
group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
group_data.group_id = group_info["id"].asUUID();
group_data.group_name = group_info["name"].asString();
group_data.group_insignia_id = group_info["image_id"].asUUID();
avatar_groups.group_list.push_back(group_data);
}
self->removePendingRequest(agent_id, APT_GROUPS);
self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
// Notes
LLAvatarNotes avatar_notes;
avatar_notes.agent_id = agent_id;
avatar_notes.target_id = agent_id;
avatar_notes.notes = result["notes"].asString();
// Request processed, no longer pending
self->removePendingRequest(agent_id, APT_NOTES);
self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
}
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
That will suppress the warnings and be compatible with old server versions.
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
*/
LLInterestsData interests_data;
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
LLAvatarPropertiesProcessor* self = getInstance();
// Request processed, no longer pending
self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
{
LLAvatarPicks avatar_picks;
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
{
if(!interests_data)
{
return;
}
LLMessageSystem* msg = gMessageSystem;
msg->newMessage(_PREHASH_AvatarInterestsUpdate);
msg->nextBlockFast( _PREHASH_AgentData);
msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
msg->nextBlockFast( _PREHASH_PropertiesData);
msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
gAgent.sendReliableMessage();
}
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;

View File

@ -56,10 +56,22 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
struct LLInterestsData
{
LLUUID agent_id;
LLUUID avatar_id; //target id
U32 want_to_mask;
std::string want_to_text;
U32 skills_mask;
std::string skills_text;
std::string languages_text;
};
struct LLAvatarData
{
LLUUID agent_id;
@ -223,6 +235,8 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@ -234,6 +248,8 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
@ -252,7 +268,10 @@ public:
protected:
void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);

View File

@ -320,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
// make sure we won't re-report, coro will update timer with correct time later
regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
try
{
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
}
catch (std::bad_alloc&)
{
LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
}
}
}
@ -343,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
// make sure we won't re-request, coro will update timer with correct time later
regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
// First send a request to get the latest data
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
try
{
// First send a request to get the latest data
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
}
catch (std::bad_alloc&)
{
LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
}
}
}

View File

@ -640,6 +640,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
mChangedBuddyIDs.insert(agent_related);
}
}
else

View File

@ -48,6 +48,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@ -118,6 +119,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@ -403,6 +405,48 @@ public:
{
LLAvatarActions::pay(getAvatarId());
}
else if (level == "report_abuse")
{
std::string time_string;
if (mTime > 0) // have frame time
{
time_t current_time = time_corrected();
time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime;
time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ LLTrans::getString("TimeDay") + "]/["
+ LLTrans::getString("TimeYear") + "] ["
+ LLTrans::getString("TimeHour") + "]:["
+ LLTrans::getString("TimeMin") + "]";
LLSD substitution;
substitution["datetime"] = (S32)message_time;
LLStringUtil::format(time_string, substitution);
}
else
{
// From history. This might be empty or not full.
// See LLChatLogParser::parse
time_string = getChild<LLTextBox>("time_box")->getValue().asString();
// Just add current date if not full.
// Should be fine since both times are supposed to be stl
if (!time_string.empty() && time_string.size() < 7)
{
time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ LLTrans::getString("TimeDay") + "]/["
+ LLTrans::getString("TimeYear") + "] " + time_string;
LLSD substitution;
// To avoid adding today's date to yesterday's timestamp,
// use creation time instead of current time
substitution["datetime"] = (S32)mCreationTime;
LLStringUtil::format(time_string, substitution);
}
}
LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText);
}
else if(level == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@ -477,6 +521,10 @@ public:
{
return canModerate(userdata);
}
else if (level == "report_abuse")
{
return gAgentID != mAvatarID;
}
else if (level == "can_ban_member")
{
return canBanGroupMember(getAvatarId());
@ -634,6 +682,12 @@ public:
mSessionID = chat.mSessionID;
mSourceType = chat.mSourceType;
// To be able to report a message, we need a copy of it's text
// and it's easier to store text directly than trying to get
// it from a lltextsegment or chat's mEditor
mText = chat.mText;
mTime = chat.mTime;
//*TODO overly defensive thing, source type should be maintained out there
if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
@ -983,6 +1037,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
std::string mText;
F64 mTime; // IM's frame time
time_t mCreationTime; // Views's time
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;

View File

@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
"can_invite_to_group" == command_name ||
"can_share" == command_name ||
"can_block" == command_name ||
"can_pay" == command_name)
"can_pay" == command_name ||
"report_abuse" == command_name)
{
return is_p2p;
}

View File

@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("map"));
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
items.push_back(std::string("report_abuse"));
items.push_back(std::string("block_unblock"));
items.push_back(std::string("MuteText"));

View File

@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
{
}
void LLDoNotDisturbNotificationStorage::reset()
{
setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
}
void LLDoNotDisturbNotificationStorage::initialize()
{
setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
reset();
getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
}

View File

@ -61,6 +61,7 @@ public:
void loadNotifications();
void updateNotifications();
void removeNotification(const char * name, const LLUUID& id);
void reset();
protected:

View File

@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild()
// by default each time vs restoring the last value
mQualityRadioGroup->setSelectedIndex(0);
return true;
}
void LLFloater360Capture::onOpen(const LLSD& key)
{
// Construct a URL pointing to the first page to load. Although
// we do not use this page for anything (after some significant
// design changes), we retain the code to load the start page
@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild()
// We do an initial capture when the floater is opened, albeit at a 'preview'
// quality level (really low resolution, but really fast)
onCapture360ImagesBtn();
return true;
}
// called when the user choose a quality level using

View File

@ -47,6 +47,7 @@ class LLFloater360Capture:
~LLFloater360Capture();
BOOL postBuild() override;
void onOpen(const LLSD& key) override;
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
void changeInterestListMode(bool send_everything);

View File

@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe()
for(U32 i=0; i<avatar_ids.size(); i++)
{
LLUUID& av = avatar_ids[i];
if(av == gAgent.getID()) continue;
if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue;
LLSD element;
element["id"] = av; // value
LLAvatarName av_name;

View File

@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT
mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
mDummyAvatar->mSpecialRenderMode = 1;
mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
mDummyAvatar->hideSkirt();
// on idle overall apperance update will set skirt to visible, so either
// call early or account for mSpecialRenderMode in updateMeshVisibility
mDummyAvatar->updateOverallAppearance();
mDummyAvatar->hideHair();
mDummyAvatar->hideSkirt();
// stop extraneous animations
mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}

View File

@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
{
LLInspect::onOpen(key);
LLUI::getInstance()->positionViewNearMouse(this);
LLInspect::repositionInspector(key);
}
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()

View File

@ -0,0 +1,71 @@
/**
* @file llfloaterclassified.cpp
* @brief LLFloaterClassified for displaying classifieds.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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 "llfloaterclassified.h"
LLFloaterClassified::LLFloaterClassified(const LLSD& key)
: LLFloater(key)
{
}
LLFloaterClassified::~LLFloaterClassified()
{
}
void LLFloaterClassified::onOpen(const LLSD& key)
{
LLPanel* panel = findChild<LLPanel>("main_panel", true);
if (panel)
{
panel->onOpen(key);
}
if (key.has("classified_name"))
{
setTitle(key["classified_name"].asString());
}
LLFloater::onOpen(key);
}
BOOL LLFloaterClassified::postBuild()
{
return TRUE;
}
bool LLFloaterClassified::matchesKey(const LLSD& key)
{
bool is_mkey_valid = mKey.has("classified_id");
bool is_key_valid = key.has("classified_id");
if (is_mkey_valid && is_key_valid)
{
return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
}
return is_mkey_valid == is_key_valid;
}
// eof

View File

@ -1,59 +1,45 @@
/**
* @file llfloaterwebprofile.h
* @brief Avatar profile floater.
/**
* @file llfloaterclassified.h
* @brief LLFloaterClassified for displaying classifieds.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* Copyright (C) 2022, 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_LLFLOATERWEBPROFILE_H
#define LL_LLFLOATERWEBPROFILE_H
#ifndef LL_LLFLOATERCLASSIFIED_H
#define LL_LLFLOATERCLASSIFIED_H
#include "llfloaterwebcontent.h"
#include "llviewermediaobserver.h"
#include "llfloater.h"
#include <string>
class LLMediaCtrl;
/**
* Displays avatar profile web page.
*/
class LLFloaterWebProfile
: public LLFloaterWebContent
class LLFloaterClassified : public LLFloater
{
LOG_CLASS(LLFloaterWebProfile);
LOG_CLASS(LLFloaterClassified);
public:
typedef LLFloaterWebContent::Params Params;
LLFloaterClassified(const LLSD& key);
virtual ~LLFloaterClassified();
LLFloaterWebProfile(const Params& key);
void onOpen(const LLSD& key) override;
BOOL postBuild() override;
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
static LLFloater* create(const LLSD& key);
private:
void applyPreferredRect();
bool matchesKey(const LLSD& key) override;
};
#endif // LL_LLFLOATERWEBPROFILE_H
#endif // LL_LLFLOATERCLASSIFIED_H

View File

@ -0,0 +1,200 @@
/**
* @file llfloaterdisplayname.cpp
* @author Leyla Farazha
* @brief Implementation of the LLFloaterDisplayName class.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
#include "llfloater.h"
#include "llnotificationsutil.h"
#include "llviewerdisplayname.h"
#include "llnotifications.h"
#include "llfloaterdisplayname.h"
#include "llavatarnamecache.h"
#include "llagent.h"
class LLFloaterDisplayName : public LLFloater
{
public:
LLFloaterDisplayName(const LLSD& key);
virtual ~LLFloaterDisplayName() { }
/*virtual*/ BOOL postBuild();
void onSave();
void onCancel();
/*virtual*/ void onOpen(const LLSD& key);
private:
void onCacheSetName(bool success,
const std::string& reason,
const LLSD& content);
};
LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
LLFloater(key)
{
}
void LLFloaterDisplayName::onOpen(const LLSD& key)
{
getChild<LLUICtrl>("display_name_editor")->clear();
getChild<LLUICtrl>("display_name_confirm")->clear();
LLAvatarName av_name;
LLAvatarNameCache::get(gAgent.getID(), &av_name);
F64 now_secs = LLDate::now().secondsSinceEpoch();
if (now_secs < av_name.mNextUpdate)
{
// ...can't update until some time in the future
F64 next_update_local_secs =
av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
LLDate next_update_local(next_update_local_secs);
// display as "July 18 12:17 PM"
std::string next_update_string =
next_update_local.toHTTPDateString("%B %d %I:%M %p");
getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
getChild<LLUICtrl>("lockout_text")->setVisible(true);
getChild<LLUICtrl>("save_btn")->setEnabled(false);
getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
}
else
{
getChild<LLUICtrl>("lockout_text")->setVisible(false);
getChild<LLUICtrl>("save_btn")->setEnabled(true);
getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
}
}
BOOL LLFloaterDisplayName::postBuild()
{
getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
center();
return TRUE;
}
void LLFloaterDisplayName::onCacheSetName(bool success,
const std::string& reason,
const LLSD& content)
{
if (success)
{
// Inform the user that the change took place, but will take a while
// to percolate.
LLSD args;
args["DISPLAY_NAME"] = content["display_name"];
LLNotificationsUtil::add("SetDisplayNameSuccess", args);
return;
}
// Request failed, notify the user
std::string error_tag = content["error_tag"].asString();
LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
// We might have a localized string for this message
// error_args will usually be empty from the server.
if (!error_tag.empty()
&& LLNotifications::getInstance()->templateExists(error_tag))
{
LLNotificationsUtil::add(error_tag);
return;
}
// The server error might have a localized message for us
std::string lang_code = LLUI::getLanguage();
LLSD error_desc = content["error_description"];
if (error_desc.has( lang_code ))
{
LLSD args;
args["MESSAGE"] = error_desc[lang_code].asString();
LLNotificationsUtil::add("GenericAlert", args);
return;
}
// No specific error, throw a generic one
LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
}
void LLFloaterDisplayName::onCancel()
{
setVisible(false);
}
void LLFloaterDisplayName::onSave()
{
std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
if (display_name_utf8.compare(display_name_confirm))
{
LLNotificationsUtil::add("SetDisplayNameMismatch");
return;
}
const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
{
LLSD args;
args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
return;
}
if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
{
LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
}
else
{
LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
}
setVisible(false);
}
//////////////////////////////////////////////////////////////////////////////
// LLInspectObjectUtil
//////////////////////////////////////////////////////////////////////////////
void LLFloaterDisplayNameUtil::registerFloater()
{
LLFloaterReg::add("display_name", "floater_display_name.xml",
&LLFloaterReg::build<LLFloaterDisplayName>);
}

View File

@ -1,6 +1,5 @@
/**
* @file llpanelme.h
* @brief Side tray "Me" (My Profile) panel
* @file llfloaterdisplayname.h
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
@ -24,27 +23,16 @@
* $/LicenseInfo$
*/
#ifndef LL_LLPANELMEPROFILE_H
#define LL_LLPANELMEPROFILE_H
#ifndef LLFLOATERDISPLAYNAME_H
#define LLFLOATERDISPLAYNAME_H
#include "llpanel.h"
#include "llpanelprofile.h"
/**
* Panel for displaying Agent's Picks and Classifieds panel.
* LLPanelMe allows user to edit his picks and classifieds.
*/
class LLPanelMe : public LLPanelProfile
namespace LLFloaterDisplayNameUtil
{
LOG_CLASS(LLPanelMe);
// Register with LLFloaterReg
void registerFloater();
}
public:
LLPanelMe();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
};
#endif // LL_LLPANELMEPROFILE_H
#endif

View File

@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mObserver = new LLFloaterGestureObserver(this);
LLGestureMgr::instance().addObserver(mObserver);
mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));

View File

@ -45,6 +45,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::pay(userID);
}
else if ("report_abuse" == command)
{
LLAvatarName av_name;
if (LLAvatarNameCache::get(userID, &av_name))
{
LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName());
}
else
{
LLFloaterReporter::showFromAvatar(userID, "not avaliable");
}
}
else if ("block_unblock" == command)
{
LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
}
// Handle all other options
if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
if (("can_invite" == item)
|| ("can_chat_history" == item)
|| ("can_share" == item)
|| ("can_pay" == item)
|| ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;

View File

@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView()
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
if (mRootFolderId.notNull())
if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
{
std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason();
if (reason.empty())
{
text = LLTrans::getString("InventoryMarketplaceConnectionError");
}
else
{
LLSD args;
args["[REASON]"] = reason;
text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args);
}
title = LLTrans::getString("InventoryOutboxErrorTitle");
tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
}
else if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);

View File

@ -156,6 +156,18 @@ void LLFloaterMediaSettings::apply()
}
}
////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onOpen(const LLSD& key)
{
if (mPanelMediaSettingsGeneral)
{
// media is expensive, so only load it when nessesary.
// If we need to preload it, set volume to 0 and any pause
// if applicable, then unpause here
mPanelMediaSettingsGeneral->updateMediaPreview();
}
}
////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose(bool app_quitting)
{

View File

@ -42,6 +42,7 @@ public:
~LLFloaterMediaSettings();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
static LLFloaterMediaSettings* getInstance();

View File

@ -507,6 +507,15 @@ void LLFloaterModelPreview::onClickCalculateBtn()
toggleCalculateButton(false);
mUploadBtn->setEnabled(false);
//disable "simplification" UI
LLPanel* simplification_panel = getChild<LLPanel>("physics simplification");
LLView* child = simplification_panel->getFirstChild();
while (child)
{
child->setEnabled(false);
child = simplification_panel->findNextSibling(child);
}
}
// Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function

View File

@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs

View File

@ -72,7 +72,7 @@ struct LLGiveMoneyInfo
mFloater(floater), mAmount(amount){}
};
typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
typedef std::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
///----------------------------------------------------------------------------
/// Class LLFloaterPay

View File

@ -332,60 +332,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
storeAvatarProperties( pAvatarData );
processProfileProperties( pAvatarData );
mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
mAvatarDataInitialized = true;
getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
}
}
}
void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
{
if (LLStartUp::getStartupState() == STATE_STARTED)
{
mAvatarProperties.avatar_id = pAvatarData->avatar_id;
mAvatarProperties.image_id = pAvatarData->image_id;
mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
mAvatarProperties.about_text = pAvatarData->about_text;
mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
mAvatarProperties.profile_url = pAvatarData->profile_url;
mAvatarProperties.flags = pAvatarData->flags;
mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
mAvatarDataInitialized = true;
}
}
void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
{
getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
}
void LLFloaterPreference::saveAvatarProperties( void )
{
const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
if (allowPublish)
{
mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
}
if ((LLStartUp::getStartupState() == STATE_STARTED)
&& mAvatarDataInitialized
&& (allowPublish != mAllowPublish))
{
std::string cap_url = gAgent.getRegionCapability("AgentProfile");
if (!cap_url.empty())
{
mAllowPublish = allowPublish;
//
// NOTE: We really don't want to send the avatar properties unless we absolutely
// need to so we can avoid the accidental profile reset bug, so, if we're
// logged in, the avatar data has been initialized and we have a state change
// for the "allow publish" flag, then set the flag to its new value and send
// the properties update.
//
// NOTE: The only reason we can not remove this update altogether is because of the
// "allow publish" flag, the last remaining profile setting in the viewer
// that doesn't exist in the web profile.
//
if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
{
mAvatarProperties.allow_publish = allowPublish;
LLCoros::instance().launch("requestAgentUserInfoCoro",
boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
}
}
}
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
}
void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpHeaders::ptr_t httpHeaders;
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setFollowRedirects(true);
std::string finalUrl = cap_url + "/" + gAgentID.asString();
LLSD data;
data["allow_publish"] = allow_publish;
LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
return;
}
LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
}
BOOL LLFloaterPreference::postBuild()
@ -911,7 +910,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
else
{
// Show beep, pop up dialog, etc.
LL_INFOS() << "Can't close preferences!" << LL_ENDL;
LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
}
LLPanelLogin::updateLocationSelectorsVisibility();
@ -1502,13 +1501,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
if (!LLXMLNode::parseFile(filename, root, NULL))
{
LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
return false;
}
if (!root->hasName("labels"))
{
LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
return false;
}
@ -1528,7 +1527,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
}
else
{
LL_WARNS() << filename << " failed to load" << LL_ENDL;
LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
return false;
}
@ -2435,7 +2434,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
LL_WARNS() << "Failed to load " << filename << LL_ENDL;
LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@ -2462,7 +2461,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
LL_WARNS() << "Failed to load " << filename << LL_ENDL;
LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@ -2568,7 +2567,7 @@ void LLPanelPreferenceControls::populateControlTable()
{
// Either unknown mode or MODE_SAVED_SETTINGS
// It doesn't have UI or actual settings yet
LL_WARNS() << "Unimplemented mode" << LL_ENDL;
LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
// Searchable columns were removed, mark searchables for an update
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
@ -2608,7 +2607,7 @@ void LLPanelPreferenceControls::populateControlTable()
}
else
{
LL_WARNS() << "Unimplemented mode" << LL_ENDL;
LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
}
// explicit update to make sure table is ready for llsearchableui
@ -2663,10 +2662,15 @@ void LLPanelPreferenceControls::cancel()
if (mConflictHandler[i].hasUnsavedChanges())
{
mConflictHandler[i].clear();
if (mEditingMode == i)
{
// cancel() can be called either when preferences floater closes
// or when child floater closes (like advanced graphical settings)
// in which case we need to clear and repopulate table
regenerateControls();
}
}
}
pControlsTable->clearRows();
pControlsTable->clearColumns();
}
void LLPanelPreferenceControls::saveSettings()

View File

@ -100,9 +100,8 @@ public:
static void updateShowFavoritesCheckbox(bool val);
void processProperties( void* pData, EAvatarProcessorType type );
void processProfileProperties(const LLAvatarData* pAvatarData );
void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
@ -217,7 +216,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
LLAvatarData mAvatarProperties;
bool mAllowPublish; // Allow showing agent in search
std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);

View File

@ -0,0 +1,170 @@
/**
* @file llfloaterprofile.cpp
* @brief Avatar profile floater.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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 "llfloaterprofile.h"
#include "llagent.h" //gAgent
#include "llnotificationsutil.h"
#include "llpanelavatar.h"
#include "llpanelprofile.h"
static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
LLFloaterProfile::LLFloaterProfile(const LLSD& key)
: LLFloater(key),
mAvatarId(key["id"].asUUID()),
mNameCallbackConnection()
{
mDefaultRectForGroup = false;
}
LLFloaterProfile::~LLFloaterProfile()
{
if (mNameCallbackConnection.connected())
{
mNameCallbackConnection.disconnect();
}
}
void LLFloaterProfile::onOpen(const LLSD& key)
{
mPanelProfile->onOpen(key);
// Update the avatar name.
mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
}
BOOL LLFloaterProfile::postBuild()
{
mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW);
return TRUE;
}
void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
{
if (!app_quitting)
{
if (mPanelProfile->hasUnpublishedClassifieds())
{
LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
}
else if (mPanelProfile->hasUnsavedChanges())
{
LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
}
else
{
closeFloater();
}
}
else
{
closeFloater();
}
}
void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (can_save)
{
// savable content
if (option == 0) // Save
{
mPanelProfile->commitUnsavedChanges();
closeFloater();
}
if (option == 1) // Discard
{
closeFloater();
}
// else cancel
}
else
{
// classifieds
if (option == 0) // Ok
{
closeFloater();
}
// else cancel
}
}
void LLFloaterProfile::createPick(const LLPickData &data)
{
mPanelProfile->createPick(data);
}
void LLFloaterProfile::showPick(const LLUUID& pick_id)
{
mPanelProfile->showPick(pick_id);
}
bool LLFloaterProfile::isPickTabSelected()
{
return mPanelProfile->isPickTabSelected();
}
void LLFloaterProfile::refreshName()
{
if (!mNameCallbackConnection.connected())
{
mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
}
LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
if (panel)
{
panel->refreshName();
}
}
void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
{
mPanelProfile->showClassified(classified_id, edit);
}
void LLFloaterProfile::createClassified()
{
mPanelProfile->createClassified();
}
void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
{
mNameCallbackConnection.disconnect();
setTitle(av_name.getCompleteName());
}
// eof

View File

@ -0,0 +1,66 @@
/**
* @file llfloaterprofile.h
* @brief Avatar profile floater.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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_LLFLOATERPROFILE_H
#define LL_LLFLOATERPROFILE_H
#include "llavatarnamecache.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloater.h"
class LLPanelProfile;
class LLFloaterProfile : public LLFloater
{
LOG_CLASS(LLFloaterProfile);
public:
LLFloaterProfile(const LLSD& key);
virtual ~LLFloaterProfile();
BOOL postBuild() override;
void onOpen(const LLSD& key) override;
void onClickCloseBtn(bool app_quitting = false) override;
void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
void createPick(const LLPickData &data);
void showPick(const LLUUID& pick_id = LLUUID::null);
bool isPickTabSelected();
void refreshName();
void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
void createClassified();
private:
LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
LLPanelProfile* mPanelProfile;
LLUUID mAvatarId;
};
#endif // LL_LLFLOATERPROFILE_H

View File

@ -0,0 +1,223 @@
/**
* @file llfloaterprofiletexture.cpp
* @brief LLFloaterProfileTexture class implementation
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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 "llfloaterprofiletexture.h"
#include "llbutton.h"
#include "llfloaterreg.h"
#include "llpreview.h" // fors constants
#include "lltrans.h"
#include "llviewercontrol.h"
#include "lltextureview.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
: LLFloater(LLSD())
, mUpdateDimensions(TRUE)
, mLastHeight(0)
, mLastWidth(0)
, mImage(NULL)
, mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
, mOwnerHandle(owner->getHandle())
{
buildFromFile("floater_profile_texture.xml");
}
LLFloaterProfileTexture::~LLFloaterProfileTexture()
{
if (mImage.notNull())
{
mImage->setBoostLevel(mImageOldBoostLevel);
mImage = NULL;
}
}
// virtual
BOOL LLFloaterProfileTexture::postBuild()
{
mProfileIcon = getChild<LLIconCtrl>("profile_pic");
mCloseButton = getChild<LLButton>("close_btn");
mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
return TRUE;
}
// virtual
void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLFloater::reshape(width, height, called_from_parent);
}
// It takes a while until we get height and width information.
// When we receive it, reshape the window accordingly.
void LLFloaterProfileTexture::updateDimensions()
{
if (mImage.isNull())
{
return;
}
if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
{
return;
}
S32 img_width = mImage->getFullWidth();
S32 img_height = mImage->getFullHeight();
if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
|| mLastWidth != img_width
|| mLastHeight != img_height)
{
mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
// Asset has been fully loaded
mUpdateDimensions = TRUE;
}
mLastHeight = img_height;
mLastWidth = img_width;
// Reshape the floater only when required
if (mUpdateDimensions)
{
mUpdateDimensions = FALSE;
LLRect old_floater_rect = getRect();
LLRect old_image_rect = mProfileIcon->getRect();
S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
S32 biggest_dim = llmax(width, height);
if (biggest_dim > MAX_DIMENTIONS)
{
F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
width *= scale_down;
height *= scale_down;
}
//reshape floater
reshape(width, height);
gFloaterView->adjustToFitScreen(this, FALSE);
}
}
void LLFloaterProfileTexture::draw()
{
// drawFrustum
LLView *owner = mOwnerHandle.get();
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, owner);
LLFloater::draw();
}
void LLFloaterProfileTexture::onOpen(const LLSD& key)
{
mCloseButton->setFocus(true);
}
void LLFloaterProfileTexture::resetAsset()
{
mProfileIcon->setValue("Generic_Person_Large");
mImageID = LLUUID::null;
if (mImage.notNull())
{
mImage->setBoostLevel(mImageOldBoostLevel);
mImage = NULL;
}
}
void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
{
if (mImageID != image_id)
{
if (mImage.notNull())
{
mImage->setBoostLevel(mImageOldBoostLevel);
mImage = NULL;
}
}
else
{
return;
}
mProfileIcon->setValue(image_id);
mImageID = image_id;
mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
mImageOldBoostLevel = mImage->getBoostLevel();
if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
{
mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
}
else
{
mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
}
mUpdateDimensions = TRUE;
updateDimensions();
}
// static
void LLFloaterProfileTexture::onTextureLoaded(
BOOL success,
LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* aux_src,
S32 discard_level,
BOOL final,
void* userdata)
{
LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
if (!handle->isDead())
{
LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
if (floater && success)
{
floater->mUpdateDimensions = TRUE;
floater->updateDimensions();
}
}
if (final || !success)
{
delete handle;
}
}

View File

@ -0,0 +1,81 @@
/**
* @file llfloaterprofiletexture.h
* @brief LLFloaterProfileTexture class definition
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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_LLFLOATERPROFILETEXTURE_H
#define LL_LLFLOATERPROFILETEXTURE_H
#include "llfloater.h"
#include "llviewertexture.h"
class LLButton;
class LLImageRaw;
class LLIconCtrl;
class LLFloaterProfileTexture : public LLFloater
{
public:
LLFloaterProfileTexture(LLView* owner);
~LLFloaterProfileTexture();
void draw() override;
void onOpen(const LLSD& key) override;
void resetAsset();
void loadAsset(const LLUUID &image_id);
static void onTextureLoaded(
BOOL success,
LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* aux_src,
S32 discard_level,
BOOL final,
void* userdata);
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
protected:
BOOL postBuild() override;
private:
void updateDimensions();
LLUUID mImageID;
LLPointer<LLViewerFetchedTexture> mImage;
S32 mImageOldBoostLevel;
S32 mAssetStatus;
F32 mContextConeOpacity;
S32 mLastHeight;
S32 mLastWidth;
BOOL mUpdateDimensions;
LLHandle<LLView> mOwnerHandle;
LLIconCtrl* mProfileIcon;
LLButton* mCloseButton;
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
};
#endif // LL_LLFLOATERPROFILETEXTURE_H

View File

@ -1322,6 +1322,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
{
static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
{
std::string buffer;
@ -1343,17 +1344,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
return FALSE;
}
if (width > 512 || height > 512)
if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
{
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_SIZE_X"] = width;
args["TEXTURE_SIZE_Y"] = height;
args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainSize", args);
return FALSE;
@ -3683,7 +3686,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin
if (!search_string.empty())
{
listCtrl->setSearchColumn(0); // name column
listCtrl->selectItemByPrefix(search_string, FALSE);
listCtrl->searchItems(search_string, false, true);
}
else
{

View File

@ -54,6 +54,7 @@
#include "llbutton.h"
#include "llfloaterreg.h"
#include "lltexturectrl.h"
#include "lltexteditor.h"
#include "llscrolllistctrl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
mMCDList.clear();
delete mResourceDatap;
}
@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin
show(avatar_id, avatar_name);
}
// static
void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description)
{
show(avatar_id, avatar_name);
LLStringUtil::format_map_t args;
args["[MSG_TIME]"] = time;
args["[MSG_DESCRIPTION]"] = description;
LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
if (self)
{
std::string description = self->getString("chat_report_format", args);
self->getChild<LLUICtrl>("details_edit")->setValue(description);
}
}
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
getChild<LLUICtrl>("object_name")->setValue(object_name);
@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)
mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
// {
// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
// if (self)
// {
// self->getChild<LLUICtrl>("details_edit")->setValue(description);
// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
// self->mMCDList.clear();
// if (mcd)
// {
// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
// }
// }
// }
// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
// {
// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
// if (self)
// {
// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
// if (text)
// {
// text->insertText(description);
// }
// if (mcd)
// {
// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
// }
// }
// }

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