Ansariel 2022-09-15 20:37:16 +02:00
commit 2507bc6137
275 changed files with 3166 additions and 4428 deletions

View File

@ -952,9 +952,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2653c3627fd8687ff9e003425fd14834</string>
<string>012aaadd1c40d430866bebda2e60bfae</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/100136/882323/dullahan-1.12.3.202205202122_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-572002.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -964,9 +964,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b4003772562a5dd40bc112eec7cba5f5</string>
<string>ff1c56b7a28c689442f6439421bb32f5</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/100149/882391/dullahan-1.12.3.202205202205_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-572002.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -976,9 +976,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d9030d7a7390b3bda7de2adcc27e535a</string>
<string>bbfe23d7f211865b81b291884949a887</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/100148/882385/dullahan-1.12.3.202205202202_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-572002.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
@ -997,7 +997,7 @@
</map>
</map>
<key>version</key>
<string>1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
<string>1.12.3.202205202205_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
</map>
<key>expat</key>
<map>
@ -2906,9 +2906,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>
@ -2930,9 +2930,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>
@ -2942,16 +2942,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

@ -93,8 +93,8 @@ if(WINDOWS)
set(release_files ${release_files} growl++.dll growl.dll )
if (FMODSTUDIO)
set(debug_files ${debug_files} fmodL.dll)
set(release_files ${release_files} fmod.dll)
set(debug_files ${debug_files} fmodL.dll)
set(release_files ${release_files} fmod.dll)
endif (FMODSTUDIO)
if (OPENAL)

View File

@ -289,7 +289,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;
}
@ -854,7 +854,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
{
@ -1321,7 +1322,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),
@ -1470,7 +1471,7 @@ void LLAudioSource::update()
void LLAudioSource::updatePriority()
{
if (isAmbient())
if (isForcedPriority())
{
mPriority = 1.f;
}

View File

@ -310,8 +310,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; }
@ -379,7 +379,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

@ -662,9 +662,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

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

@ -523,7 +523,8 @@ FMOD_RESULT LLAudioStreamManagerFMODSTUDIO::getOpenState(FMOD_OPENSTATE& state,
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
Check_FMOD_Error(mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES), "FMOD::System::setStreamBufferSize");
if (Check_FMOD_Error(mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES), "FMOD::System::setStreamBufferSize"))
return;
FMOD_ADVANCEDSETTINGS settings;
memset(&settings, 0, sizeof(settings));
settings.cbSize = sizeof(settings);
@ -542,7 +543,7 @@ bool LLStreamingAudio_FMODSTUDIO::releaseDeadStreams()
{
LL_INFOS() << "Closed dead stream" << LL_ENDL;
delete streamp;
mDeadStreams.erase(iter++);
iter = mDeadStreams.erase(iter);
}
else
{

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;
@ -870,7 +878,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;
@ -1364,12 +1375,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);
@ -1382,7 +1394,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)
{
@ -1442,12 +1454,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);
}
@ -1458,7 +1470,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>
@ -213,6 +214,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;
@ -301,11 +318,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))
{
@ -320,7 +337,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)
@ -349,11 +365,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
}
}
@ -363,8 +387,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]);
}
}
};
@ -798,6 +897,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]);
}
}
std::string getCPUFeatureDescription() const
@ -856,6 +980,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

@ -608,6 +608,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();
@ -620,6 +625,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
@ -637,6 +671,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;
@ -647,6 +706,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.
@ -656,6 +720,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

@ -481,6 +481,38 @@ void LLDiskCache::clearCache()
LL_INFOS() << "Cleared cache " << mCacheDir << LL_ENDL;
}
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

@ -153,6 +153,8 @@ class LLDiskCache :
*/
const std::string getCacheInfo();
void removeOldVFSFiles();
// <FS:Ansariel> Better asset cache size control
void setMaxSizeBytes(uintmax_t size) { mMaxSizeBytes = size; }

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

@ -701,7 +701,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++)
@ -6785,13 +6785,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;
}
}
@ -6977,7 +6983,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

@ -197,6 +197,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

@ -1563,6 +1563,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

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

@ -858,7 +858,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)
@ -1588,6 +1588,28 @@ 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)
{
// <FS> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//res += mJointNames[i].size(); // actual size, not capacity
res += mJointNames[i].mName.size(); // actual size, not capacity
// </FS>
}
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);
@ -1694,6 +1716,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

@ -52,6 +52,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;
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
@ -119,6 +120,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
@ -129,6 +138,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
bool hasHullList() const;
U32 sizeBytes() const;
void merge(const Decomposition* rhs);

View File

@ -1256,7 +1256,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++)
@ -1276,7 +1281,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++)
@ -1299,7 +1309,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

@ -830,17 +830,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();
@ -1531,7 +1527,7 @@ void LLFloater::cleanupHandles()
LLFloater* floaterp = dependent_it->get();
if (!floaterp)
{
mDependents.erase(dependent_it++);
dependent_it = mDependents.erase(dependent_it);
}
else
{

View File

@ -2164,6 +2164,12 @@ void LLLineEditor::draw()
ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
// <FS:Zi> IME - International input compositing, i.e. for Japanese / Chinese text input
#if LL_SDL2
static LLUICachedControl<S32> sdl2_ime_default_vertical_offset("SDL2IMEDefaultVerticalOffset");
ime_pos.mY += sdl2_ime_default_vertical_offset;
#endif
// </FS:Zi>
getWindow()->setLanguageTextInput( ime_pos );
}
}
@ -2313,12 +2319,21 @@ void LLLineEditor::setFocus( BOOL new_state )
if (new_state)
{
// <FS:Zi> IME - International input compositing, i.e. for Japanese / Chinese text input
#if LL_SDL2
// Linux/SDL2 doesn't currently allow to disable IME, so we remove the restrictions on
// password entry fields and prevalidated input fields. Otherwise those fields would
// be completely inaccessible.
getWindow()->allowLanguageTextInput(this, true);
#else
// </FS:Zi>
// Allow Language Text Input only when this LineEditor has
// no prevalidate function attached. This criterion works
// fine on 1.15.0.2, since all prevalidate func reject any
// non-ASCII characters. I'm not sure on future versions,
// however.
getWindow()->allowLanguageTextInput(this, mPrevalidateFunc == NULL);
#endif // <FS:Zi>
}
}
@ -2498,7 +2513,16 @@ void LLLineEditor::updateAllowingLanguageInput()
// test app, no window available
return;
}
// <FS:Zi> IME - International input compositing, i.e. for Japanese / Chinese text input
#if LL_SDL2
// Linux/SDL2 doesn't currently allow to disable IME, so we remove the restrictions on
// password entry fields and prevalidated input fields. Otherwise those fields would
// be completely inaccessible.
if (hasFocus() && !mReadOnly)
#else
// </FS:Zi>
if (hasFocus() && !mReadOnly && !mDrawAsterixes && mPrevalidateFunc == NULL)
#endif // <FS:Zi>
{
window->allowLanguageTextInput(this, TRUE);
}

View File

@ -3990,15 +3990,15 @@ LLTearOffMenu::~LLTearOffMenu()
void LLTearOffMenu::draw()
{
mMenu->setBackgroundVisible(isBackgroundOpaque());
// <FS:Ansariel> FIRE-31823: Torn off menu doesn't update enabled/visible state
// <FS:Ansariel> FIRE-31823: Do it before reshaping - needsArrange can change visbility status of items!
mMenu->needsArrange();
if (getRect().getHeight() != mTargetHeight)
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
//mMenu->needsArrange(); // <FS:Ansariel> FIRE-31823: Torn off menu doesn't update enabled/visible state
}
//mMenu->needsArrange(); // <FS:Ansariel> FIRE-31823: Do it before reshaping - needsArrange can change visbility status of items!
LLFloater::draw();
}

View File

@ -1522,6 +1522,90 @@ BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool pre
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;
}
// <FS:Ansariel> Fix for FS-specific people list (radar)
if (isFiltered(item))
{
continue;
}
// </FS:Ansariel> Fix for FS-specific people list (radar)
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;
}
// <FS:Ansariel> Allow selection by substring match
BOOL LLScrollListCtrl::selectItemBySubstring(const std::string& target, BOOL case_sensitive)
{
@ -2120,6 +2204,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));
@ -2224,6 +2309,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

@ -281,6 +281,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.
@ -348,6 +356,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();
@ -498,6 +507,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

@ -731,6 +731,12 @@ void LLTextBase::drawCursor()
ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
// <FS:Zi> IME - International input compositing, i.e. for Japanese / Chinese text input
#if LL_SDL2
static LLUICachedControl<S32> sdl2_ime_default_vertical_offset("SDL2IMEDefaultVerticalOffset");
ime_pos.mY += sdl2_ime_default_vertical_offset;
#endif
// </FS:Zi>
getWindow()->setLanguageTextInput( ime_pos );
}
}
@ -2245,6 +2251,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));

View File

@ -206,6 +206,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

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

View File

@ -39,6 +39,7 @@
#include "llstring.h"
#include "lldir.h"
#include "llfindlocale.h"
#include "llframetimer.h"
#ifdef LL_GLIB
#include <glib.h>
@ -390,6 +391,10 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
mIsMinimized = -1;
mFSAASamples = fsaa_samples;
// IME - International input compositing, i.e. for Japanese / Chinese text input
// Preeditor means here the actual XUI input field currently in use
mPreeditor = nullptr;
#if LL_X11
mSDL_XWindowID = None;
mSDL_Display = NULL;
@ -654,6 +659,10 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
SDL_SetHint( SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0" );
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
// IME - International input compositing, i.e. for Japanese / Chinese text input
// Request the IME interface to show over-the-top compositing while typing
SDL_SetHint( SDL_HINT_IME_INTERNAL_EDITING, "1");
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 )
{
LL_INFOS() << "sdl_init() failed! " << SDL_GetError() << LL_ENDL;
@ -1758,6 +1767,7 @@ void LLWindowSDL::gatherInput()
static int rightClick = 0;
static Uint32 lastLeftDown = 0;
static Uint32 lastRightDown = 0;
static U64 previousTextinputTime = 0;
SDL_Event event;
// Handle all outstanding SDL events
@ -1796,9 +1806,10 @@ void LLWindowSDL::gatherInput()
else
handleUnicodeUTF16(key, mKeyModifiers);
}
previousTextinputTime = LLFrameTimer::getTotalTime();
break;
}
case SDL_KEYDOWN:
mKeyVirtualKey = event.key.keysym.sym;
mKeyModifiers = event.key.keysym.mod;
@ -1810,6 +1821,19 @@ void LLWindowSDL::gatherInput()
mKeyVirtualKey = SDLK_RETURN;
}
if (mKeyVirtualKey == SDLK_RETURN)
{
// block spurious enter key events that break up IME entered lines in teh wrong places
U64 eventTimeDiff = LLFrameTimer::getTotalTime() - previousTextinputTime;
previousTextinputTime = 0;
if (eventTimeDiff < 20000)
{
LL_INFOS() << "SDL_KEYDOWN(SDLK_RETURN) event came too fast after SDL_TEXTINPUT, blocked - Time: " << eventTimeDiff << LL_ENDL;
break;
}
}
gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers );
// <FS:ND> Slightly hacky :| To make the viewer honor enter (eg to accept form input) we've to not only send handleKeyDown but also send a
@ -2646,4 +2670,51 @@ void LLWindowSDL::toggleVSync(bool enable_vsync)
}
// </FS:Zi>
// IME - International input compositing, i.e. for Japanese / Chinese text input
// Put the IME window at the right place (near current text input).
// Point coordinates should be the top of the current text line.
void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position)
{
LLCoordWindow win_pos;
convertCoords( position, &win_pos );
SDL_Rect r;
r.x = win_pos.mX;
r.y = win_pos.mY;
r.w = 500;
r.h = 16;
SDL_SetTextInputRect(&r);
}
// IME - International input compositing, i.e. for Japanese / Chinese text input
void LLWindowSDL::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
{
if (preeditor != mPreeditor && !b)
{
// This condition may occur with a call to
// setEnabled(BOOL) from LLTextEditor or LLLineEditor
// when the control is not focused.
// We need to silently ignore the case so that
// the language input status of the focused control
// is not disturbed.
return;
}
// Take care of old and new preeditors.
if (preeditor != mPreeditor || !b)
{
mPreeditor = (b ? preeditor : nullptr);
}
if (b)
{
SDL_StartTextInput();
}
else
{
SDL_StopTextInput();
}
}
#endif // LL_SDL

View File

@ -128,6 +128,9 @@ public:
/*virtual*/ void *getPlatformWindow();
/*virtual*/ void bringToFront();
/*virtual*/ void allowLanguageTextInput(LLPreeditor* preeditor, BOOL b);
/*virtual*/ void setLanguageTextInput(const LLCoordGL& pos);
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ void openFile(const std::string& file_name);
@ -201,6 +204,7 @@ protected:
SDL_Surface* mSurface;
SDL_GLContext mContext;
SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT];
LLPreeditor* mPreeditor;
std::string mWindowTitle;
double mOriginalAspectRatio;

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"
@ -617,9 +618,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

@ -1 +1 @@
6.6.4
6.6.5

View File

@ -2100,17 +2100,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>
@ -6962,11 +6951,11 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;sid=[SESSION_ID]</string>
<string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;sid=[SESSION_ID]</string>
<key>Backup</key>
<integer>0</integer>
<!-- LL, possibly privacy leaking search string
<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>
@ -8200,6 +8189,17 @@
<key>Backup</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>
@ -20164,6 +20164,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<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>
@ -26214,5 +26225,38 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>SDL2IMEDefaultVerticalOffset</key>
<map>
<key>Comment</key>
<string>Default vertical offset to apply to the international input method editor for Japanese, Chinese, etc.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>18</integer>
</map>
<key>SDL2IMEChatHistoryVerticalOffset</key>
<map>
<key>Comment</key>
<string>Chat History: Vertical offset to apply to the international input method editor for Japanese, Chinese, etc.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>14</integer>
</map>
<key>SDL2IMEMediaVerticalOffset</key>
<map>
<key>Comment</key>
<string>Media: Vertical offset to apply to the international input method editor for Japanese, Chinese, etc.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>-4</integer>
</map>
</map>
</llsd>

View File

@ -16,7 +16,7 @@
* 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
* You should have received a copy of the GNU Lesser General PublicatarActions::pay(getAvat
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
@ -50,6 +50,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llstylemap.h"
#include "llslurl.h"
@ -68,6 +69,10 @@
#include "llviewermenu.h"
#include "llviewernetwork.h"
#if LL_SDL2
#include "llwindow.h"
#endif
#include "fscommon.h"
#include "llchatentry.h"
#include "llfocusmgr.h"
@ -137,6 +142,7 @@ public:
mType(CHAT_TYPE_NORMAL), // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports
mFrom(),
mSessionID(),
mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@ -452,6 +458,48 @@ public:
{
LLUrlAction::copyURLToClipboard(LLSLURL("agent", getAvatarId(), "about").getSLURLString());
}
else if (param == "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 (param == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@ -537,7 +585,11 @@ public:
{
return canModerate(userdata);
}
// [RLVa:KB] - @pay
else if (param == "report_abuse")
{
return gAgentID != mAvatarID;
}
// [RLVa:KB] - @pay
else if (param == "can_pay")
{
return RlvActions::canPayAvatar(getAvatarId());
@ -676,6 +728,12 @@ public:
mType = chat.mChatType; // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports
mNameStyleParams = style_params;
// 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()))
{
@ -1158,7 +1216,10 @@ protected:
EChatType mType; // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports
std::string mFrom;
LLUUID mSessionID;
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
std::string mText;
F64 mTime; // IM's frame time
time_t mCreationTime; // Views's time
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
bool mShowContextMenu;
bool mShowInfoCtrl;
// [/RLVa:KB]
@ -1211,6 +1272,50 @@ FSChatHistory::~FSChatHistory()
this->clear();
}
void FSChatHistory::updateChatInputLine()
{
if(!mChatInputLine)
{
// get our focus root
LLUICtrl* focusRoot=findRootMostFocusRoot();
if(focusRoot)
{
// focus on the next item that is a text input control
focusRoot->focusNextItem(true);
// remember the control's pointer if it really is a LLLineEditor
mChatInputLine = dynamic_cast<LLChatEntry*>(gFocusMgr.getKeyboardFocus());
}
}
}
#if LL_SDL2
void FSChatHistory::setFocus(BOOL b)
{
LLTextEditor::setFocus(b);
// IME - International input compositing, i.e. for Japanese / Chinese text input
updateChatInputLine();
if (b && mChatInputLine)
{
// Make sure the IME is in the right place, on top of the input line
LLRect screen_pos = mChatInputLine->calcScreenRect();
LLCoordGL ime_pos(screen_pos.mLeft, screen_pos.mBottom + gSavedSettings.getS32("SDL2IMEChatHistoryVerticalOffset"));
// shift by a few pixels so the IME doesn't pop to the left side when the input
// field is very close to the left edge
ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]) + 5;
ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
getWindow()->setLanguageTextInput(ime_pos);
}
// this floater is not an LLPreeditor but we are only interested in the pointer anyway
// so hopefully we will get away with this
getWindow()->allowLanguageTextInput((LLPreeditor*) this, true);
}
#endif
void FSChatHistory::initFromParams(const FSChatHistory::Params& p)
{
// initialize the LLTextEditor base class first ... -Zi
@ -1795,19 +1900,8 @@ BOOL FSChatHistory::handleUnicodeCharHere(llwchar uni_char)
return LLTextEditor::handleUnicodeCharHere(uni_char);
}
// we don't know which is our chat input line yet
if(!mChatInputLine)
{
// get our focus root
LLUICtrl* focusRoot=findRootMostFocusRoot();
if(focusRoot)
{
// focus on the next item that is a text input control
focusRoot->focusNextItem(true);
// remember the control's pointer if it really is a LLLineEditor
mChatInputLine = dynamic_cast<LLChatEntry*>(gFocusMgr.getKeyboardFocus());
}
}
// we might not know which is our chat input line yet
updateChatInputLine();
// do we know our chat input line now?
if(mChatInputLine)

View File

@ -96,8 +96,17 @@ class FSChatHistory : public LLTextEditor // <FS:Zi> FIRE-8600: TAB out of chat
*/
LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args);
// try to fill in mChatInputLine
void updateChatInputLine();
public:
~FSChatHistory();
#if LL_SDL2
// IME - International input compositing, i.e. for Japanese / Chinese text input
/* virtual */ void setFocus(BOOL b);
#endif
LLSD getValue() const;
void initFromParams(const Params&);

View File

@ -407,9 +407,6 @@ void FSFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
if (!session) return;
// no need to spawn chiclets for participants in P2P calls called through Avaline
if (session->isP2P() && session->isOtherParticipantAvaline()) return;
FSFloaterIM::onNewIMReceived(session_id);
}

View File

@ -59,46 +59,6 @@
#include "rlvcommon.h"
static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids);
void reshape_floater(FSFloaterVoiceControls* floater, S32 delta_height);
class LLNonAvatarCaller : public LLAvatarListItem
{
public:
LLNonAvatarCaller() : LLAvatarListItem(false)
{
}
BOOL 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;
}
void setName(const std::string& name)
{
const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
LLAvatarListItem::setAvatarName(formatted_phone);
LLAvatarListItem::setAvatarToolTip(formatted_phone);
}
void setSpeakerId(const LLUUID& id) { mSpeakingIndicator->setSpeakerId(id); }
};
static void* create_non_avatar_caller(void*)
{
return new LLNonAvatarCaller;
}
LLVoiceChannel* FSFloaterVoiceControls::sCurrentVoiceChannel = NULL;
@ -107,7 +67,6 @@ FSFloaterVoiceControls::FSFloaterVoiceControls(const LLSD& key)
, mSpeakerManager(NULL)
, mParticipants(NULL)
, mAvatarList(NULL)
, mNonAvatarCaller(NULL)
, mVoiceType(VC_LOCAL_CHAT)
, mAgentPanel(NULL)
, mSpeakingIndicator(NULL)
@ -120,7 +79,6 @@ FSFloaterVoiceControls::FSFloaterVoiceControls(const LLSD& key)
static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&FSFloaterVoiceControls::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);
LLVoiceClient::instance().addObserver(this);
LLTransientFloaterMgr::getInstance()->addControlView(this);
@ -156,9 +114,6 @@ BOOL FSFloaterVoiceControls::postBuild()
childSetAction("leave_call_btn", boost::bind(&FSFloaterVoiceControls::leaveCall, this));
mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller");
mNonAvatarCaller->setVisible(FALSE);
mVolumeSlider = findChild<LLSliderCtrl>("volume_slider");
mMuteButton = findChild<LLButton>("mute_btn");
@ -283,11 +238,6 @@ void FSFloaterVoiceControls::updateSession()
case IM_NOTHING_SPECIAL:
case IM_SESSION_P2P_INVITE:
mVoiceType = VC_PEER_TO_PEER;
if (!im_session->mOtherParticipantIsAvatar)
{
mVoiceType = VC_PEER_TO_PEER_AVALINE;
}
break;
case IM_SESSION_CONFERENCE_START:
case IM_SESSION_GROUP_START:
@ -298,7 +248,7 @@ void FSFloaterVoiceControls::updateSession()
}
else
{
mVoiceType = VC_AD_HOC_CHAT;
mVoiceType = VC_AD_HOC_CHAT;
}
break;
default:
@ -348,37 +298,24 @@ void FSFloaterVoiceControls::updateSession()
void FSFloaterVoiceControls::refreshParticipantList()
{
bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType;
if (non_avatar_caller)
{
LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSpeakerManager->getSessionID());
mNonAvatarCaller->setSpeakerId(session->mOtherParticipantID);
mNonAvatarCaller->setName(session->mName);
}
// Ansariel: Changed for RLVa @shownearby
//mNonAvatarCaller->setVisible(non_avatar_caller);
//mAvatarList->setVisible(!non_avatar_caller);
updateListVisibility();
if (!non_avatar_caller)
{
llassert(mParticipants == NULL); // check for possible memory leak
mParticipants = new FSParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
mParticipants->setValidateSpeakerCallback(boost::bind(&FSFloaterVoiceControls::validateSpeaker, this, _1));
const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
mParticipants->setSortOrder(FSParticipantList::EParticipantSortOrder(speaker_sort_order));
llassert(mParticipants == NULL); // check for possible memory leak
mParticipants = new FSParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
mParticipants->setValidateSpeakerCallback(boost::bind(&FSFloaterVoiceControls::validateSpeaker, this, _1));
const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
mParticipants->setSortOrder(FSParticipantList::EParticipantSortOrder(speaker_sort_order));
if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager)
{
mAvatarList->setNoItemsCommentText(getString("no_one_near"));
}
// we have to made delayed initialization of voice state of participant list.
// it will be performed after first LLAvatarList refreshing in the onAvatarListRefreshed().
mInitParticipantsVoiceState = true;
if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager)
{
mAvatarList->setNoItemsCommentText(getString("no_one_near"));
}
// we have to made delayed initialization of voice state of participant list.
// it will be performed after first LLAvatarList refreshing in the onAvatarListRefreshed().
mInitParticipantsVoiceState = true;
}
void FSFloaterVoiceControls::onAvatarListRefreshed()
@ -494,15 +431,8 @@ void FSFloaterVoiceControls::updateTitle()
title = getString("title_nearby");
break;
case VC_PEER_TO_PEER:
case VC_PEER_TO_PEER_AVALINE:
{
title = voice_channel->getSessionName();
if (VC_PEER_TO_PEER_AVALINE == mVoiceType)
{
title = LLTextUtil::formatPhoneNumber(title);
}
LLStringUtil::format_map_t args;
args["[NAME]"] = title;
title = getString("title_peer_2_peer", args);
@ -896,7 +826,6 @@ void FSFloaterVoiceControls::reset(const LLVoiceChannel::EState& new_state)
// Ansariel: Changed for RLVa @shownearby
//mAvatarList->setVisible(TRUE);
//mNonAvatarCaller->setVisible(FALSE);
updateListVisibility();
mSpeakerManager = NULL;
@ -913,26 +842,12 @@ void FSFloaterVoiceControls::updateListVisibility()
if (mIsRlvShowNearbyRestricted && mVoiceType == VC_LOCAL_CHAT)
{
mAvatarList->setVisible(FALSE);
mNonAvatarCaller->setVisible(FALSE);
mRlvRestrictedText->setVisible(TRUE);
}
else
{
mAvatarList->setVisible(TRUE);
mRlvRestrictedText->setVisible(FALSE);
if (mParticipants)
{
// Case coming from refreshParticipantList
bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType;
mNonAvatarCaller->setVisible(non_avatar_caller);
mAvatarList->setVisible(!non_avatar_caller);
}
else
{
// Case coming from reset()
mAvatarList->setVisible(TRUE);
mNonAvatarCaller->setVisible(FALSE);
}
}
}
//EOF

View File

@ -38,7 +38,6 @@ class FSParticipantList;
class LLAvatarList;
class LLAvatarListItem;
class LLAvatarName;
class LLNonAvatarCaller;
class LLOutputMonitorCtrl;
class LLSpeakerMgr;
class LLSpeakersDelayActionsStorage;
@ -92,8 +91,7 @@ private:
VC_GROUP_CHAT,
VC_AD_HOC_CHAT,
VC_PEER_TO_PEER,
VC_PEER_TO_PEER_AVALINE
}EVoiceControls;
} EVoiceControls;
typedef enum e_speaker_state
{
@ -258,7 +256,6 @@ private:
LLSpeakerMgr* mSpeakerManager;
FSParticipantList* mParticipants;
LLAvatarList* mAvatarList;
LLNonAvatarCaller* mNonAvatarCaller;
EVoiceControls mVoiceType;
LLPanel* mAgentPanel;
LLOutputMonitorCtrl* mSpeakingIndicator;

View File

@ -59,146 +59,6 @@ static void update_speaker_indicator(const LLAvatarList* const avatar_list, cons
}
}
// See EXT-4301.
/**
* class LLAvalineUpdater - observe the list of voice participants in session and check
* presence of Avaline Callers among them.
*
* LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation:
* - whether Avaline caller presence among participants;
* - whether watched Avaline caller still exists in voice channel.
* Both validations have callbacks which will notify subscriber if any of event occur.
*
* @see findAvalineCaller()
* @see checkIfAvalineCallersExist()
*/
class LLAvalineUpdater : public LLVoiceClientParticipantObserver
{
public:
typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t;
LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb)
: mAvalineFoundCallback(found_cb)
, mAvalineRemovedCallback(removed_cb)
{
LLVoiceClient::getInstance()->addObserver(this);
}
~LLAvalineUpdater()
{
if (LLVoiceClient::instanceExists())
{
LLVoiceClient::getInstance()->removeObserver(this);
}
}
/**
* Adds UUID of Avaline caller to watch.
*
* @see checkIfAvalineCallersExist().
*/
void watchAvalineCaller(const LLUUID& avaline_caller_id)
{
mAvalineCallers.insert(avaline_caller_id);
}
void onParticipantsChanged()
{
uuid_set_t participant_uuids;
LLVoiceClient::getInstance()->getParticipantList(participant_uuids);
// check whether Avaline caller exists among voice participants
// and notify Participant List
findAvalineCaller(participant_uuids);
// check whether watched Avaline callers still present among voice participant
// and remove if absents.
checkIfAvalineCallersExist(participant_uuids);
}
private:
typedef std::set<LLUUID> uuid_set_t;
/**
* Finds Avaline callers among voice participants and calls mAvalineFoundCallback.
*
* When Avatar is in group call with Avaline caller and then ends call Avaline caller stays
* in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again
* Avaline caller is added to voice channel AFTER Avatar is connected to group call.
* But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information
* if a speaker is Avaline caller.
*
* In this case this speaker is created as avatar and will be recreated when it appears in
* Avatar's Voice session.
*
* @see FSParticipantList::onAvalineCallerFound()
*/
void findAvalineCaller(const uuid_set_t& participant_uuids)
{
uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end();
for(; it != it_end; ++it)
{
const LLUUID& participant_id = *it;
if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id))
{
LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL;
if (mAvalineFoundCallback)
{
mAvalineFoundCallback(participant_id);
}
}
}
}
/**
* Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback.
*
* The problem is when Avaline caller ends a call it is removed from Voice Client session but
* still exists in LLSpeakerMgr. Server does not send such information.
* This method implements a HUCK to notify subscribers that watched Avaline callers by class
* are not anymore in the call.
*
* @see FSParticipantList::onAvalineCallerRemoved()
*/
void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids)
{
uuid_set_t::iterator it = mAvalineCallers.begin();
uuid_set_t::const_iterator participants_it_end = participant_uuids.end();
while (it != mAvalineCallers.end())
{
const LLUUID participant_id = *it;
LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL;
bool not_found = participant_uuids.find(participant_id) == participants_it_end;
if (not_found)
{
LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL;
// notify Participant List
if (mAvalineRemovedCallback)
{
mAvalineRemovedCallback(participant_id);
}
// remove from the watch list
mAvalineCallers.erase(it++);
}
else
{
++it;
}
}
}
process_avaline_callback_t mAvalineFoundCallback;
process_avaline_callback_t mAvalineRemovedCallback;
uuid_set_t mAvalineCallers;
};
FSParticipantList::FSParticipantList(LLSpeakerMgr* data_source,
LLAvatarList* avatar_list,
bool use_context_menu/* = true*/,
@ -211,10 +71,6 @@ FSParticipantList::FSParticipantList(LLSpeakerMgr* data_source,
mValidateSpeakerCallback(NULL),
mConvType(CONV_UNKNOWN)
{
mAvalineUpdater = new LLAvalineUpdater(boost::bind(&FSParticipantList::onAvalineCallerFound, this, _1),
boost::bind(&FSParticipantList::onAvalineCallerRemoved, this, _1));
mSpeakerAddListener = new SpeakerAddListener(*this);
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
@ -316,8 +172,6 @@ FSParticipantList::~FSParticipantList()
mAvatarList->setContextMenu(NULL);
mAvatarList->setComparator(NULL);
delete mAvalineUpdater;
}
void FSParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
@ -425,55 +279,6 @@ void FSParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
}
}
/*
Seems this method is not necessary after onAvalineCallerRemoved was implemented;
It does nothing because list item is always created with correct class type for Avaline caller.
For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client
session.
This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call.
Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself.
Asked in EXT-4301.
*/
void FSParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
{
LLPanel* item = mAvatarList->getItemByValue(participant_id);
if (NULL == item)
{
LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL;
return;
}
if (typeid(*item) == typeid(LLAvalineListItem))
{
LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL;
// item representing an Avaline caller has a correct type already.
return;
}
LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL;
// remove UUID from LLAvatarList::mIDs to be able add it again.
uuid_vec_t& ids = mAvatarList->getIDs();
uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id);
ids.erase(pos);
// remove item directly
mAvatarList->removeItem(item);
// re-add avaline caller with a correct class instance.
addAvatarIDExceptAgent(participant_id);
}
void FSParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
{
LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL;
mSpeakerMgr->removeAvalineSpeaker(participant_id);
}
void FSParticipantList::setSortOrder(EParticipantSortOrder order)
{
const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
@ -631,12 +436,7 @@ void FSParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
mAvatarList->getIDs().push_back(avatar_id);
mAvatarList->setDirty();
}
else
{
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
mAvalineUpdater->watchAvalineCaller(avatar_id);
}
adjustParticipant(avatar_id);
}

View File

@ -36,7 +36,6 @@
class LLSpeakerMgr;
class LLAvatarList;
class LLUICtrl;
class LLAvalineUpdater;
class FSParticipantList
{
@ -260,9 +259,6 @@ private:
void onAvatarListDoubleClicked(LLUICtrl* ctrl);
void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
void onAvalineCallerFound(const LLUUID& participant_id);
void onAvalineCallerRemoved(const LLUUID& participant_id);
/**
* Adjusts passed participant to work properly.
*
@ -301,7 +297,6 @@ private:
LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
validate_speaker_callback_t mValidateSpeakerCallback;
LLAvalineUpdater* mAvalineUpdater;
EConversationType mConvType;
};

View File

@ -1712,6 +1712,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();
}
}// <FS:Beq> ensure we have the entire top scope of frame covered (close input event and coro "idle")
@ -3969,9 +3971,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
@ -5059,6 +5070,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()
{
@ -5091,12 +5111,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;
}
}
@ -5166,7 +5190,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();
@ -6336,10 +6372,7 @@ void LLAppViewer::disconnectViewer()
}
// <FS:Ansariel>
// <FS:Ansariel> Wrong instance check
//if (LLSelectMgr::getInstance())
if (LLSelectMgr::instanceExists())
// </FS:Ansariel
{
LLSelectMgr::getInstance()->deselectAll();
}
@ -6449,11 +6482,13 @@ void LLAppViewer::forceErrorDriverCrash()
glDeleteTextures(1, NULL);
}
void LLAppViewer::forceErrorCoroutineCrash()
{
LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
}
// <FS:Ansariel> Wrongly merged back in by LL
//void LLAppViewer::forceErrorCoroutineCrash()
//{
// LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
// LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
//}
// </FS:Ansariel>
void LLAppViewer::forceErrorThreadCrash()
{

View File

@ -130,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@ -150,16 +151,17 @@ 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();
// <FS:Ansariel> Wrongly merged back in by LL
//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

@ -358,21 +358,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
//////////////////////////////////////////////////////////////////////////
@ -416,24 +401,17 @@ 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
{
// <FS:AO> Always show usernames on avatar lists
// <FS:Ansa> The passed name is not used as of 21-01-2014
//std::string display_name = getAvatarName(av_name);
//addNewItem(buddy_id,
// display_name.empty() ? waiting_str : display_name,
// LLAvatarTracker::instance().isBuddyOnline(buddy_id));
addNewItem(buddy_id,
av_name.getCompleteName(),
LLAvatarTracker::instance().isBuddyOnline(buddy_id));
// </FS:AO>
}
// <FS:AO> Always show usernames on avatar lists
// <FS:Ansa> The passed name is not used as of 21-01-2014
//std::string display_name = getAvatarName(av_name);
//addNewItem(buddy_id,
// display_name.empty() ? waiting_str : display_name,
// LLAvatarTracker::instance().isBuddyOnline(buddy_id));
addNewItem(buddy_id,
av_name.getCompleteName(),
LLAvatarTracker::instance().isBuddyOnline(buddy_id));
// </FS:AO>
modified = true;
nadded++;
}
@ -620,9 +598,9 @@ 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)
// [RLVa:KB] - Checked: 2010-06-04 (RLVa-1.2.2a) | Modified: RLVa-1.2.0d
if ( (mContextMenu && !isAvalineItemSelected()) && ((!mRlvCheckShowNames) || (!RlvActions::hasBehaviour(RLV_BHVR_SHOWNAMES))) )
if (mContextMenu && ((!mRlvCheckShowNames) || (!RlvActions::hasBehaviour(RLV_BHVR_SHOWNAMES))) )
// [/RLVa:KB]
{
uuid_vec_t selected_uuids;
@ -683,21 +661,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 )
@ -823,63 +786,3 @@ bool LLAvatarItemUserNameComparator::doCompare(const LLAvatarListItem* avatar_it
return name1 < name2;
}
// </FS:Ansariel>
/************************************************************************/
/* 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

@ -122,7 +122,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;};
@ -142,8 +141,6 @@ protected:
private:
bool isAvalineItemSelected();
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@ -238,27 +235,4 @@ protected:
};
// </FS:Ansariel>
/**
* 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

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

@ -50,6 +50,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@ -132,6 +133,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@ -417,6 +419,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);
@ -491,6 +535,10 @@ public:
{
return canModerate(userdata);
}
else if (level == "report_abuse")
{
return gAgentID != mAvatarID;
}
// [RLVa:KB] - @pay
else if (level == "can_pay")
{
@ -658,6 +706,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()))
{
@ -1040,6 +1094,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
std::string mText;
F64 mTime; // IM's frame time
time_t mCreationTime; // Views's time
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
bool mShowContextMenu;
bool mShowInfoCtrl;

View File

@ -92,9 +92,6 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
if (!session) return;
// no need to spawn chiclets for participants in P2P calls called through Avaline
if (session->isP2P() && session->isOtherParticipantAvaline()) return;
if (getChicletPanel()->findChiclet<LLChiclet>(session_id)) return;
LLIMChiclet* chiclet = createIMChiclet(session_id);

View File

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

@ -184,6 +184,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

@ -115,6 +115,11 @@ BOOL LLFloater360Capture::postBuild()
// <FS:Ansariel> UX/UI has no clue what the users actually want!
//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
@ -155,8 +160,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

@ -116,6 +116,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@ -432,7 +433,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

@ -1490,7 +1490,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 );
@ -1578,6 +1583,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}

View File

@ -46,6 +46,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@ -1246,6 +1247,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);
@ -1511,10 +1524,13 @@ 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)
// [RLVa:KB] - @pay
if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item))
// || ("can_pay" == item)
// [/RLVa:KB]
|| ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;

View File

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

@ -589,6 +589,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

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

@ -4400,10 +4400,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

@ -1506,6 +1506,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;
@ -1527,20 +1528,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;
}
// <FS:Ansariel> Allow terrain textures up to 1024x1024 pixels
// as in Phoenix (FIRE-2319)
//if (width > 512 || height > 512)
if (width > 1024 || height > 1024)
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;
@ -3920,7 +3920,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"
@ -253,9 +254,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
mMCDList.clear();
delete mResourceDatap;
}
@ -675,6 +673,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);
@ -1056,36 +1071,3 @@ void LLFloaterReporter::onUpdateScreenshot()
doAfterInterval(boost::bind(&LLFloaterReporter::takeNewSnapshot,this, true), gSavedSettings.getF32("AbuseReportScreenshotDelay"));
}
// </FS:Ansariel>
// 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));
// }
// }
// }

View File

@ -93,6 +93,7 @@ public:
static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null);
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description);
static void showFromExperience(const LLUUID& experience_id);
static void onClickSend (void *userdata);
@ -101,8 +102,6 @@ public:
void onClickSelectAbuser ();
static void closePickTool (void *userdata);
static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);
static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
@ -117,10 +116,8 @@ private:
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null);
void takeScreenshot(bool use_prev_screenshot = false);
void sendReportViaCaps(std::string url);
void uploadImage();
bool validateReport();
void setReporterID();
LLSD gatherReport();
void sendReportViaLegacy(const LLSD & report);
void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
@ -149,7 +146,6 @@ private:
BOOL mPicking;
LLVector3 mPosition;
BOOL mCopyrightWarningSeen;
std::list<LLMeanCollisionData*> mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
boost::signals2::connection mAvatarNameCacheConnection;

View File

@ -60,10 +60,10 @@ public:
const size_t parts = tokens.size();
// get the (optional) category for the search
std::string category;
std::string collection;
if (parts > 0)
{
category = tokens[0].asString();
collection = tokens[0].asString();
}
// get the (optional) search string
@ -75,7 +75,7 @@ public:
// create the LLSD arguments for the search floater
LLFloaterSearch::Params p;
p.search.category = category;
p.search.collection = collection;
p.search.query = LLURI::unescape(search_text);
// open the search floater and perform the requested search
@ -86,8 +86,9 @@ public:
LLSearchHandler gSearchHandler;
LLFloaterSearch::SearchQuery::SearchQuery()
: category("category", ""),
query("query")
: category("category", ""),
collection("collection", ""),
query("query")
{}
LLFloaterSearch::LLFloaterSearch(const Params& key) :
@ -96,16 +97,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) :
{
// declare a map that transforms a category name into
// the URL suffix that is used to search that category
mCategoryPaths = LLSD::emptyMap();
mCategoryPaths["all"] = "search";
mCategoryPaths["people"] = "search/people";
mCategoryPaths["places"] = "search/places";
mCategoryPaths["events"] = "search/events";
mCategoryPaths["groups"] = "search/groups";
mCategoryPaths["wiki"] = "search/wiki";
mCategoryPaths["land"] = "land";
mCategoryPaths["destinations"] = "destinations";
mCategoryPaths["classifieds"] = "classifieds";
mSearchType.insert("standard");
mSearchType.insert("land");
mSearchType.insert("classified");
mCollectionType.insert("events");
mCollectionType.insert("destinations");
mCollectionType.insert("places");
mCollectionType.insert("groups");
mCollectionType.insert("people");
}
BOOL LLFloaterSearch::postBuild()
@ -173,31 +174,49 @@ void LLFloaterSearch::search(const SearchQuery &p)
// work out the subdir to use based on the requested category
LLSD subs;
if (mCategoryPaths.has(p.category))
if (mSearchType.find(p.category) != mSearchType.end())
{
subs["CATEGORY"] = mCategoryPaths[p.category].asString();
subs["TYPE"] = p.category;
}
else
{
subs["CATEGORY"] = mCategoryPaths["all"].asString();
subs["TYPE"] = "standard";
}
// add the search query string
subs["QUERY"] = LLURI::escape(p.query);
subs["COLLECTION"] = "";
if (subs["TYPE"] == "standard")
{
if (mCollectionType.find(p.collection) != mCollectionType.end())
{
subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection);
}
else
{
std::string collection_args("");
for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
{
collection_args += "&collection_chosen=" + std::string(*it);
}
subs["COLLECTION"] = collection_args;
}
}
// add the user's preferred maturity (can be changed via prefs)
std::string maturity;
if (gAgent.prefersAdult())
{
maturity = "42"; // PG,Mature,Adult
maturity = "gma"; // PG,Mature,Adult
}
else if (gAgent.prefersMature())
{
maturity = "21"; // PG,Mature
maturity = "gm"; // PG,Mature
}
else
{
maturity = "13"; // PG
maturity = "g"; // PG
}
subs["MATURITY"] = maturity;

View File

@ -49,6 +49,7 @@ public:
struct SearchQuery : public LLInitParam::Block<SearchQuery>
{
Optional<std::string> category;
Optional<std::string> collection;
Optional<std::string> query;
SearchQuery();
@ -84,7 +85,8 @@ public:
private:
/*virtual*/ BOOL postBuild();
LLSD mCategoryPaths;
std::set<std::string> mSearchType;
std::set<std::string> mCollectionType;
U8 mSearchGodLevel;
};

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,6 @@ class LLRadioGroup;
class LLSlider;
class LLTabContainer;
class LLTextBox;
class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@ -104,11 +103,6 @@ public:
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
void onClickBtnDeleteMedia();
void onClickBtnAddMedia();
void onClickBtnEditMedia();
void clearMediaSettings();
bool selectedMediaEditable();
void updateLandImpacts();
static void setGridMode(S32 mode);
@ -120,13 +114,6 @@ public:
private:
void refresh();
void refreshMedia();
void getMediaState();
void updateMediaSettings();
void navigateToTitleMedia( const std::string url ); // navigate if changed
void updateMediaTitle();
static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
@ -218,9 +205,6 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
LLMediaCtrl *mTitleMedia;
bool mNeedMediaTitle;
private:
BOOL mDirty;
BOOL mHasSelection;
@ -231,10 +215,6 @@ private:
S32 mExpandedHeight;
std::map<std::string, std::string> mStatusText;
protected:
LLSD mMediaSettings;
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;

View File

@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
else
{
LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
if(panel_face)
{
panel_face->setMediaType(mime_type);
panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
}
}
getChildView("loading_label")->setVisible( false);
closeFloater();

View File

@ -1342,7 +1342,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLCtrlListInterface *list = mListFriendCombo;
if (list)
if (list && list->getSelectedValue().asString() != "None")
{
list->selectByValue( "None" );
}

View File

@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders()
/************************************************************************/
/* Private Methods */
/************************************************************************/
const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const
{
if (parent_id.isNull())
{
return LLUUID::null;
}
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(parent_id, cats, items);
if (!cats || !items || cats->size() == 0)
{
// call failed
return LLUUID::null;
}
if (cats->size() > 1)
{
const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id);
if (friendFolder)
{
LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL;
}
}
for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin();
iter != cats->end();
++iter)
{
const LLInventoryCategory* category = (*iter);
if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD)
{
return category->getUUID();
}
}
return LLUUID::null;
}
// Inventorry ->
// Calling Cards - >
// Friends - > (the only expected folder)
// All (the only expected folder)
const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
{
const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
std::string friendFolderName = get_friend_folder_name();
return findChildFolderUUID(callingCardsFolderID, friendFolderName);
return findFirstCallingCardSubfolder(callingCardsFolderID);
}
const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
{
LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
std::string friendAllSubfolderName = get_friend_all_subfolder_name();
return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName);
return findFirstCallingCardSubfolder(friendFolderUUID);
}
const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const

View File

@ -121,6 +121,7 @@ public: // <FS:Ansariel> Needed to check in LLOpenTaskOffer
private: // <FS:Ansariel> Needed to check in LLOpenTaskOffer
const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const;
const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const;
const LLUUID& findFriendFolderUUIDImpl() const;
const LLUUID& findFriendAllSubfolderUUIDImpl() const;
const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);

View File

@ -185,7 +185,7 @@ private:
std::set<LLUUID> mLoadingAssets;
// LLEventHost interface
boost::shared_ptr<LLGestureListener> mListener;
std::shared_ptr<LLGestureListener> mListener;
};
#endif

View File

@ -240,7 +240,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
void LLGroupActions::search()
{
// <FS:Ansariel> Open groups search panel instead of invoking presumed failed websearch
//LLFloaterReg::showInstance("search");
//LLFloaterReg::showInstance("search", LLSD().with("collection", "groups"));
LLFloaterReg::showInstance("search", LLSD().with("tab", "groups"));
// </FS:Ansariel>
}

View File

@ -371,7 +371,7 @@ void LLHUDText::updateVisibility()
if (!mSourceObject)
{
LL_WARNS_ONCE() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL;
// Beacons
mVisible = TRUE;
if (mOnHUDAttachment)
{

View File

@ -673,7 +673,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false),
mStartedAsIMCall(voice),
mIsDNDsend(false),
@ -685,13 +684,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
{
mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
// check if it was AVALINE call
if (!mOtherParticipantIsAvatar)
{
mSessionType = AVALINE_SESSION;
}
}
else
{
@ -792,9 +784,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
switch(mSessionType)
{
case AVALINE_SESSION:
// no text notifications
break;
case P2P_SESSION:
LLAvatarNameCache::get(mOtherParticipantID, &av_name);
other_avatar_name = av_name.getUserName();
@ -1055,11 +1044,6 @@ bool LLIMModel::LLIMSession::isGroupChat()
return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID, TRUE));
}
bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
{
return !mOtherParticipantIsAvatar;
}
LLUUID LLIMModel::LLIMSession::generateOutgoingAdHocHash() const
{
LLUUID hash = LLUUID::null;
@ -2076,7 +2060,6 @@ LLIMMgr::onConfirmForceCloseError(
LLCallDialogManager::LLCallDialogManager():
mPreviousSessionlName(""),
mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION),
mCurrentSessionlName(""),
mSession(NULL),
mOldState(LLVoiceChannel::STATE_READY)
@ -2107,12 +2090,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
return;
}
if (mSession)
{
// store previous session type to process Avaline calls in dialogs
mPreviousSessionType = mSession->mSessionType;
}
mSession = session;
@ -2138,7 +2115,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@ -2174,7 +2150,6 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = new_state;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@ -2191,8 +2166,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
break;
case LLVoiceChannel::STATE_HUNG_UP:
// this state is coming before session is changed, so, put it into payload map
mCallDialogPayload["old_session_type"] = mSession->mSessionType;
// this state is coming before session is changed
break;
case LLVoiceChannel::STATE_CONNECTED :
@ -2312,7 +2286,6 @@ void LLCallDialog::onOpen(const LLSD& key)
void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
{
// *NOTE: 12/28/2009: check avaline calls: LLVoiceClient::isParticipantAvatar returns false for them
bool participant_is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
bool is_group = participant_is_avatar && gAgent.isInGroup(session_id, TRUE);
@ -2333,8 +2306,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
else
{
avatar_icon->setValue("Avaline_Icon");
avatar_icon->setToolTip(std::string(""));
LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL;
group_icon->setValue(session_id);
}
}
@ -2378,13 +2351,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
// tell the user which voice channel they are leaving
if (!mPayload["old_channel_name"].asString().empty())
{
bool was_avaline_call = LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["old_session_type"].asInteger();
std::string old_caller_name = mPayload["old_channel_name"].asString();
if (was_avaline_call)
{
old_caller_name = LLTextUtil::formatPhoneNumber(old_caller_name);
}
getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name);
show_oldchannel = true;
@ -2397,10 +2364,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)
if (!mPayload["disconnected_channel_name"].asString().empty())
{
std::string channel_name = mPayload["disconnected_channel_name"].asString();
if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger())
{
channel_name = LLTextUtil::formatPhoneNumber(channel_name);
}
getChild<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
@ -2416,16 +2379,11 @@ void LLOutgoingCallDialog::show(const LLSD& key)
std::string callee_name = mPayload["session_name"].asString();
LLUUID session_id = mPayload["session_id"].asUUID();
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
if (callee_name == "anonymous")
if (callee_name == "anonymous") // obsolete? Likely was part of avaline support
{
callee_name = getString("anonymous");
}
else if (!is_avatar)
{
callee_name = LLTextUtil::formatPhoneNumber(callee_name);
}
LLSD callee_id = mPayload["other_user_id"];
// Beautification: Since you know who you called, just show display name
@ -2625,18 +2583,11 @@ BOOL LLIncomingCallDialog::postBuild()
call_type = getString(notify_box_type);
}
// check to see if this is an Avaline call
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
if (caller_name == "anonymous")
if (caller_name == "anonymous") // obsolete? Likely was part of avaline support
{
caller_name = getString("anonymous");
setCallerName(caller_name, caller_name, call_type);
}
else if (!is_avatar)
{
caller_name = LLTextUtil::formatPhoneNumber(caller_name);
setCallerName(caller_name, caller_name, call_type);
}
else
{
// Get the full name information
@ -2656,7 +2607,7 @@ BOOL LLIncomingCallDialog::postBuild()
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
// starting notification's timer for P2P and AVALINE invitations
// starting notification's timer for P2P invitations
mLifetimeTimer.start();
}
else
@ -2665,7 +2616,7 @@ BOOL LLIncomingCallDialog::postBuild()
}
//it's not possible to connect to existing Ad-Hoc/Group chat through incoming ad-hoc call
//and no IM for avaline
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
setCanDrag(FALSE);

View File

@ -72,7 +72,6 @@ public:
P2P_SESSION,
GROUP_SESSION,
ADHOC_SESSION,
AVALINE_SESSION,
NONE_SESSION,
} SType;
@ -101,12 +100,10 @@ public:
bool isAdHoc();
bool isP2P();
bool isGroupChat();
bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;}
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
LLUUID generateOutgoingAdHocHash() const;
@ -151,7 +148,6 @@ public:
bool mCallBackEnabled;
bool mTextIMPossible;
bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
//if IM session is created for a voice call
@ -569,7 +565,6 @@ private:
protected:
std::string mPreviousSessionlName;
LLIMModel::LLIMSession::SType mPreviousSessionType;
std::string mCurrentSessionlName;
LLIMModel::LLIMSession* mSession;
LLVoiceChannel::EState mOldState;

View File

@ -1233,7 +1233,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
LLInventoryModel::cat_array_t categories;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE);
if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4);
LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20);
if (categories.size() >= max_count
|| depth > (max_depth + 1))
{
disabled_items.push_back(std::string("New Folder"));
}

View File

@ -151,15 +151,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
///----------------------------------------------------------------------------
/// Class LLInventoryValidationInfo
///----------------------------------------------------------------------------
LLInventoryValidationInfo::LLInventoryValidationInfo():
mFatalErrorCount(0),
mWarningCount(0),
mLoopCount(0),
mOrphanedCount(0),
mInitialized(false),
mFatalNoRootFolder(false),
mFatalNoLibraryRootFolder(false),
mFatalQADebugMode(false)
LLInventoryValidationInfo::LLInventoryValidationInfo()
{
}
@ -181,7 +173,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v)
void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
{
sd["fatal_error_count"] = mFatalErrorCount;
sd["warning_count"] = mWarningCount;
sd["loop_count"] = mLoopCount;
sd["orphaned_count"] = mOrphanedCount;
sd["initialized"] = mInitialized;
@ -189,6 +180,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
sd["fatal_no_root_folder"] = mFatalNoRootFolder;
sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder;
sd["fatal_qa_debug_mode"] = mFatalQADebugMode;
sd["warning_count"] = mWarningCount;
if (mWarningCount>0)
{
sd["warnings"] = LLSD::emptyArray();
for (auto const& it : mWarnings)
{
S32 val =LLSD::Integer(it.second);
if (val>0)
{
sd["warnings"][it.first] = val;
}
}
}
if (mMissingRequiredSystemFolders.size()>0)
{
sd["missing_system_folders"] = LLSD::emptyArray();
@ -368,13 +373,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
return NULL;
}
LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
if (!object)
{
LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
return ANSCESTOR_MISSING;
return ANCESTOR_MISSING;
}
std::set<LLUUID> object_ids{ object_id }; // loop protection
@ -384,19 +389,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co
if (object_ids.find(parent_id) != object_ids.end())
{
LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
return ANSCESTOR_LOOP;
return ANCESTOR_LOOP;
}
object_ids.insert(parent_id);
LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
return ANSCESTOR_MISSING;
return ANCESTOR_MISSING;
}
object = parent_object;
}
result = object->getUUID();
return ANSCESTOR_OK;
return ANCESTOR_OK;
}
// <FS:Beq> [OPENSIM] FIRE-31674 Exclude suitcase and descendents from validation when in OpenSim
#ifdef OPENSIM
@ -609,9 +614,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E
LLViewerInventoryCategory* cat = getCategory(*it);
changeCategoryParent(cat, main_id, TRUE);
}
// Purge the emptied folder
removeCategory(folder_id);
// Note that this might be a system folder, don't validate removability
LLViewerInventoryCategory* cat = getCategory(folder_id);
if (cat)
{
const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
if (trash_id.notNull())
{
changeCategoryParent(cat, trash_id, TRUE);
}
}
remove_inventory_category(folder_id, NULL);
}
}
@ -4435,9 +4449,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
S32 fatal_errs = 0;
S32 warnings = 0;
S32 loops = 0;
S32 orphaned = 0;
S32 warning_count= 0;
S32 loop_count = 0;
S32 orphaned_count = 0;
if (getRootFolderID().isNull())
{
@ -4464,7 +4478,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// ParentChild should be one larger because of the special entry for null uuid.
LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size()
<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL;
warnings++;
validation_info->mWarnings["category_map_size"]++;
warning_count++;
}
S32 cat_lock = 0;
S32 item_lock = 0;
@ -4483,32 +4499,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cat)
{
LL_WARNS("Inventory") << "null cat" << LL_ENDL;
warnings++;
validation_info->mWarnings["null_cat"]++;
warning_count++;
continue;
}
LLUUID topmost_ancestor_id;
// Will leave as null uuid on failure
EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
switch (res)
{
case ANSCESTOR_MISSING:
orphaned++;
case ANCESTOR_MISSING:
orphaned_count++;
break;
case ANSCESTOR_LOOP:
loops++;
case ANCESTOR_LOOP:
loop_count++;
break;
case ANSCESTOR_OK:
case ANCESTOR_OK:
break;
default:
LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
warnings++;
validation_info->mWarnings["unknown_ancestor_status"]++;
warning_count++;
break;
}
if (cat_id != cat->getUUID())
{
LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
warnings++;
validation_info->mWarnings["cat_id_index_mismatch"]++;
warning_count++;
}
if (cat->getParentUUID().isNull())
@ -4518,7 +4537,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root ("
<< getRootFolderID() << ") or library root ("
<< getLibraryRootFolderID() << ")" << LL_ENDL;
warnings++;
validation_info->mWarnings["null_parent"]++;
warning_count++;
}
}
// <FS:Beq> FIRE-31674 Suitcase contents do not need checking.
@ -4536,7 +4556,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cats || !items)
{
LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL;
warnings++;
validation_info->mWarnings["direct_descendents"]++;
warning_count++;
continue;
}
if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
@ -4554,7 +4575,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " cached " << cat->getDescendentCount()
<< " expected " << cats->size() << "+" << items->size()
<< "=" << cats->size() +items->size() << LL_ENDL;
warnings++;
validation_info->mWarnings["invalid_descendent_count"]++;
warning_count++;
}
}
if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
@ -4578,7 +4600,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!item)
{
LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
warnings++;
validation_info->mWarnings["null_item_at_index"]++;
warning_count++;
continue;
}
@ -4589,7 +4612,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "wrong parent for " << item_id << " found "
<< item->getParentUUID() << " expected " << cat_id
<< LL_ENDL;
warnings++;
validation_info->mWarnings["wrong_parent_for_item"]++;
warning_count++;
}
@ -4599,7 +4623,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " found as child of "
<< cat_id << " but not in top level mItemMap" << LL_ENDL;
warnings++;
validation_info->mWarnings["item_not_in_top_map"]++;
warning_count++;
}
else
{
@ -4613,11 +4638,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// Topmost ancestor should be root or library.
LLUUID topmost_ancestor_id;
EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
if (found != ANSCESTOR_OK)
EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
if (found != ANCESTOR_OK)
{
LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
warnings++;
validation_info->mWarnings["topmost_ancestor_not_found"]++;
warning_count++;
}
else
{
@ -4628,7 +4654,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " got " << topmost_ancestor_id
<< " expected " << getRootFolderID()
<< " or " << getLibraryRootFolderID() << LL_ENDL;
warnings++;
validation_info->mWarnings["topmost_ancestor_not_recognized"]++;
warning_count++;
}
}
}
@ -4644,7 +4671,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
orphaned++;
orphaned_count++;
}
else
{
@ -4662,7 +4689,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
orphaned++;
orphaned_count++;
}
}
}
@ -4671,7 +4698,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LLFolderType::EType folder_type = cat->getPreferredType();
bool cat_is_in_library = false;
LLUUID topmost_id;
if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID())
{
cat_is_in_library = true;
}
@ -4713,14 +4740,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (item->getUUID() != item_id)
{
LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
warnings++;
validation_info->mWarnings["item_id_mismatch"]++;
warning_count++;
}
const LLUUID& parent_id = item->getParentUUID();
if (parent_id.isNull())
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
orphaned++;
orphaned_count++;
}
else
{
@ -4731,7 +4759,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
orphaned++;
orphaned_count++;
}
else
{
@ -4748,7 +4776,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
orphaned++;
orphaned_count++;
}
}
@ -4767,18 +4795,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
<< " missing backlink info at target_id " << target_id
<< LL_ENDL;
orphaned++;
orphaned_count++;
}
// Links should have referents.
if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
{
LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
orphaned++;
orphaned_count++;
}
else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
{
LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
orphaned++;
orphaned_count++;
}
if (target_item && target_item->getIsLinkType())
{
@ -4864,13 +4892,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
validation_info->mLog << out.str() << std::endl;
// </FS:Beq>
fatal_errs++;
validation_info->mMissingRequiredSystemFolders.insert(folder_type);
fatal_errs++;
}
else
{
// Can create, and will when needed.
warnings++;
// (Not sure this is really a warning, but worth logging)
validation_info->mWarnings["missing_system_folder_can_create"]++;
warning_count++;
}
}
else if (count_under_root > 1)
@ -4889,6 +4919,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
validation_info->mFatalSystemDuplicate++;
fatal_errs++;
}
else
@ -4897,13 +4928,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// For automatic folders it's not a fatal issue and shouldn't
// break inventory or other functionality further
// Exception: FT_SETTINGS is not automatic, but only deserves a warning.
warnings++;
validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++;
warning_count++;
}
}
if (count_elsewhere > 0)
{
LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << LLFolderType::lookup(folder_type) << "(" << ft << ") outside of root" << LL_ENDL; //<FS:Beq/> FIRE-31634 [OPENSIM] Better inventory validation
warnings++;
validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++;
warning_count++;
}
}
}
@ -4925,12 +4958,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// FIXME need to fail login and tell user to retry, contact support if problem persists.
bool valid = (fatal_errs == 0);
LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL;
validation_info->mFatalErrorCount = fatal_errs;
validation_info->mWarningCount = warnings;
validation_info->mLoopCount = loops;
validation_info->mOrphanedCount = orphaned;
validation_info->mWarningCount = warning_count;
validation_info->mLoopCount = loop_count;
validation_info->mOrphanedCount = orphaned_count;
return validation_info;
}

View File

@ -69,15 +69,19 @@ public:
void toOstream(std::ostream& os) const;
void asLLSD(LLSD& sd) const;
bool mInitialized{false};
S32 mWarningCount{0};
std::map<std::string,U32> mWarnings;
S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves
S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders
S32 mFatalErrorCount{0};
bool mFatalNoRootFolder{false};
S32 mFatalSystemDuplicate{0};
bool mFatalNoLibraryRootFolder{false};
bool mFatalQADebugMode{false};
S32 mFatalErrorCount;
S32 mWarningCount;
S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
S32 mOrphanedCount; // Missing or orphaned items, links and folders
bool mInitialized;
bool mFatalNoRootFolder;
bool mFatalNoLibraryRootFolder;
bool mFatalQADebugMode;
std::set<LLFolderType::EType> mMissingRequiredSystemFolders;
std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders;
std::ostringstream mLog; // <FS:Beq/> Extra validation logs for OpenSim.
@ -305,13 +309,13 @@ public:
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
enum EAnscestorResult{
ANSCESTOR_OK = 0,
ANSCESTOR_MISSING = 1,
ANSCESTOR_LOOP = 2,
enum EAncestorResult{
ANCESTOR_OK = 0,
ANCESTOR_MISSING = 1,
ANCESTOR_LOOP = 2,
};
// Follow parent chain to the top.
EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
// <FS:Beq> FIRE-31674 ignore suitcase contents
#ifdef OPENSIM
bool isInSuitcase(const LLInventoryCategory * cat) const;

View File

@ -109,6 +109,8 @@ public:
LLLineEditor* getTextEntry() const { return mTextEntry; }
void handleLoginComplete();
bool isNavMeshDirty() { return mIsNavMeshDirty; }
// [RLVa:KB] - Checked: 2014-03-23 (RLVa-1.4.10)
void refresh();
// [/RLVa:KB]

View File

@ -809,7 +809,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type&
if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
// If already initialized, just confirm the status so the callback gets called
setSLMStatus(mMarketPlaceStatus);
if (mMarketPlaceFailureReason.empty())
{
setSLMStatus(mMarketPlaceStatus);
}
else
{
setSLMConnectionFailure(mMarketPlaceFailureReason);
}
}
else
{
@ -850,28 +857,27 @@ void LLMarketplaceData::getMerchantStatusCoro()
if (httpCode == HTTP_NOT_FOUND)
{
log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant"));
setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
}
else if (httpCode == HTTP_SERVICE_UNAVAILABLE)
{
log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated"));
setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
else if (httpCode == HTTP_INTERNAL_ERROR)
else
{
// 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938
LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode
<< ", reason : " << status.toString()
<< ", code : " << result["error_code"].asString()
<< ", description : " << result["error_description"].asString() << LL_ENDL;
LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
}
else
{
std::string err_code = result["error_code"].asString();
//std::string err_description = result["error_description"].asString();
log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]);
setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
std::string reason = status.toString();
if (reason.empty())
{
reason = result["error_code"].asString();
}
// Since user might not even have a marketplace, there is no reason to report the error
// to the user, instead write it down into listings' floater
LLMarketplaceData::instance().setSLMConnectionFailure(reason);
}
return;
}
@ -1349,6 +1355,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route)
void LLMarketplaceData::setSLMStatus(U32 status)
{
mMarketPlaceStatus = status;
mMarketPlaceFailureReason.clear();
if (mStatusUpdatedSignal)
{
(*mStatusUpdatedSignal)();
}
}
void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason)
{
mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
mMarketPlaceFailureReason = reason;
if (mStatusUpdatedSignal)
{
(*mStatusUpdatedSignal)();

View File

@ -198,7 +198,9 @@ public:
typedef boost::signals2::signal<void ()> status_updated_signal_t;
void initializeSLM(const status_updated_signal_t::slot_type& cb);
U32 getSLMStatus() const { return mMarketPlaceStatus; }
std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; }
void setSLMStatus(U32 status);
void setSLMConnectionFailure(const std::string& reason);
void getSLMListings();
bool isEmpty() { return (mMarketplaceItems.size() == 0); }
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
@ -273,6 +275,7 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
std::string mMarketPlaceFailureReason;
status_updated_signal_t* mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check

View File

@ -48,6 +48,12 @@
#include "llviewermenu.h"
#include "llviewermenufile.h" // LLFilePickerThread
// <FS:Zi> IME - International input compositing, i.e. for Japanese / Chinese text input
#if LL_SDL2
#include "llwindow.h"
#endif
// </FS:Zi>
// linden library includes
#include "llfocusmgr.h"
#include "llsdutil.h"
@ -411,6 +417,34 @@ void LLMediaCtrl::onFocusLost()
// This might go away later.
void LLMediaCtrl::setFocus(BOOL b)
{
// <FS:Zi> IME - International input compositing, i.e. for Japanese / Chinese text input
#if LL_SDL2
// IME - International input compositing, i.e. for Japanese / Chinese text input
// Caveat: we currently don't know the position of the input cursor inside the
// media control box, so the IME will pop up somewhere at the top instead,
// which is not ideal and needs more research
if (b)
{
// Make sure the IME is in the right place, on top of the input line
LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos(screen_pos.mLeft, screen_pos.mTop + gSavedSettings.getS32("SDL2IMEMediaVerticalOffset"));
// shift by a few pixels so the IME doesn't pop to the left side when the nedia
// control is very close to the left edge
ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]) + 5;
ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
getWindow()->setLanguageTextInput(ime_pos);
}
// this floater is not an LLPreeditor but we are only interested in the pointer anyway
// so hopefully we will get away with this
getWindow()->allowLanguageTextInput((LLPreeditor*) this, b);
#endif
// </FS:Zi>
if (b)
{
onFocusReceived();

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