diff --git a/autobuild.xml b/autobuild.xml
index ccb5ac4e12..1d303b3e95 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -482,9 +482,9 @@
archive
name
darwin64
@@ -494,9 +494,9 @@
archive
name
windows
@@ -506,16 +506,16 @@
archive
name
windows64
version
- 1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114
+ 1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114
expat
version
- 4.10.0000.32327.5fc3fe7c.558436
+ 4.10.0000.32327.5fc3fe7c.571099
threejs
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 640ffb037e..2c1e5487ce 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -223,6 +223,7 @@ Ansariel Hiller
MAINT-8723
SL-10385
SL-10891
+ SL-10675
SL-13364
SL-13858
SL-13697
@@ -820,6 +821,7 @@ Jonathan Yap
Kadah Coba
STORM-1060
STORM-1843
+ SL-10675
Jondan Lundquist
Joosten Briebers
MAINT-7074
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index e0ebbb76bd..9e897a7ce8 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -276,7 +276,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
{
// The source is done playing, clean it up.
delete sourcep;
- mAllSources.erase(iter++);
+ iter = mAllSources.erase(iter);
continue;
}
@@ -827,7 +827,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
addAudioSource(asp);
if (pos_global.isExactlyZero())
{
- asp->setAmbient(true);
+ // For sound preview and UI
+ asp->setForcedPriority(true);
}
else
{
@@ -1273,7 +1274,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mPriority(0.f),
mGain(gain),
mSourceMuted(false),
- mAmbient(false),
+ mForcedPriority(false),
mLoop(false),
mSyncMaster(false),
mSyncSlave(false),
@@ -1339,7 +1340,7 @@ void LLAudioSource::update()
void LLAudioSource::updatePriority()
{
- if (isAmbient())
+ if (isForcedPriority())
{
mPriority = 1.f;
}
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index b5fd4c27a1..e12fb970ca 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -266,8 +266,8 @@ public:
void addAudioData(LLAudioData *adp, bool set_current = TRUE);
- void setAmbient(const bool ambient) { mAmbient = ambient; }
- bool isAmbient() const { return mAmbient; }
+ void setForcedPriority(const bool ambient) { mForcedPriority = ambient; }
+ bool isForcedPriority() const { return mForcedPriority; }
void setLoop(const bool loop) { mLoop = loop; }
bool isLoop() const { return mLoop; }
@@ -326,7 +326,7 @@ protected:
F32 mPriority;
F32 mGain;
bool mSourceMuted;
- bool mAmbient;
+ bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI
bool mLoop;
bool mSyncMaster;
bool mSyncSlave;
diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp
index b0c87b0208..e5752d3dad 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.cpp
+++ b/indra/llaudio/llaudioengine_fmodstudio.cpp
@@ -519,9 +519,9 @@ void LLAudioChannelFMODSTUDIO::update3DPosition()
return;
}
- if (mCurrentSourcep->isAmbient())
+ if (mCurrentSourcep->isForcedPriority())
{
- // Ambient sound, don't need to do any positional updates.
+ // Prioritized UI and preview sounds don't need to do any positional updates.
set3DMode(false);
}
else
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
index 3bdd0302ee..305aa1ecb5 100644
--- a/indra/llaudio/llaudioengine_openal.cpp
+++ b/indra/llaudio/llaudioengine_openal.cpp
@@ -297,7 +297,7 @@ void LLAudioChannelOpenAL::update3DPosition()
{
return;
}
- if (mCurrentSourcep->isAmbient())
+ if (mCurrentSourcep->isForcedPriority())
{
alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 1ad29a3f59..85577992a6 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -70,7 +70,11 @@ mRetryCount(0)
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
- mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
+ }
// Here's where we set the size of the network buffer and some buffering
// parameters. In this case we want a network buffer of 16k, we want it
@@ -134,7 +138,7 @@ void LLStreamingAudio_FMODSTUDIO::killDeadStreams()
{
LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
delete streamp;
- mDeadStreams.erase(iter++);
+ iter = mDeadStreams.erase(iter);
}
else
{
@@ -404,7 +408,11 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
if (mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
- mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
+ FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
+ }
return mStreamChannel;
}
@@ -445,16 +453,29 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream()
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
- mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
+ }
return state;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
- mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_RESULT result = mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
+ return;
+ }
FMOD_ADVANCEDSETTINGS settings;
memset(&settings, 0, sizeof(settings));
settings.cbSize = sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
- mSystem->setAdvancedSettings(&settings);
+ result = mSystem->setAdvancedSettings(&settings);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setAdvancedSettings error: " << FMOD_ErrorString(result) << LL_ENDL;
+ }
}
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index e906d81ce1..c38614b0b4 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -44,6 +44,14 @@ using namespace std;
#define INCHES_TO_METERS 0.02540005f
+/// The .bvh does not have a formal spec, and different readers interpret things in their own way.
+/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation.
+const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1;
+/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards.
+/// I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point..
+/// Thus there are two frame of the total that do not contribute to the total running time of the animation.
+const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1;
+
const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f;
const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f;
@@ -865,7 +873,10 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
return E_ST_NO_FRAME_TIME;
}
- mDuration = (F32)mNumFrames * mFrameTime;
+ // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime.
+ // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the
+ // behavior is not defined. In this case, retain historical undefined behavior.
+ mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime;
if (!mLoop)
{
mLoopOutPoint = mDuration;
@@ -1355,12 +1366,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
S32 outcount = 0;
- S32 frame = 1;
+ S32 frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
- if ((frame == 1) && joint->mRelativeRotationKey)
+
+ if ((frame == 0) && joint->mRelativeRotationKey)
{
first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
@@ -1373,7 +1385,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
- time = (F32)frame * mFrameTime;
+ time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
if (mergeParent)
{
@@ -1433,12 +1445,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLVector3 relPos = joint->mRelativePosition;
LLVector3 relKey;
- frame = 1;
+ frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
- if ((frame == 1) && joint->mRelativePositionKey)
+ if ((frame == 0) && joint->mRelativePositionKey)
{
relKey.setVec(ki->mPos);
}
@@ -1449,7 +1461,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
- time = (F32)frame * mFrameTime;
+ time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;
LLVector3 outPos = inPos * frameRot * offsetRot;
diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
index b68e9e0f82..da9d98c16c 100644
--- a/indra/llcommon/llalignedarray.h
+++ b/indra/llcommon/llalignedarray.h
@@ -116,14 +116,20 @@ void LLAlignedArray::resize(U32 size)
template
T& LLAlignedArray::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
const T& LLAlignedArray::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];
}
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c2d353b0fc..14bfb98629 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -35,6 +35,7 @@
// STL headers
// std headers
#include
+#include
// external library headers
#include
#include
@@ -214,6 +215,22 @@ std::string LLCoros::logname()
return data.mName.empty()? data.getKey() : data.mName;
}
+void LLCoros::saveException(const std::string& name, std::exception_ptr exc)
+{
+ mExceptionQueue.emplace(name, exc);
+}
+
+void LLCoros::rethrow()
+{
+ if (! mExceptionQueue.empty())
+ {
+ ExceptionData front = mExceptionQueue.front();
+ mExceptionQueue.pop();
+ LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL;
+ std::rethrow_exception(front.exception);
+ }
+}
+
void LLCoros::setStackSize(S32 stacksize)
{
LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
@@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
-void LLCoros::winlevel(const std::string& name, const callable_t& callable)
+void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
{
__try
{
- toplevelTryWrapper(name, callable);
+ LLCoros::toplevelTryWrapper(name, callable);
}
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
@@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)
throw std::exception(integer_string);
}
}
-
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
@@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
+#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
- // crash, hopefully informatively.
+ // crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
+#else
+ // Stash any OTHER kind of uncaught exception in the rethrow() queue
+ // to be rethrown by the main fiber.
+ LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
+ << name << LL_ENDL;
+ LLCoros::instance().saveException(name, std::current_exception());
+#endif
}
}
@@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
- // Can not use __try in functions that require unwinding, so use one more wrapper
- winlevel(name, callable);
+ // Because SEH can's have unwinding, need to call a wrapper
+ // 'try' is inside SEH handling to not catch LLContinue
+ sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index a94cfca19f..dbff921f16 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -38,6 +38,8 @@
#include "llinstancetracker.h"
#include
#include
+#include
+#include
// e.g. #include LLCOROS_MUTEX_HEADER
#define LLCOROS_MUTEX_HEADER
@@ -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 mExceptionQueue;
S32 mStackSize;
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 818df07bb2..4a1a81f083 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -118,7 +118,11 @@ namespace
eMONTIOR_MWAIT=33,
eCPLDebugStore=34,
eThermalMonitor2=35,
- eAltivec=36
+ eAltivec=36,
+ eSSE3S_Features = 37,
+ eSSE4_1_Features = 38,
+ eSSE4_2_Features = 39,
+ eSSE4a_Features = 40,
};
const char* cpu_feature_names[] =
@@ -161,7 +165,11 @@ namespace
"CPL Qualified Debug Store",
"Thermal Monitor 2",
- "Altivec"
+ "Altivec",
+ "SSE3S Instructions",
+ "SSE4.1 Instructions",
+ "SSE4.2 Instructions",
+ "SSE4a Instructions",
};
std::string intel_CPUFamilyName(int composed_family)
@@ -250,6 +258,31 @@ public:
return hasExtension(cpu_feature_names[eSSE2_Ext]);
}
+ bool hasSSE3() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ bool hasSSE3S() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ bool hasSSE41() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ bool hasSSE42() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ bool hasSSE4a() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+
bool hasAltivec() const
{
return hasExtension("Altivec");
@@ -473,6 +506,12 @@ private:
*((int*)(cpu_vendor+4)) = cpu_info[3];
*((int*)(cpu_vendor+8)) = cpu_info[2];
setInfo(eVendor, cpu_vendor);
+ std::string cmp_vendor(cpu_vendor);
+ bool is_amd = false;
+ if (cmp_vendor == "AuthenticAMD")
+ {
+ is_amd = true;
+ }
// Get the information associated with each valid Id
for(unsigned int i=0; i<=ids; ++i)
@@ -504,6 +543,7 @@ private:
if(cpu_info[2] & 0x8)
{
+ // intel specific SSE3 suplements
setExtension(cpu_feature_names[eMONTIOR_MWAIT]);
}
@@ -516,7 +556,22 @@ private:
{
setExtension(cpu_feature_names[eThermalMonitor2]);
}
-
+
+ if (cpu_info[2] & 0x200)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_info[2] & 0x80000)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_info[2] & 0x100000)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
unsigned int feature_info = (unsigned int) cpu_info[3];
for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
{
@@ -543,8 +598,17 @@ private:
__cpuid(cpu_info, i);
// Interpret CPU brand string and cache information.
- if (i == 0x80000002)
- memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ if (i == 0x80000001)
+ {
+ if (is_amd)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+ }
+ else if (i == 0x80000002)
+ {
+ memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ }
else if (i == 0x80000003)
memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info));
else if (i == 0x80000004)
@@ -690,6 +754,41 @@ private:
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
setConfig(eExtFeatureBits, ext_feature_infos[0]);
+
+
+ char cpu_features[1024];
+ len = sizeof(cpu_features);
+ memset(cpu_features, 0, len);
+ sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0);
+
+ std::string cpu_features_str(cpu_features);
+ cpu_features_str = " " + cpu_features_str + " ";
+
+ if (cpu_features_str.find(" SSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (cpu_features_str.find(" SSSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4A ") != std::string::npos)
+ {
+ // Not supposed to happen?
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
}
};
@@ -800,6 +899,31 @@ private:
{
setExtension(cpu_feature_names[eSSE2_Ext]);
}
+
+ if (flags.find(" pni ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (flags.find(" ssse3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (flags.find(" sse4_1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (flags.find(" sse4_2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (flags.find(" sse4a ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
# endif // LL_X86
}
@@ -860,6 +984,11 @@ LLProcessorInfo::~LLProcessorInfo() {}
F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
+bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); }
+bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
+bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
+bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
+bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index b77eb22c3a..1a473ddc97 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -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;
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 9b6bb3826c..26a0fa1b1c 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -597,6 +597,11 @@ LLCPUInfo::LLCPUInfo()
// proc.WriteInfoTextFile("procInfo.txt");
mHasSSE = proc.hasSSE();
mHasSSE2 = proc.hasSSE2();
+ mHasSSE3 = proc.hasSSE3();
+ mHasSSE3S = proc.hasSSE3S();
+ mHasSSE41 = proc.hasSSE41();
+ mHasSSE42 = proc.hasSSE42();
+ mHasSSE4a = proc.hasSSE4a();
mHasAltivec = proc.hasAltivec();
mCPUMHz = (F64)proc.getCPUFrequency();
mFamily = proc.getCPUFamilyName();
@@ -609,6 +614,35 @@ LLCPUInfo::LLCPUInfo()
}
mCPUString = out.str();
LLStringUtil::trim(mCPUString);
+
+ if (mHasSSE)
+ {
+ mSSEVersions.append("1");
+ }
+ if (mHasSSE2)
+ {
+ mSSEVersions.append("2");
+ }
+ if (mHasSSE3)
+ {
+ mSSEVersions.append("3");
+ }
+ if (mHasSSE3S)
+ {
+ mSSEVersions.append("3S");
+ }
+ if (mHasSSE41)
+ {
+ mSSEVersions.append("4.1");
+ }
+ if (mHasSSE42)
+ {
+ mSSEVersions.append("4.2");
+ }
+ if (mHasSSE4a)
+ {
+ mSSEVersions.append("4a");
+ }
}
bool LLCPUInfo::hasAltivec() const
@@ -626,6 +660,31 @@ bool LLCPUInfo::hasSSE2() const
return mHasSSE2;
}
+bool LLCPUInfo::hasSSE3() const
+{
+ return mHasSSE3;
+}
+
+bool LLCPUInfo::hasSSE3S() const
+{
+ return mHasSSE3S;
+}
+
+bool LLCPUInfo::hasSSE41() const
+{
+ return mHasSSE41;
+}
+
+bool LLCPUInfo::hasSSE42() const
+{
+ return mHasSSE42;
+}
+
+bool LLCPUInfo::hasSSE4a() const
+{
+ return mHasSSE4a;
+}
+
F64 LLCPUInfo::getMHz() const
{
return mCPUMHz;
@@ -636,6 +695,11 @@ std::string LLCPUInfo::getCPUString() const
return mCPUString;
}
+const LLSD& LLCPUInfo::getSSEVersions() const
+{
+ return mSSEVersions;
+}
+
void LLCPUInfo::stream(std::ostream& s) const
{
// gather machine information.
@@ -645,6 +709,11 @@ void LLCPUInfo::stream(std::ostream& s) const
// CPU's attributes regardless of platform
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
+ s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl;
+ s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl;
+ s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl;
+ s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl;
+ s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl;
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
s << "->mCPUMHz: " << mCPUMHz << std::endl;
s << "->mCPUString: " << mCPUString << std::endl;
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index cb92cb0ac6..5ffbf5a732 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -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;
};
//=============================================================================
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index ee43a599f7..01144d8b0d 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -354,6 +354,38 @@ void LLDiskCache::clearCache()
}
}
+void LLDiskCache::removeOldVFSFiles()
+{
+ //VFS files won't be created, so consider removing this code later
+ static const char CACHE_FORMAT[] = "inv.llsd";
+ static const char DB_FORMAT[] = "db2.x";
+
+ boost::system::error_code ec;
+#if LL_WINDOWS
+ std::wstring cache_path(utf8str_to_utf16str(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")));
+#else
+ std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""));
+#endif
+ if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
+ {
+ for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
+ {
+ if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+ {
+ if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
+ (entry.path().string().find(DB_FORMAT) != std::string::npos))
+ {
+ boost::filesystem::remove(entry, ec);
+ if (ec.failed())
+ {
+ LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+}
+
uintmax_t LLDiskCache::dirFileSize(const std::string dir)
{
uintmax_t total_file_size = 0;
diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h
index 1cbd2c58aa..b60e74f8c9 100644
--- a/indra/llfilesystem/lldiskcache.h
+++ b/indra/llfilesystem/lldiskcache.h
@@ -140,6 +140,8 @@ class LLDiskCache :
*/
const std::string getCacheInfo();
+ void removeOldVFSFiles();
+
private:
/**
* Utility function to gather the total size the files in a given
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index e25dae8a90..134e783053 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -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();
}
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 5d08c1f4c6..f5ee1241ab 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -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;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 4a069b0f63..93f1d508f3 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -684,7 +684,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
- static LLAlignedArray pt;
+ static thread_local LLAlignedArray pt;
pt.resize(mTotal) ;
for (S32 i=mTotalOut;i= profile.size())
+ {
+ // edge?
+ ss = flat ? 1.f - begin_stex : 1.f;
+ }
+ else if (!flat)
{
- ss = profile[mBeginS + s][2];
+ ss = profile[index][2];
}
else
{
- ss = profile[mBeginS + s][2] - begin_stex;
+ ss = profile[index][2] - begin_stex;
}
}
@@ -6866,7 +6872,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* norm = mNormals;
- static LLAlignedArray triangle_normals;
+ static thread_local LLAlignedArray triangle_normals;
try
{
triangle_normals.resize(count);
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index c67f59bc0c..846549b368 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -196,6 +196,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vectorhandleAvNameCacheSuccess(results, httpResults);
}
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (...)
{
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 2d460826ff..c5bc37dd0e 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -32,7 +32,6 @@
#include "llcoros.h"
#include "llcorehttputil.h"
#include "lluuid.h"
-#include
class LLCoprocedurePool;
@@ -84,7 +83,7 @@ public:
private:
- typedef boost::shared_ptr poolPtr_t;
+ typedef std::shared_ptr poolPtr_t;
typedef std::map poolMap_t;
poolMap_t mPoolMap;
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 219b1855d2..35dcbe3836 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -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");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 8f6ee5a327..3015f438b5 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -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;
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 6f88232c1d..3e72710366 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1549,6 +1549,7 @@ void LLPluginClassMedia::seek(float time)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
message.setValueReal("time", time);
+ mCurrentTime = time; // assume that it worked and we will receive an update later
sendMessage(message);
}
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index eef22156bc..1fbbad06d4 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -999,7 +999,7 @@ void LLPluginProcessParent::poll(F64 timeout)
while (itClean != sInstances.end())
{
if ((*itClean).second->isDone())
- sInstances.erase(itClean++);
+ itClean = sInstances.erase(itClean);
else
++itClean;
}
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 285c5f656b..555164f3b0 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -843,7 +843,7 @@ LLSD LLModel::writeModel(
{
LLVector3 pos(face.mPositions[j].getF32ptr());
- weight_list& weights = high->getJointInfluences(pos);
+ weight_list& weights = model[idx]->getJointInfluences(pos);
S32 count = 0;
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
@@ -1553,6 +1553,25 @@ void LLMeshSkinInfo::updateHash()
mHash = digest[0];
}
+U32 LLMeshSkinInfo::sizeBytes() const
+{
+ U32 res = sizeof(LLUUID); // mMeshID
+
+ res += sizeof(std::vector) + sizeof(std::string) * mJointNames.size();
+ for (U32 i = 0; i < mJointNames.size(); ++i)
+ {
+ res += mJointNames[i].size(); // actual size, not capacity
+ }
+
+ res += sizeof(std::vector) + sizeof(S32) * mJointNums.size();
+ res += sizeof(std::vector) + 16 * sizeof(float) * mInvBindMatrix.size();
+ res += sizeof(std::vector) + 16 * sizeof(float) * mAlternateBindMatrix.size();
+ res += 16 * sizeof(float); //mBindShapeMatrix
+ res += sizeof(float) + 3 * sizeof(bool);
+
+ return res;
+}
+
LLModel::Decomposition::Decomposition(LLSD& data)
{
fromLLSD(data);
@@ -1659,6 +1678,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
}
}
+U32 LLModel::Decomposition::sizeBytes() const
+{
+ U32 res = sizeof(LLUUID); // mMeshID
+
+ res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector) * 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) + sizeof(std::vector) * mMesh.size();
+ for (U32 i = 0; i < mMesh.size(); ++i)
+ {
+ res += mMesh[i].sizeBytes();
+ }
+
+ res += sizeof(std::vector) * 2;
+ res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes();
+
+ return res;
+}
+
bool LLModel::Decomposition::hasHullList() const
{
return !mHull.empty() ;
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 354ceb26b7..a6ab96ab18 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -50,6 +50,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash();
+ U32 sizeBytes() const;
LLUUID mMeshID;
std::vector mJointNames;
@@ -112,6 +113,14 @@ public:
{
return mPositions.empty();
}
+
+ U32 sizeBytes() const
+ {
+ U32 res = sizeof(std::vector) * 2;
+ res += sizeof(LLVector3) * mPositions.size();
+ res += sizeof(LLVector3) * mNormals.size();
+ return res;
+ }
};
class Decomposition
@@ -122,6 +131,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
bool hasHullList() const;
+ U32 sizeBytes() const;
void merge(const Decomposition* rhs);
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 9bd3a0a6b0..b9dc689d1a 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1248,7 +1248,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1268,7 +1273,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1291,7 +1301,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 03efd09689..d413fab270 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -259,6 +259,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
mLegacyHeaderHeight(p.legacy_header_height),
+ mDefaultRectForGroup(true),
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
@@ -761,17 +762,13 @@ void LLFloater::closeFloater(bool app_quitting)
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); )
{
-
LLFloater* floaterp = dependent_it->get();
- if (floaterp)
- {
- ++dependent_it;
- floaterp->closeFloater(app_quitting);
- }
- else
- {
- mDependents.erase(dependent_it++);
- }
+ dependent_it = mDependents.erase(dependent_it);
+ if (floaterp)
+ {
+ floaterp->mDependeeHandle = LLHandle();
+ floaterp->closeFloater(app_quitting);
+ }
}
cleanupHandles();
@@ -906,7 +903,10 @@ bool LLFloater::applyRectControl()
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
- mRectControl.clear();
+ if (mDefaultRectForGroup)
+ {
+ mRectControl.clear();
+ }
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
else
@@ -1439,7 +1439,7 @@ void LLFloater::cleanupHandles()
LLFloater* floaterp = dependent_it->get();
if (!floaterp)
{
- mDependents.erase(dependent_it++);
+ dependent_it = mDependents.erase(dependent_it);
}
else
{
@@ -3481,8 +3481,15 @@ void LLFloater::stackWith(LLFloater& other)
}
next_rect.translate(floater_offset, -floater_offset);
- next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
-
+ const LLRect& rect = getControlGroup()->getRect(mRectControl);
+ if (rect.notEmpty() && !mDefaultRectForGroup && mResizable)
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ }
+ else
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
+ }
setShape(next_rect);
if (!other.getHost())
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 306760b7fb..668cd208a9 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -454,6 +454,7 @@ public:
protected:
bool mSaveRect;
+ bool mDefaultRectForGroup;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 82b01e705d..e01aba402e 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -35,6 +35,7 @@
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluiimage.h"
+#include "llwindow.h"
static LLDefaultChildRegistry::Register r("icon");
@@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()
: image("image_name"),
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
+ interactable("interactable", false),
scale_image("scale_image"),
min_width("min_width", 0),
min_height("min_height", 0)
@@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
mColor(p.color()),
mImagep(p.image),
mUseDrawContextAlpha(p.use_draw_context_alpha),
+ mInteractable(p.interactable),
mPriority(0),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
@@ -81,6 +84,16 @@ void LLIconCtrl::draw()
LLUICtrl::draw();
}
+BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mInteractable && getEnabled())
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ return TRUE;
+ }
+ return LLUICtrl::handleHover(x, y, mask);
+}
+
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value)
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index dd83e78fd3..9c3b517bca 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -48,7 +48,8 @@ public:
{
Optional image;
Optional color;
- Optional use_draw_context_alpha;
+ Optional use_draw_context_alpha,
+ interactable;
Optional min_width,
min_height;
Ignored scale_image;
@@ -67,6 +68,9 @@ public:
// llview overrides
virtual void draw();
+ // llview overrides
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+
// lluictrl overrides
virtual void setValue(const LLSD& value );
@@ -88,6 +92,7 @@ protected:
// If set to true (default), use the draw context transparency.
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
bool mUseDrawContextAlpha;
+ bool mInteractable;
private:
LLUIColor mColor;
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 303afcda15..583704418b 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -40,6 +40,7 @@ void LLMenuButton::MenuPositions::declareValues()
declare("topleft", MP_TOP_LEFT);
declare("topright", MP_TOP_RIGHT);
declare("bottomleft", MP_BOTTOM_LEFT);
+ declare("bottomright", MP_BOTTOM_RIGHT);
}
LLMenuButton::Params::Params()
@@ -212,6 +213,13 @@ void LLMenuButton::updateMenuOrigin()
mY = rect.mBottom;
break;
}
+ case MP_BOTTOM_RIGHT:
+ {
+ const LLRect& menu_rect = menu->getRect();
+ mX = rect.mRight - menu_rect.getWidth();
+ mY = rect.mBottom;
+ break;
+ }
}
}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index 67ec1983b3..e42f8f53bd 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -41,7 +41,8 @@ public:
{
MP_TOP_LEFT,
MP_TOP_RIGHT,
- MP_BOTTOM_LEFT
+ MP_BOTTOM_LEFT,
+ MP_BOTTOM_RIGHT
} EMenuPosition;
struct MenuPositions
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8f00d1274e..4264028338 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3960,8 +3960,8 @@ void LLTearOffMenu::draw()
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
- mMenu->needsArrange();
}
+ mMenu->needsArrange();
LLFloater::draw();
}
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 5cfa8ea973..3e5978eb59 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -100,7 +100,10 @@ void LLModalDialog::onOpen(const LLSD& key)
if (!sModalStack.empty())
{
LLModalDialog* front = sModalStack.front();
- front->setVisible(FALSE);
+ if (front != this)
+ {
+ front->setVisible(FALSE);
+ }
}
// This is a modal dialog. It sucks up all mouse and keyboard operations.
@@ -108,7 +111,14 @@ void LLModalDialog::onOpen(const LLSD& key)
LLUI::getInstance()->addPopup(this);
setFocus(TRUE);
- sModalStack.push_front( this );
+ std::list::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
+ if (iter != sModalStack.end())
+ {
+ // if already present, we want to move it to front.
+ sModalStack.erase(iter);
+ }
+
+ sModalStack.push_front(this);
}
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 11b0eb9f80..65c7b420ce 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1388,6 +1388,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
return found;
}
+U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus)
+{
+ return searchItems(utf8str_to_wstring(substring), case_sensitive, focus);
+}
+
+U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus)
+{
+ U32 found = 0;
+
+ LLWString substring_trimmed(substring);
+ S32 len = substring_trimmed.size();
+
+ if (0 == len)
+ {
+ // at the moment search for empty element is not supported
+ return 0;
+ }
+ else
+ {
+ deselectAllItems(TRUE);
+ if (!case_sensitive)
+ {
+ // do comparisons in lower case
+ LLWStringUtil::toLower(substring_trimmed);
+ }
+
+ for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ {
+ LLScrollListItem* item = *iter;
+ // Only select enabled items with matching names
+ if (!item->getEnabled())
+ {
+ continue;
+ }
+ LLScrollListCell* cellp = item->getColumn(getSearchColumn());
+ if (!cellp)
+ {
+ continue;
+ }
+ LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
+ if (!case_sensitive)
+ {
+ LLWStringUtil::toLower(item_label);
+ }
+ // remove extraneous whitespace from searchable label
+ LLWStringUtil::trim(item_label);
+
+ size_t found_iter = item_label.find(substring_trimmed);
+
+ if (found_iter != std::string::npos)
+ {
+ // find offset of matching text
+ cellp->highlightText(found_iter, substring_trimmed.size());
+ selectItem(item, -1, FALSE);
+
+ found++;
+
+ if (!mAllowMultipleSelection)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (focus && found != 0)
+ {
+ mNeedsScroll = true;
+ }
+
+ if (mCommitOnSelectionChange)
+ {
+ commitIfChanged();
+ }
+
+ return found;
+}
+
const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const
{
LLScrollListItem* item;
@@ -1912,6 +1990,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1975,6 +2054,15 @@ void LLScrollListCtrl::removeFriend(std::string id)
LLUrlAction::removeFriend(slurl);
}
+void LLScrollListCtrl::reportAbuse(std::string id, bool is_group)
+{
+ if (!is_group)
+ {
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::reportAbuse(slurl);
+ }
+}
+
void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
{
// open the resident's details or the group details
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 08134bbfc8..77d10fdec7 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -267,6 +267,14 @@ public:
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
+ // If multi select is on, select all element that include substring,
+ // otherwise select first match only.
+ // If focus is true will scroll to selection.
+ // Returns number of results.
+ // Note: at the moment search happens in one go and is expensive
+ U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true);
+ U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true);
+
// DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
@@ -325,6 +333,7 @@ public:
// support right-click context menus for avatar/group lists
enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
+ ContextMenuType getContextMenuType() { return mContextMenuType; }
// Overridden from LLView
/*virtual*/ void draw();
@@ -460,6 +469,7 @@ private:
static void sendIM(std::string id);
static void addFriend(std::string id);
static void removeFriend(std::string id);
+ static void reportAbuse(std::string id, bool is_group);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 459fdcf2ae..0aa7a2d217 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -402,9 +402,13 @@ void LLTabContainer::draw()
S32 cur_scroll_pos = getScrollPos();
if (cur_scroll_pos > 0)
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
- if (!mIsVertical)
+ if (mIsVertical)
{
+ target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
+ }
+ else
+ {
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@@ -1189,13 +1193,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
-
+
+ updateMaxScrollPos();
+
if( select )
{
selectLastTab();
+ mScrollPos = mMaxScrollPos;
}
- updateMaxScrollPos();
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
@@ -2079,9 +2085,9 @@ void LLTabContainer::updateMaxScrollPos()
if( tab_total_height > available_height )
{
static LLUICachedControl tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
- S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
+ S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;
S32 additional_needed = tab_total_height - available_height_with_arrows;
- setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
+ setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );
no_scroll = FALSE;
}
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0dc99fdde6..7e4aaa53bf 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -163,6 +163,7 @@ LLTextBase::Params::Params()
font_shadow("font_shadow"),
wrap("wrap"),
trusted_content("trusted_content", true),
+ always_show_icons("always_show_icons", false),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
force_urls_external("force_urls_external", false),
@@ -212,6 +213,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mClip(p.clip),
mClipPartial(p.clip_partial && !p.allow_scroll),
mTrustedContent(p.trusted_content),
+ mAlwaysShowIcons(p.always_show_icons),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@@ -448,8 +450,48 @@ void LLTextBase::drawSelectionBackground()
++rect_it)
{
LLRect selection_rect = *rect_it;
- selection_rect = *rect_it;
- selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ if (mScroller)
+ {
+ // If scroller is On content_display_rect has correct rect and safe to use as is
+ // Note: we might need to account for border
+ selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ }
+ else
+ {
+ // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
+ // and we have to acount for offset depending on position
+ S32 v_delta = 0;
+ S32 h_delta = 0;
+ switch (mVAlign)
+ {
+ case LLFontGL::TOP:
+ v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
+ break;
+ case LLFontGL::VCENTER:
+ v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
+ break;
+ default:
+ break;
+ }
+ switch (mHAlign)
+ {
+ case LLFontGL::LEFT:
+ h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
+ break;
+ case LLFontGL::HCENTER:
+ h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
+ break;
+ case LLFontGL::RIGHT:
+ h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
+ break;
+ default:
+ break;
+ }
+ selection_rect.translate(h_delta, v_delta);
+ }
gl_rect_2d(selection_rect, selection_color);
}
}
@@ -2007,6 +2049,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
@@ -2116,7 +2159,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons))
{
start = match.getStart();
end = match.getEnd()+1;
@@ -2141,7 +2184,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// add icon before url if need
- LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
+ LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
{
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index a4e83b42b4..25f8fa1c2b 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -321,7 +321,8 @@ public:
parse_highlights,
clip,
clip_partial,
- trusted_content;
+ trusted_content,
+ always_show_icons;
Optional v_pad,
h_pad;
@@ -369,6 +370,8 @@ public:
virtual void onFocusReceived();
virtual void onFocusLost();
+ void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
+
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
@@ -702,6 +705,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipTripleClick;
+ bool mAlwaysShowIcons;
+
bool mSkipLinkUnderline;
// support widgets
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 26702b2412..1a10d2fd1e 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -196,6 +196,7 @@ public:
const LLUUID& getSourceID() const { return mSourceID; }
const LLTextSegmentPtr getPreviousSegment() const;
+ const LLTextSegmentPtr getLastSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void setShowContextMenu(bool show) { mShowContextMenu = show; }
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index 538508b856..78049319bc 100644
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
@@ -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)
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index a9c143e445..1adc3516f7 100644
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
@@ -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.
*
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 84ea770a8d..8216046174 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -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);
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 2d2a8dfef1..c2c576254d 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -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);
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 5404ac50e5..e65cc7563e 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -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()
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 36bd8bcbed..fb1ae10f50 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -58,7 +58,8 @@ public:
LLKeyboard();
virtual ~LLKeyboard();
- void resetKeys();
+ void resetKeyDownAndHandle();
+ void resetKeys();
F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; }
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index fd20f2ad15..049226db65 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -495,14 +495,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
+ unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
+ bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch);
- bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]);
- unichar ch;
if (acceptsText &&
!mMarkedTextAllowed &&
!(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow
![(LLAppDelegate*)[NSApp delegate] romanScript] &&
- (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' &&
+ ch > ' ' &&
ch != NSDeleteCharacter &&
(ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h)
{
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index f895c17643..5ec9b017cf 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -100,13 +100,13 @@ const unsigned short *copyFromPBoard()
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
- [NSString stringWithFormat:@"%s", fullpath]
+ [NSString stringWithUTF8String:fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index b3616e4ea8..66f7e60371 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1668,7 +1668,7 @@ void LLWindowMacOSX::hideCursor()
void LLWindowMacOSX::showCursor()
{
- if(mCursorHidden)
+ if(mCursorHidden || !isCGCursorVisible())
{
// LL_INFOS() << "showCursor: showing" << LL_ENDL;
mCursorHidden = FALSE;
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ea70e21414..43d3a32e64 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,6 +34,7 @@
#include "llplugininstance.h"
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"
+#include "llstring.h"
#include "volume_catcher.h"
#include "media_plugin_base.h"
@@ -55,7 +56,7 @@ private:
bool init();
void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
- void onCustomSchemeURLCallback(std::string url);
+ void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect);
void onConsoleMessageCallback(std::string message, std::string source, int line);
void onStatusMessageCallback(std::string value);
void onTitleChangeCallback(std::string title);
@@ -299,11 +300,18 @@ void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
////////////////////////////////////////////////////////////////////////////////
//
-void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
+void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
- message.setValue("uri", url);
- message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
+ message.setValue("uri", url);
+
+ // indicate if this interaction was from a user click (okay on a SLAPP) or
+ // via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP)
+ const std::string nav_type = user_gesture ? "clicked" : "navigated";
+
+ message.setValue("nav_type", nav_type);
+ message.setValueBoolean("is_redirect", is_redirect);
+
sendMessage(message);
}
@@ -592,7 +600,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
// event callbacks from Dullahan
mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
- mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
+ mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
@@ -616,9 +624,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
// dir as the executable that loaded it (SLPlugin.exe). The code in
// Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
- char cur_dir_str[MAX_PATH];
- GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
- settings.host_process_path = std::string(cur_dir_str);
+ std::vector 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;
diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
index 1afe25e9a1..89144922cc 100644
--- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
+++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
@@ -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")
{
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a996777fa4..776797da7c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -234,12 +234,14 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
+ llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
+ llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloaterenvironmentadjust.cpp
@@ -296,10 +298,12 @@ set(viewer_SOURCE_FILES
llfloaterperformance.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
+ llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferencesgraphicsadvanced.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
+ llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@@ -332,7 +336,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
- llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@@ -478,7 +481,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
- llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@@ -488,8 +490,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
- llpanelpick.cpp
- llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@@ -498,6 +498,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
+ llpanelprofileclassifieds.cpp
+ llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@@ -659,6 +661,7 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
+ llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@@ -872,12 +875,14 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
+ llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
+ llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloaterenvironmentadjust.h
@@ -937,10 +942,12 @@ set(viewer_HEADER_FILES
llfloaterperformance.h
llfloaterperms.h
llfloaterpostprocess.h
+ llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferencesgraphicsadvanced.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
+ llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@@ -973,7 +980,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
- llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@@ -1109,7 +1115,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
- llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@@ -1119,8 +1124,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
- llpanelpick.h
- llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@@ -1129,6 +1132,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
+ llpanelprofileclassifieds.h
+ llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
@@ -1291,6 +1296,7 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
+ llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index e411592c25..5dbe61b99e 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.3
+6.6.5
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 05a87d197d..4a3dfffde1 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -167,10 +167,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="picks"
- is_running_function="Floater.IsOpen"
- is_running_parameters="picks"
+ execute_function="Avatar.TogglePicks"
+ is_running_function="Avatar.IsPicksTabOpen"
/>
Value
1
- AvalinePhoneSeparator
-
- Comment
- Separator of phone parts to have Avaline numbers human readable in Voice Control Panel
- Persist
- 1
- Type
- String
- Value
- -
-
AvatarAxisDeadZone0
Comment
@@ -4758,7 +4747,7 @@
Type
String
Value
- https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]
+ https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]
GuidebookURL
@@ -5806,6 +5795,17 @@
Value
0
+ DiskCacheVersion
+
+ Comment
+ Version number of disk cache
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 0
+
LocalFileSystemBrowsingEnabled
Comment
@@ -15769,6 +15769,17 @@
Boolean
Value
1
+
+ AllowSelectAvatar
+
+ Comment
+ 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
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
WebProfileFloaterRect
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index a658459caa..78c726043e 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -716,6 +716,9 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
if ((getControlFlags() & mask) == mask)
{
+ // Rotation into both directions should cancel out
+ // But keep sending controls to simulator,
+ // it's needed for script based controls
gAgentCamera.setYawKey(0);
}
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index f981e08ff7..21df036cb7 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
-private:
-
void onServerRespond(LLAvatarPicks* picks);
+private:
+
/**
* Sets number of Picks.
*/
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 60797c87d9..d61a66c696 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1450,6 +1450,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ // if one of our coroutines threw an uncaught exception, rethrow it now
+ LLCoros::instance().rethrow();
}
if (!LLApp::isExiting())
@@ -3291,9 +3293,18 @@ LLSD LLAppViewer::getViewerInfo() const
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
if(LLVoiceClient::getInstance()->voiceEnabled())
{
- LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ const std::string build_version = version.mBuildVersion;
std::ostringstream version_string;
- version_string << version.serverType << " " << version.serverVersion << std::endl;
+ if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
+ version.serverVersion.begin()))
+ { // Normal case: Show type and build version.
+ version_string << version.serverType << " " << build_version << std::endl;
+ }
+ else
+ { // Mismatch: Show both versions.
+ version_string << version.serverVersion << "/" << build_version << std::endl;
+ }
info["VOICE_VERSION"] = version_string.str();
}
else
@@ -4256,6 +4267,15 @@ U32 LLAppViewer::getTextureCacheVersion()
return TEXTURE_CACHE_VERSION ;
}
+//static
+U32 LLAppViewer::getDiskCacheVersion()
+{
+ // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
+ const U32 DISK_CACHE_VERSION = 1;
+
+ return DISK_CACHE_VERSION ;
+}
+
//static
U32 LLAppViewer::getObjectCacheVersion()
{
@@ -4285,12 +4305,16 @@ bool LLAppViewer::initCache()
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
bool texture_cache_mismatch = false;
+ bool remove_vfs_files = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+
+ //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
+ remove_vfs_files = true;
}
}
@@ -4336,7 +4360,19 @@ bool LLAppViewer::initCache()
if (!read_only)
{
- if (mPurgeCache)
+ if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
+ {
+ LLDiskCache::getInstance()->clearCache();
+ remove_vfs_files = true;
+ gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion());
+ }
+
+ if (remove_vfs_files)
+ {
+ LLDiskCache::getInstance()->removeOldVFSFiles();
+ }
+
+ if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
@@ -5418,7 +5454,7 @@ void LLAppViewer::disconnectViewer()
gFloaterView->restoreAll();
}
- if (LLSelectMgr::getInstance())
+ if (LLSelectMgr::instanceExists())
{
LLSelectMgr::getInstance()->deselectAll();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 7ab21f35cd..f28a90c703 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -130,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
+ static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@@ -153,16 +154,16 @@ public:
void removeMarkerFiles();
void removeDumpDir();
- // LLAppViewer testing helpers.
- // *NOTE: These will potentially crash the viewer. Only for debugging.
- virtual void forceErrorLLError();
- virtual void forceErrorBreakpoint();
- virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInfiniteLoop();
- virtual void forceErrorSoftwareException();
- virtual void forceErrorDriverCrash();
- virtual void forceErrorCoroutineCrash();
- virtual void forceErrorThreadCrash();
+ // LLAppViewer testing helpers.
+ // *NOTE: These will potentially crash the viewer. Only for debugging.
+ virtual void forceErrorLLError();
+ virtual void forceErrorBreakpoint();
+ virtual void forceErrorBadMemoryAccess();
+ virtual void forceErrorInfiniteLoop();
+ virtual void forceErrorSoftwareException();
+ virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 1797d2dd6e..25ba7c365f 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -48,6 +48,7 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterpay.h"
+#include "llfloaterprofile.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
@@ -62,11 +63,14 @@
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llpaneloutfitedit.h"
#include "llpanelprofile.h"
+#include "llparcel.h"
#include "llrecentpeople.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
+#include "llviewernetwork.h" //LLGridManager
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lltrans.h"
#include "llcallingcard.h"
@@ -81,6 +85,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
+std::string getProfileURL(const std::string& agent_name, bool feed_only)
+{
+ std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
+ LLSD subs;
+ subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
+ subs["AGENT_NAME"] = agent_name;
+ subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLStringUtil::toLower(url);
+ return url;
+}
+
+
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@@ -316,57 +333,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
make_ui_sound("UISndStartIM");
}
-static const char* get_profile_floater_name(const LLUUID& avatar_id)
-{
- // Use different floater XML for our profile to be able to save its rect.
- return avatar_id == gAgentID ? "my_profile" : "profile";
-}
-
-static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
-{
- std::string url = getProfileURL(av_name.getAccountName());
-
- // PROFILES: open in webkit window
- LLFloaterWebContent::Params p;
- p.url(url).id(agent_id.asString());
- LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
-}
-
// static
-void LLAvatarActions::showProfile(const LLUUID& id)
+void LLAvatarActions::showProfile(const LLUUID& avatar_id)
{
- if (id.notNull())
+ if (avatar_id.notNull())
{
- LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
+ LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
}
}
+// static
+void LLAvatarActions::showPicks(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick();
+ }
+ }
+}
+
+// static
+void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick(pick_id);
+ }
+ }
+}
+
+// static
+void LLAvatarActions::createPick()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ LLViewerRegion* region = gAgent.getRegion();
+ if (profilefloater && region)
+ {
+ LLPickData data;
+ data.pos_global = gAgent.getPositionGlobal();
+ data.sim_name = region->getName();
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ data.name = parcel->getName();
+ data.desc = parcel->getDesc();
+ data.snapshot_id = parcel->getSnapshotID();
+ data.parcel_id = parcel->getID();
+ }
+ else
+ {
+ data.name = region->getName();
+ }
+
+ profilefloater->createPick(data);
+ }
+}
+
+// static
+bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance("profile", LLSD().with("id", avatar_id));
+ if (profilefloater)
+ {
+ return profilefloater->isPickTabSelected();
+ }
+ }
+ return false;
+}
+
+// static
+void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified();
+ }
+ }
+}
+
+// static
+void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified(classified_id, edit);
+ }
+ }
+}
+
+// static
+void LLAvatarActions::createClassified()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ if (profilefloater)
+ {
+ profilefloater->createClassified();
+ }
+}
+
//static
-bool LLAvatarActions::profileVisible(const LLUUID& id)
+bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- return browser && browser->isShown();
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ return floater && floater->isShown();
}
//static
-LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
+LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
{
- LLFloaterWebContent *browser = dynamic_cast
- (LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
- return browser;
+ LLFloaterProfile* floater = LLFloaterReg::findTypedInstance("profile", LLSD().with("id", avatar_id));
+ return floater;
}
//static
-void LLAvatarActions::hideProfile(const LLUUID& id)
+void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- if (browser)
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ if (floater)
{
- browser->closeFloater();
+ floater->closeFloater();
}
}
@@ -990,7 +1094,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// static
-void LLAvatarActions::toggleBlock(const LLUUID& id)
+bool LLAvatarActions::toggleBlock(const LLUUID& id)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@@ -1000,10 +1104,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
{
LLMuteList::getInstance()->remove(mute);
+ return false;
}
else
{
LLMuteList::getInstance()->add(mute);
+ return true;
}
}
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 7c721076c8..86183cc119 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -38,6 +38,8 @@ class LLInventoryPanel;
class LLFloater;
class LLView;
+std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
+
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@@ -91,13 +93,20 @@ public:
*/
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
- /**
- * Show avatar profile.
- */
- static void showProfile(const LLUUID& id);
- static void hideProfile(const LLUUID& id);
- static bool profileVisible(const LLUUID& id);
- static LLFloater* getProfileFloater(const LLUUID& id);
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& avatar_id);
+ static void showPicks(const LLUUID& avatar_id);
+ static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
+ static void createPick();
+ static void showClassifieds(const LLUUID& avatar_id);
+ static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
+ static void createClassified();
+ static void hideProfile(const LLUUID& avatar_id);
+ static bool profileVisible(const LLUUID& avatar_id);
+ static bool isPickTabSelected(const LLUUID& avatar_id);
+ static LLFloater* getProfileFloater(const LLUUID& avatar_id);
/**
* Show avatar on world map.
@@ -126,9 +135,10 @@ public:
static void shareWithAvatars(LLView * panel);
/**
- * Block/unblock the avatar.
+ * Block/unblock the avatar by id.
+ * Returns true if blocked, returns false if unblocked
*/
- static void toggleBlock(const LLUUID& id);
+ static bool toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index b0715a3afd..c0990d9d11 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/)
}
}
-void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name)
-{
- LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL;
- LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
- item->setAvatarId(item_id, session_id, true, false);
- item->setName(item_name);
- item->showLastInteractionTime(mShowLastInteractionTime);
- item->showSpeakingIndicator(mShowSpeakingIndicator);
- item->setOnline(false);
-
- addItem(item, item_id);
- mIDs.push_back(item_id);
- sort();
-}
-
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
@@ -296,18 +281,10 @@ void LLAvatarList::refresh()
{
// *NOTE: If you change the UI to show a different string,
// be sure to change the filter code below.
- if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
- {
- const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
- addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
- }
- else
- {
- std::string display_name = getAvatarName(av_name);
- addNewItem(buddy_id,
- display_name.empty() ? waiting_str : display_name,
- LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
+ std::string display_name = getAvatarName(av_name);
+ addNewItem(buddy_id,
+ display_name.empty() ? waiting_str : display_name,
+ LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
@@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- if ( mContextMenu && !isAvalineItemSelected())
+ if ( mContextMenu)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
@@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
-bool LLAvatarList::isAvalineItemSelected()
-{
- std::vector selected_items;
- getSelectedItems(selected_items);
- std::vector::iterator it = selected_items.begin();
-
- for(; it != selected_items.end(); ++it)
- {
- if (dynamic_cast(*it))
- return true;
- }
-
- return false;
-}
-
void LLAvatarList::setVisible(BOOL visible)
{
if ( visible == FALSE && mContextMenu )
@@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_
}
return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);
}
-
-/************************************************************************/
-/* class LLAvalineListItem */
-/************************************************************************/
-LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false)
-, mIsHideNumber(hide_number)
-{
- // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
- buildFromFile( "panel_avatar_list_item.xml");
-}
-
-BOOL LLAvalineListItem::postBuild()
-{
- BOOL rv = LLAvatarListItem::postBuild();
-
- if (rv)
- {
- setOnline(true);
- showLastInteractionTime(false);
- setShowProfileBtn(false);
- setShowInfoBtn(false);
- mAvatarIcon->setValue("Avaline_Icon");
- mAvatarIcon->setToolTip(std::string(""));
- }
- return rv;
-}
-
-// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number
-void LLAvalineListItem::setName(const std::string& name)
-{
- if (mIsHideNumber)
- {
- static U32 order = 0;
- typedef std::map 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);
- }
-}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 1a672c279b..48b0e70454 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -98,7 +98,6 @@ public:
virtual S32 notifyParent(const LLSD& info);
- void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
void setShowCompleteName(bool show) { mShowCompleteName = show;};
@@ -118,8 +117,6 @@ protected:
private:
- bool isAvalineItemSelected();
-
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@@ -189,27 +186,4 @@ protected:
virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
};
-/**
- * Represents Avaline caller in Avatar list in Voice Control Panel and group chats.
- */
-class LLAvalineListItem : public LLAvatarListItem
-{
-public:
-
- /**
- * Constructor
- *
- * @param hide_number - flag indicating if number should be hidden.
- * In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc.
- */
- LLAvalineListItem(bool hide_number = true);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setName(const std::string& name);
-
-private:
- bool mIsHideNumber;
-};
-
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index f41eb3daf4..dd0d06a8c8 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -36,6 +36,7 @@
#include "llstartup.h"
// Linden library includes
+#include "llavataractions.h" // for getProfileUrl
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
@@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
}
}
-
-void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
+void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
+ // this is the startup state when send_complete_agent_movement() message is sent.
+ // Before this messages won't work so don't bother trying
+ if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
+ {
+ return;
+ }
+
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+
// Suppress duplicate requests while waiting for a response from the network
if (isPendingRequest(avatar_id, type))
{
// waiting for a response, don't re-request
return;
}
- // indicate we're going to make a request
- addPendingRequest(avatar_id, type);
- std::vector strings;
- strings.push_back( avatar_id.asString() );
- send_generic_message(method, strings);
+ std::string cap;
+
+ switch (type)
+ {
+ case APT_PROPERTIES:
+ // indicate we're going to make a request
+ sendAvatarPropertiesRequestMessage(avatar_id);
+ // can use getRegionCapability("AgentProfile"), but it is heavy
+ // initAgentProfileCapRequest(avatar_id, cap);
+ break;
+ case APT_PICKS:
+ case APT_GROUPS:
+ case APT_NOTES:
+ if (cap.empty())
+ {
+ // indicate we're going to make a request
+ sendGenericRequest(avatar_id, type, method);
+ }
+ else
+ {
+ initAgentProfileCapRequest(avatar_id, cap);
+ }
+ break;
+ default:
+ sendGenericRequest(avatar_id, type, method);
+ break;
+ }
+}
+
+void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
+{
+ // indicate we're going to make a request
+ addPendingRequest(avatar_id, type);
+
+ std::vector strings;
+ strings.push_back(avatar_id.asString());
+ send_generic_message(method, strings);
+}
+
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
+
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
+ addPendingRequest(avatar_id, APT_PICKS);
+ addPendingRequest(avatar_id, APT_GROUPS);
+ addPendingRequest(avatar_id, APT_NOTES);
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
}
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
{
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the AvatarPropertiesRequest message
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
- {
- return;
- }
-
- if (isPendingRequest(avatar_id, APT_PROPERTIES))
- {
- // waiting for a response, don't re-request
- return;
- }
- // indicate we're going to make a request
- addPendingRequest(avatar_id, APT_PROPERTIES);
-
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
- gAgent.sendReliableMessage();
+ sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{
- sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
+ sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
}
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
@@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
return;
}
- LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
+ LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
// This value is required by sendAvatarPropertiesUpdate method.
//A profile should never be mature. (From the original code)
@@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
+// static
+void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ LLAvatarPropertiesProcessor* self = getInstance();
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->removePendingRequest(agent_id, APT_NOTES);
+ return;
+ }
+
+ // Avatar Data
+
+ LLAvatarData avatar_data;
+ std::string birth_date;
+
+ avatar_data.agent_id = agent_id;
+ avatar_data.avatar_id = agent_id;
+ avatar_data.image_id = result["sl_image_id"].asUUID();
+ avatar_data.fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data.partner_id = result["partner_id"].asUUID();
+ avatar_data.about_text = result["sl_about_text"].asString();
+ avatar_data.fl_about_text = result["fl_about_text"].asString();
+ avatar_data.born_on = result["member_since"].asDate();
+ avatar_data.profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data.flags = 0;
+ avatar_data.caption_index = 0;
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_NOTES);
+ self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
+}
+
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
@@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
That will suppress the warnings and be compatible with old server versions.
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
*/
+
+ LLInterestsData interests_data;
+
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
+ msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
+ self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
{
LLAvatarPicks avatar_picks;
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
@@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
+void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
+{
+ if(!interests_data)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_AvatarInterestsUpdate);
+ msg->nextBlockFast( _PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast( _PREHASH_PropertiesData);
+ msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
+ msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
+ msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
+ msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
+ msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index b063048c26..f778634d25 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -56,10 +56,22 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
+ APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
+struct LLInterestsData
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ U32 want_to_mask;
+ std::string want_to_text;
+ U32 skills_mask;
+ std::string skills_text;
+ std::string languages_text;
+};
+
struct LLAvatarData
{
LLUUID agent_id;
@@ -223,6 +235,8 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
+ void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
+
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@@ -234,6 +248,8 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+ static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
+
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
@@ -252,7 +268,10 @@ public:
protected:
- void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
+ void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
+ void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index fe94cd27b6..275f17b02a 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -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;
+ }
}
}
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 8d1e9a438e..fa7d5139ae 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -640,6 +640,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
+ mChangedBuddyIDs.insert(agent_related);
}
}
else
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index bdd516e1de..7ff24f64ac 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -48,6 +48,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@@ -118,6 +119,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
+ mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@@ -403,6 +405,48 @@ public:
{
LLAvatarActions::pay(getAvatarId());
}
+ else if (level == "report_abuse")
+ {
+ std::string time_string;
+ if (mTime > 0) // have frame time
+ {
+ time_t current_time = time_corrected();
+ time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime;
+
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] ["
+ + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32)message_time;
+ LLStringUtil::format(time_string, substitution);
+ }
+ else
+ {
+ // From history. This might be empty or not full.
+ // See LLChatLogParser::parse
+ time_string = getChild("time_box")->getValue().asString();
+
+ // Just add current date if not full.
+ // Should be fine since both times are supposed to be stl
+ if (!time_string.empty() && time_string.size() < 7)
+ {
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] " + time_string;
+
+ LLSD substitution;
+ // To avoid adding today's date to yesterday's timestamp,
+ // use creation time instead of current time
+ substitution["datetime"] = (S32)mCreationTime;
+ LLStringUtil::format(time_string, substitution);
+ }
+ }
+ LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText);
+ }
else if(level == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@@ -477,6 +521,10 @@ public:
{
return canModerate(userdata);
}
+ else if (level == "report_abuse")
+ {
+ return gAgentID != mAvatarID;
+ }
else if (level == "can_ban_member")
{
return canBanGroupMember(getAvatarId());
@@ -634,6 +682,12 @@ public:
mSessionID = chat.mSessionID;
mSourceType = chat.mSourceType;
+ // To be able to report a message, we need a copy of it's text
+ // and it's easier to store text directly than trying to get
+ // it from a lltextsegment or chat's mEditor
+ mText = chat.mText;
+ mTime = chat.mTime;
+
//*TODO overly defensive thing, source type should be maintained out there
if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
@@ -983,6 +1037,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
+ std::string mText;
+ F64 mTime; // IM's frame time
+ time_t mCreationTime; // Views's time
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 86e23e7c83..97b16a5e93 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
"can_invite_to_group" == command_name ||
"can_share" == command_name ||
"can_block" == command_name ||
- "can_pay" == command_name)
+ "can_pay" == command_name ||
+ "report_abuse" == command_name)
{
return is_p2p;
}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a685639427..9ec4fb085b 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("map"));
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
+ items.push_back(std::string("report_abuse"));
items.push_back(std::string("block_unblock"));
items.push_back(std::string("MuteText"));
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 7d4961c598..4d9ef99319 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -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));
}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index c6f0bf1ab5..237d58b4de 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -61,6 +61,7 @@ public:
void loadNotifications();
void updateNotifications();
void removeNotification(const char * name, const LLUUID& id);
+ void reset();
protected:
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index ffbb0bbee9..c075f7e8bd 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild()
// by default each time vs restoring the last value
mQualityRadioGroup->setSelectedIndex(0);
+ return true;
+}
+
+void LLFloater360Capture::onOpen(const LLSD& key)
+{
// Construct a URL pointing to the first page to load. Although
// we do not use this page for anything (after some significant
// design changes), we retain the code to load the start page
@@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild()
// We do an initial capture when the floater is opened, albeit at a 'preview'
// quality level (really low resolution, but really fast)
onCapture360ImagesBtn();
-
- return true;
}
// called when the user choose a quality level using
diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h
index 6da7ee074a..8f765c0b1b 100644
--- a/indra/newview/llfloater360capture.h
+++ b/indra/newview/llfloater360capture.h
@@ -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);
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index ab95bc06b8..0186c4aebe 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
+ mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe()
for(U32 i=0; imSpecialRenderMode = 1;
mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- mDummyAvatar->hideSkirt();
+
+ // on idle overall apperance update will set skirt to visible, so either
+ // call early or account for mSpecialRenderMode in updateMeshVisibility
+ mDummyAvatar->updateOverallAppearance();
+ mDummyAvatar->hideHair();
+ mDummyAvatar->hideSkirt();
// stop extraneous animations
mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
@@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
+ gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
index 45aea00a49..67c412dfa6 100644
--- a/indra/newview/llfloaterchatvoicevolume.cpp
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
{
LLInspect::onOpen(key);
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(key);
}
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp
new file mode 100644
index 0000000000..3520b0f67a
--- /dev/null
+++ b/indra/newview/llfloaterclassified.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file llfloaterclassified.cpp
+ * @brief LLFloaterClassified for displaying classifieds.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterclassified.h"
+
+LLFloaterClassified::LLFloaterClassified(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLFloaterClassified::~LLFloaterClassified()
+{
+}
+
+void LLFloaterClassified::onOpen(const LLSD& key)
+{
+ LLPanel* panel = findChild("main_panel", true);
+ if (panel)
+ {
+ panel->onOpen(key);
+ }
+ if (key.has("classified_name"))
+ {
+ setTitle(key["classified_name"].asString());
+ }
+ LLFloater::onOpen(key);
+}
+
+BOOL LLFloaterClassified::postBuild()
+{
+ return TRUE;
+}
+
+
+bool LLFloaterClassified::matchesKey(const LLSD& key)
+{
+ bool is_mkey_valid = mKey.has("classified_id");
+ bool is_key_valid = key.has("classified_id");
+ if (is_mkey_valid && is_key_valid)
+ {
+ return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
+ }
+ return is_mkey_valid == is_key_valid;
+}
+
+// eof
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterclassified.h
similarity index 51%
rename from indra/newview/llfloaterwebprofile.h
rename to indra/newview/llfloaterclassified.h
index 4c355e401b..2c95d82b2c 100644
--- a/indra/newview/llfloaterwebprofile.h
+++ b/indra/newview/llfloaterclassified.h
@@ -1,59 +1,45 @@
-/**
- * @file llfloaterwebprofile.h
- * @brief Avatar profile floater.
+/**
+ * @file llfloaterclassified.h
+ * @brief LLFloaterClassified for displaying classifieds.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#ifndef LL_LLFLOATERWEBPROFILE_H
-#define LL_LLFLOATERWEBPROFILE_H
+#ifndef LL_LLFLOATERCLASSIFIED_H
+#define LL_LLFLOATERCLASSIFIED_H
-#include "llfloaterwebcontent.h"
-#include "llviewermediaobserver.h"
+#include "llfloater.h"
-#include
-
-class LLMediaCtrl;
-
-/**
- * Displays avatar profile web page.
- */
-class LLFloaterWebProfile
-: public LLFloaterWebContent
+class LLFloaterClassified : public LLFloater
{
- LOG_CLASS(LLFloaterWebProfile);
+ LOG_CLASS(LLFloaterClassified);
public:
- typedef LLFloaterWebContent::Params Params;
+ LLFloaterClassified(const LLSD& key);
+ virtual ~LLFloaterClassified();
- LLFloaterWebProfile(const Params& key);
+ void onOpen(const LLSD& key) override;
+ BOOL postBuild() override;
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
-
- static LLFloater* create(const LLSD& key);
-
-private:
- void applyPreferredRect();
+ bool matchesKey(const LLSD& key) override;
};
-#endif // LL_LLFLOATERWEBPROFILE_H
-
+#endif // LL_LLFLOATERCLASSIFIED_H
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
new file mode 100644
index 0000000000..3b0c67415a
--- /dev/null
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llfloaterdisplayname.cpp
+ * @author Leyla Farazha
+ * @brief Implementation of the LLFloaterDisplayName class.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "llfloater.h"
+
+#include "llnotificationsutil.h"
+#include "llviewerdisplayname.h"
+
+#include "llnotifications.h"
+#include "llfloaterdisplayname.h"
+#include "llavatarnamecache.h"
+
+#include "llagent.h"
+
+
+class LLFloaterDisplayName : public LLFloater
+{
+public:
+ LLFloaterDisplayName(const LLSD& key);
+ virtual ~LLFloaterDisplayName() { }
+ /*virtual*/ BOOL postBuild();
+ void onSave();
+ void onCancel();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+private:
+
+ void onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content);
+};
+
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+ LLFloater(key)
+{
+}
+
+void LLFloaterDisplayName::onOpen(const LLSD& key)
+{
+ getChild("display_name_editor")->clear();
+ getChild("display_name_confirm")->clear();
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(gAgent.getID(), &av_name);
+
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
+
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // ...can't update until some time in the future
+ F64 next_update_local_secs =
+ av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
+ LLDate next_update_local(next_update_local_secs);
+ // display as "July 18 12:17 PM"
+ std::string next_update_string =
+ next_update_local.toHTTPDateString("%B %d %I:%M %p");
+ getChild("lockout_text")->setTextArg("[TIME]", next_update_string);
+ getChild("lockout_text")->setVisible(true);
+ getChild("save_btn")->setEnabled(false);
+ getChild("display_name_editor")->setEnabled(false);
+ getChild("display_name_confirm")->setEnabled(false);
+ getChild("cancel_btn")->setFocus(TRUE);
+
+ }
+ else
+ {
+ getChild("lockout_text")->setVisible(false);
+ getChild("save_btn")->setEnabled(true);
+ getChild("display_name_editor")->setEnabled(true);
+ getChild("display_name_confirm")->setEnabled(true);
+
+ }
+}
+
+BOOL LLFloaterDisplayName::postBuild()
+{
+ getChild("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
+ getChild("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
+
+ center();
+
+ return TRUE;
+}
+
+void LLFloaterDisplayName::onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content)
+{
+ if (success)
+ {
+ // Inform the user that the change took place, but will take a while
+ // to percolate.
+ LLSD args;
+ args["DISPLAY_NAME"] = content["display_name"];
+ LLNotificationsUtil::add("SetDisplayNameSuccess", args);
+ return;
+ }
+
+ // Request failed, notify the user
+ std::string error_tag = content["error_tag"].asString();
+ LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
+
+ // We might have a localized string for this message
+ // error_args will usually be empty from the server.
+ if (!error_tag.empty()
+ && LLNotifications::getInstance()->templateExists(error_tag))
+ {
+ LLNotificationsUtil::add(error_tag);
+ return;
+ }
+
+ // The server error might have a localized message for us
+ std::string lang_code = LLUI::getLanguage();
+ LLSD error_desc = content["error_description"];
+ if (error_desc.has( lang_code ))
+ {
+ LLSD args;
+ args["MESSAGE"] = error_desc[lang_code].asString();
+ LLNotificationsUtil::add("GenericAlert", args);
+ return;
+ }
+
+ // No specific error, throw a generic one
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+}
+
+void LLFloaterDisplayName::onCancel()
+{
+ setVisible(false);
+}
+
+void LLFloaterDisplayName::onSave()
+{
+ std::string display_name_utf8 = getChild("display_name_editor")->getValue().asString();
+ std::string display_name_confirm = getChild("display_name_confirm")->getValue().asString();
+
+ if (display_name_utf8.compare(display_name_confirm))
+ {
+ LLNotificationsUtil::add("SetDisplayNameMismatch");
+ return;
+ }
+
+ const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
+ LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
+ if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
+ {
+ LLSD args;
+ args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
+ LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
+ return;
+ }
+
+ if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
+ {
+ LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ }
+ else
+ {
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ }
+
+ setVisible(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterDisplayNameUtil::registerFloater()
+{
+ LLFloaterReg::add("display_name", "floater_display_name.xml",
+ &LLFloaterReg::build);
+}
diff --git a/indra/newview/llpanelme.h b/indra/newview/llfloaterdisplayname.h
similarity index 65%
rename from indra/newview/llpanelme.h
rename to indra/newview/llfloaterdisplayname.h
index 60e9d4317d..a00bf56712 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llfloaterdisplayname.h
@@ -1,6 +1,5 @@
/**
- * @file llpanelme.h
- * @brief Side tray "Me" (My Profile) panel
+ * @file llfloaterdisplayname.h
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,27 +23,16 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLPANELMEPROFILE_H
-#define LL_LLPANELMEPROFILE_H
+#ifndef LLFLOATERDISPLAYNAME_H
+#define LLFLOATERDISPLAYNAME_H
-#include "llpanel.h"
-#include "llpanelprofile.h"
-/**
-* Panel for displaying Agent's Picks and Classifieds panel.
-* LLPanelMe allows user to edit his picks and classifieds.
-*/
-class LLPanelMe : public LLPanelProfile
+namespace LLFloaterDisplayNameUtil
{
- LOG_CLASS(LLPanelMe);
+ // Register with LLFloaterReg
+ void registerFloater();
+}
-public:
- LLPanelMe();
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-};
-
-#endif // LL_LLPANELMEPROFILE_H
+#endif
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 6e326ff3cf..d17889bed1 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mObserver = new LLFloaterGestureObserver(this);
LLGestureMgr::instance().addObserver(mObserver);
- mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 1525bb9952..703b5d0011 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -45,6 +45,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
+#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::pay(userID);
}
+ else if ("report_abuse" == command)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(userID, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(userID, "not avaliable");
+ }
+ }
else if ("block_unblock" == command)
{
LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
@@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
}
// Handle all other options
- if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+ if (("can_invite" == item)
+ || ("can_chat_history" == item)
+ || ("can_share" == item)
+ || ("can_pay" == item)
+ || ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 524162ba51..e755e9924c 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView()
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
- if (mRootFolderId.notNull())
+ if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
+ {
+ std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason();
+ if (reason.empty())
+ {
+ text = LLTrans::getString("InventoryMarketplaceConnectionError");
+ }
+ else
+ {
+ LLSD args;
+ args["[REASON]"] = reason;
+ text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args);
+ }
+
+ title = LLTrans::getString("InventoryOutboxErrorTitle");
+ tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
+ }
+ else if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 2afd889609..b34961e8a2 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -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)
{
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index f93512eb3a..151e43e6b9 100644
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
@@ -42,6 +42,7 @@ public:
~LLFloaterMediaSettings();
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
static LLFloaterMediaSettings* getInstance();
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 58fbdba315..90390de52a 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -507,6 +507,15 @@ void LLFloaterModelPreview::onClickCalculateBtn()
toggleCalculateButton(false);
mUploadBtn->setEnabled(false);
+
+ //disable "simplification" UI
+ LLPanel* simplification_panel = getChild("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
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index dccef88e41..ad5e97e067 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
-#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 87973c2286..94261b2e4e 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,7 +72,7 @@ struct LLGiveMoneyInfo
mFloater(floater), mAmount(amount){}
};
-typedef boost::shared_ptr give_money_ptr;
+typedef std::shared_ptr give_money_ptr;
///----------------------------------------------------------------------------
/// Class LLFloaterPay
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 0e94d31d90..ac1dbe9867 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -332,60 +332,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
const LLAvatarData* pAvatarData = static_cast( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
- storeAvatarProperties( pAvatarData );
- processProfileProperties( pAvatarData );
+ mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
+ mAvatarDataInitialized = true;
+ getChild("online_searchresults")->setValue(mAllowPublish);
}
}
}
-void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
-{
- if (LLStartUp::getStartupState() == STATE_STARTED)
- {
- mAvatarProperties.avatar_id = pAvatarData->avatar_id;
- mAvatarProperties.image_id = pAvatarData->image_id;
- mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
- mAvatarProperties.about_text = pAvatarData->about_text;
- mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
- mAvatarProperties.profile_url = pAvatarData->profile_url;
- mAvatarProperties.flags = pAvatarData->flags;
- mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
-
- mAvatarDataInitialized = true;
- }
-}
-
-void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
-{
- getChild("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
-}
-
void LLFloaterPreference::saveAvatarProperties( void )
{
- const BOOL allowPublish = getChild("online_searchresults")->getValue();
+ const bool allowPublish = getChild("online_searchresults")->getValue();
- if (allowPublish)
- {
- mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
- }
+ if ((LLStartUp::getStartupState() == STATE_STARTED)
+ && mAvatarDataInitialized
+ && (allowPublish != mAllowPublish))
+ {
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
+ {
+ mAllowPublish = allowPublish;
- //
- // NOTE: We really don't want to send the avatar properties unless we absolutely
- // need to so we can avoid the accidental profile reset bug, so, if we're
- // logged in, the avatar data has been initialized and we have a state change
- // for the "allow publish" flag, then set the flag to its new value and send
- // the properties update.
- //
- // NOTE: The only reason we can not remove this update altogether is because of the
- // "allow publish" flag, the last remaining profile setting in the viewer
- // that doesn't exist in the web profile.
- //
- if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
- {
- mAvatarProperties.allow_publish = allowPublish;
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
+ }
+ }
+}
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
- }
+void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + gAgentID.asString();
+ LLSD data;
+ data["allow_publish"] = allow_publish;
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
}
BOOL LLFloaterPreference::postBuild()
@@ -911,7 +910,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
else
{
// Show beep, pop up dialog, etc.
- LL_INFOS() << "Can't close preferences!" << LL_ENDL;
+ LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
}
LLPanelLogin::updateLocationSelectorsVisibility();
@@ -1502,13 +1501,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
return false;
}
if (!root->hasName("labels"))
{
- LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
return false;
}
@@ -1528,7 +1527,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
}
else
{
- LL_WARNS() << filename << " failed to load" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
return false;
}
@@ -2435,7 +2434,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2462,7 +2461,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2568,7 +2567,7 @@ void LLPanelPreferenceControls::populateControlTable()
{
// Either unknown mode or MODE_SAVED_SETTINGS
// It doesn't have UI or actual settings yet
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
// Searchable columns were removed, mark searchables for an update
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences");
@@ -2608,7 +2607,7 @@ void LLPanelPreferenceControls::populateControlTable()
}
else
{
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
}
// explicit update to make sure table is ready for llsearchableui
@@ -2663,10 +2662,15 @@ void LLPanelPreferenceControls::cancel()
if (mConflictHandler[i].hasUnsavedChanges())
{
mConflictHandler[i].clear();
+ if (mEditingMode == i)
+ {
+ // cancel() can be called either when preferences floater closes
+ // or when child floater closes (like advanced graphical settings)
+ // in which case we need to clear and repopulate table
+ regenerateControls();
+ }
}
}
- pControlsTable->clearRows();
- pControlsTable->clearColumns();
}
void LLPanelPreferenceControls::saveSettings()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 3e4c853a08..a089fde9ff 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -100,9 +100,8 @@ public:
static void updateShowFavoritesCheckbox(bool val);
void processProperties( void* pData, EAvatarProcessorType type );
- void processProfileProperties(const LLAvatarData* pAvatarData );
- void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
+ static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector& names);
@@ -217,7 +216,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
- LLAvatarData mAvatarProperties;
+ bool mAllowPublish; // Allow showing agent in search
std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp
new file mode 100644
index 0000000000..6ccdace6c5
--- /dev/null
+++ b/indra/newview/llfloaterprofile.cpp
@@ -0,0 +1,170 @@
+/**
+ * @file llfloaterprofile.cpp
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofile.h"
+
+#include "llagent.h" //gAgent
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+LLFloaterProfile::LLFloaterProfile(const LLSD& key)
+ : LLFloater(key),
+ mAvatarId(key["id"].asUUID()),
+ mNameCallbackConnection()
+{
+ mDefaultRectForGroup = false;
+}
+
+LLFloaterProfile::~LLFloaterProfile()
+{
+ if (mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection.disconnect();
+ }
+}
+
+void LLFloaterProfile::onOpen(const LLSD& key)
+{
+ mPanelProfile->onOpen(key);
+
+ // Update the avatar name.
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLFloaterProfile::postBuild()
+{
+ mPanelProfile = findChild(PANEL_PROFILE_VIEW);
+
+ return TRUE;
+}
+
+void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ {
+ if (mPanelProfile->hasUnpublishedClassifieds())
+ {
+ LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
+ }
+ else if (mPanelProfile->hasUnsavedChanges())
+ {
+ LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
+ }
+ else
+ {
+ closeFloater();
+ }
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (can_save)
+ {
+ // savable content
+
+ if (option == 0) // Save
+ {
+ mPanelProfile->commitUnsavedChanges();
+ closeFloater();
+ }
+ if (option == 1) // Discard
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+ else
+ {
+ // classifieds
+
+ if (option == 0) // Ok
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+
+}
+
+void LLFloaterProfile::createPick(const LLPickData &data)
+{
+ mPanelProfile->createPick(data);
+}
+
+void LLFloaterProfile::showPick(const LLUUID& pick_id)
+{
+ mPanelProfile->showPick(pick_id);
+}
+
+bool LLFloaterProfile::isPickTabSelected()
+{
+ return mPanelProfile->isPickTabSelected();
+}
+
+void LLFloaterProfile::refreshName()
+{
+ if (!mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+ }
+
+ LLPanelProfileSecondLife *panel = findChild("panel_profile_secondlife");
+ if (panel)
+ {
+ panel->refreshName();
+ }
+}
+
+void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
+{
+ mPanelProfile->showClassified(classified_id, edit);
+}
+
+void LLFloaterProfile::createClassified()
+{
+ mPanelProfile->createClassified();
+}
+
+void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mNameCallbackConnection.disconnect();
+ setTitle(av_name.getCompleteName());
+}
+
+// eof
diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h
new file mode 100644
index 0000000000..b3ed02fc2c
--- /dev/null
+++ b/indra/newview/llfloaterprofile.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloaterprofile.h
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILE_H
+#define LL_LLFLOATERPROFILE_H
+
+#include "llavatarnamecache.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloater.h"
+
+class LLPanelProfile;
+
+class LLFloaterProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterProfile);
+public:
+ LLFloaterProfile(const LLSD& key);
+ virtual ~LLFloaterProfile();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+ void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ void refreshName();
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+private:
+ LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ LLPanelProfile* mPanelProfile;
+
+ LLUUID mAvatarId;
+};
+
+#endif // LL_LLFLOATERPROFILE_H
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
new file mode 100644
index 0000000000..bf1f56a6d1
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llfloaterprofiletexture.cpp
+ * @brief LLFloaterProfileTexture class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofiletexture.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llpreview.h" // fors constants
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "lltextureview.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+
+
+LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
+ : LLFloater(LLSD())
+ , mUpdateDimensions(TRUE)
+ , mLastHeight(0)
+ , mLastWidth(0)
+ , mImage(NULL)
+ , mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_texture.xml");
+}
+
+LLFloaterProfileTexture::~LLFloaterProfileTexture()
+{
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+
+// virtual
+BOOL LLFloaterProfileTexture::postBuild()
+{
+ mProfileIcon = getChild("profile_pic");
+
+ mCloseButton = getChild("close_btn");
+ mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloater::reshape(width, height, called_from_parent);
+}
+
+// It takes a while until we get height and width information.
+// When we receive it, reshape the window accordingly.
+void LLFloaterProfileTexture::updateDimensions()
+{
+ if (mImage.isNull())
+ {
+ return;
+ }
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ return;
+ }
+
+ S32 img_width = mImage->getFullWidth();
+ S32 img_height = mImage->getFullHeight();
+
+ if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
+ || mLastWidth != img_width
+ || mLastHeight != img_height)
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ // Asset has been fully loaded
+ mUpdateDimensions = TRUE;
+ }
+
+ mLastHeight = img_height;
+ mLastWidth = img_width;
+
+ // Reshape the floater only when required
+ if (mUpdateDimensions)
+ {
+ mUpdateDimensions = FALSE;
+
+ LLRect old_floater_rect = getRect();
+ LLRect old_image_rect = mProfileIcon->getRect();
+ S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
+ S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
+
+ const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
+
+ S32 biggest_dim = llmax(width, height);
+ if (biggest_dim > MAX_DIMENTIONS)
+ {
+ F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
+ width *= scale_down;
+ height *= scale_down;
+ }
+
+ //reshape floater
+ reshape(width, height);
+
+ gFloaterView->adjustToFitScreen(this, FALSE);
+ }
+}
+
+void LLFloaterProfileTexture::draw()
+{
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+void LLFloaterProfileTexture::onOpen(const LLSD& key)
+{
+ mCloseButton->setFocus(true);
+}
+
+void LLFloaterProfileTexture::resetAsset()
+{
+ mProfileIcon->setValue("Generic_Person_Large");
+ mImageID = LLUUID::null;
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
+{
+ if (mImageID != image_id)
+ {
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ mProfileIcon->setValue(image_id);
+ mImageID = image_id;
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mImageOldBoostLevel = mImage->getBoostLevel();
+
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
+ 0, TRUE, FALSE, new LLHandle(getHandle()), &mCallbackTextureList);
+
+ mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
+ }
+ else
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ }
+
+ mUpdateDimensions = TRUE;
+ updateDimensions();
+}
+
+// static
+void LLFloaterProfileTexture::onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ LLHandle* handle = (LLHandle*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLFloaterProfileTexture* floater = static_cast(handle->get());
+ if (floater && success)
+ {
+ floater->mUpdateDimensions = TRUE;
+ floater->updateDimensions();
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h
new file mode 100644
index 0000000000..66a61213dd
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterprofiletexture.h
+ * @brief LLFloaterProfileTexture class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILETEXTURE_H
+#define LL_LLFLOATERPROFILETEXTURE_H
+
+#include "llfloater.h"
+#include "llviewertexture.h"
+
+class LLButton;
+class LLImageRaw;
+class LLIconCtrl;
+
+class LLFloaterProfileTexture : public LLFloater
+{
+public:
+ LLFloaterProfileTexture(LLView* owner);
+ ~LLFloaterProfileTexture();
+
+ void draw() override;
+ void onOpen(const LLSD& key) override;
+
+ void resetAsset();
+ void loadAsset(const LLUUID &image_id);
+
+
+ static void onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+protected:
+ BOOL postBuild() override;
+
+private:
+ void updateDimensions();
+
+ LLUUID mImageID;
+ LLPointer mImage;
+ S32 mImageOldBoostLevel;
+ S32 mAssetStatus;
+ F32 mContextConeOpacity;
+ S32 mLastHeight;
+ S32 mLastWidth;
+ BOOL mUpdateDimensions;
+
+ LLHandle mOwnerHandle;
+ LLIconCtrl* mProfileIcon;
+ LLButton* mCloseButton;
+
+ LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
+};
+#endif // LL_LLFLOATERPROFILETEXTURE_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 296e155d28..293ccc344c 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -1322,6 +1322,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
{
+ static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
{
std::string buffer;
@@ -1343,17 +1344,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
return FALSE;
}
- if (width > 512 || height > 512)
+ if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
{
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_SIZE_X"] = width;
args["TEXTURE_SIZE_Y"] = height;
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainSize", args);
return FALSE;
@@ -3683,7 +3686,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin
if (!search_string.empty())
{
listCtrl->setSearchColumn(0); // name column
- listCtrl->selectItemByPrefix(search_string, FALSE);
+ listCtrl->searchItems(search_string, false, true);
}
else
{
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index b73755cf4e..2df4ca973d 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -54,6 +54,7 @@
#include "llbutton.h"
#include "llfloaterreg.h"
#include "lltexturectrl.h"
+#include "lltexteditor.h"
#include "llscrolllistctrl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
@@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
- std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
- mMCDList.clear();
-
delete mResourceDatap;
}
@@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin
show(avatar_id, avatar_name);
}
+// static
+void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description)
+{
+ show(avatar_id, avatar_name);
+
+ LLStringUtil::format_map_t args;
+ args["[MSG_TIME]"] = time;
+ args["[MSG_DESCRIPTION]"] = description;
+
+ LLFloaterReporter *self = LLFloaterReg::findTypedInstance("reporter");
+ if (self)
+ {
+ std::string description = self->getString("chat_report_format", args);
+ self->getChild("details_edit")->setValue(description);
+ }
+}
+
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
getChild("object_name")->setValue(object_name);
@@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)
mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
-
-
-// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance("reporter");
-// if (self)
-// {
-// self->getChild("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("reporter");
-// if (self)
-// {
-// LLTextEditor* text = self->getChild("details_edit");
-// if (text)
-// {
-// text->insertText(description);
-// }
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index c678df7155..b6c70e866d 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -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);
@@ -114,10 +113,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);
@@ -144,7 +141,6 @@ private:
BOOL mPicking;
LLVector3 mPosition;
BOOL mCopyrightWarningSeen;
- std::list mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2e1fbb09e0..bb3ed77772 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -57,10 +57,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
@@ -72,7 +72,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
@@ -83,8 +83,9 @@ public:
LLSearchHandler gSearchHandler;
LLFloaterSearch::SearchQuery::SearchQuery()
-: category("category", ""),
- query("query")
+: category("category", ""),
+ collection("collection", ""),
+ query("query")
{}
LLFloaterSearch::LLFloaterSearch(const Params& key) :
@@ -93,16 +94,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()
@@ -157,31 +158,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::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;
diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h
index 35b268e1b2..cc77ce696f 100644
--- a/indra/newview/llfloatersearch.h
+++ b/indra/newview/llfloatersearch.h
@@ -49,6 +49,7 @@ public:
struct SearchQuery : public LLInitParam::Block
{
Optional category;
+ Optional collection;
Optional query;
SearchQuery();
@@ -84,7 +85,8 @@ public:
private:
/*virtual*/ BOOL postBuild();
- LLSD mCategoryPaths;
+ std::set mSearchType;
+ std::set mCollectionType;
U8 mSearchGodLevel;
};
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 77a04bc5d7..b6acba6558 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -46,7 +46,6 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
-#include "llmediactrl.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelcontents.h"
@@ -240,7 +239,6 @@ BOOL LLFloaterTools::postBuild()
mRadioGroupMove = getChild("move_radio_group");
mRadioGroupEdit = getChild("edit_radio_group");
mBtnGridOptions = getChild("Options...");
- mTitleMedia = getChild("title_media");
mBtnLink = getChild("link_btn");
mBtnUnlink = getChild("unlink_btn");
@@ -329,7 +327,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
- mTitleMedia(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
@@ -369,8 +366,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mLandImpactsObserver(NULL),
mDirty(TRUE),
- mHasSelection(TRUE),
- mNeedMediaTitle(TRUE)
+ mHasSelection(TRUE)
{
gFloaterTools = this;
@@ -394,9 +390,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
- mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
@@ -553,7 +546,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
- refreshMedia();
+ mPanelFace->refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
@@ -580,9 +573,6 @@ void LLFloaterTools::draw()
mDirty = FALSE;
}
- // grab media name/title and update the UI widget
- updateMediaTitle();
-
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
@@ -906,8 +896,7 @@ void LLFloaterTools::onClose(bool app_quitting)
LLViewerJoystick::getInstance()->moveAvatar(false);
// destroy media source used to grab media title
- if( mTitleMedia )
- mTitleMedia->unloadMediaSource();
+ mPanelFace->unloadMedia();
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
@@ -1160,51 +1149,6 @@ void LLFloaterTools::onFocusReceived()
LLFloater::onFocusReceived();
}
-// Media stuff
-void LLFloaterTools::refreshMedia()
-{
- getMediaState();
-}
-
-bool LLFloaterTools::selectedMediaEditable()
-{
- U32 owner_mask_on;
- U32 owner_mask_off;
- U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
- &owner_mask_on, &owner_mask_off );
- U32 group_mask_on;
- U32 group_mask_off;
- U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
- &group_mask_on, &group_mask_off );
- U32 everyone_mask_on;
- U32 everyone_mask_off;
- S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
- &everyone_mask_on, &everyone_mask_off );
-
- bool selected_Media_editable = false;
-
- // if perms we got back are valid
- if ( valid_owner_perms &&
- valid_group_perms &&
- valid_everyone_perms )
- {
-
- if ( ( owner_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) )
- {
- selected_Media_editable = true;
- }
- else
- // user is NOT allowed to press the RESET button
- {
- selected_Media_editable = false;
- };
- };
-
- return selected_Media_editable;
-}
-
void LLFloaterTools::updateLandImpacts()
{
LLParcel *parcel = mParcelSelection->getParcel();
@@ -1221,784 +1165,3 @@ void LLFloaterTools::updateLandImpacts()
}
}
-void LLFloaterTools::getMediaState()
-{
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* first_object = selected_objects->getFirstObject();
- LLTextBox* media_info = getChild("media_info");
-
- if( !(first_object
- && first_object->getPCode() == LL_PCODE_VOLUME
- &&first_object->permModify()
- ))
- {
- getChildView("add_media")->setEnabled(FALSE);
- media_info->clear();
- clearMediaSettings();
- return;
- }
-
- std::string url = first_object->getRegion()->getCapability("ObjectMedia");
- bool has_media_capability = (!url.empty());
-
- if(!has_media_capability)
- {
- getChildView("add_media")->setEnabled(FALSE);
- LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
- clearMediaSettings();
- return;
- }
-
- BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
- && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
- || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
- bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
-
- // Check modify permissions and whether any selected objects are in
- // the process of being fetched. If they are, then we're not editable
- if (editable)
- {
- LLObjectSelection::iterator iter = selected_objects->begin();
- LLObjectSelection::iterator end = selected_objects->end();
- for ( ; iter != end; ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = dynamic_cast(node->getObject());
- if (NULL != object)
- {
- if (!object->permModify())
- {
- LL_INFOS("LLFloaterToolsMedia")
- << "Selection not editable due to lack of modify permissions on object id "
- << object->getID() << LL_ENDL;
-
- editable = false;
- break;
- }
- // XXX DISABLE this for now, because when the fetch finally
- // does come in, the state of this floater doesn't properly
- // update. Re-selecting fixes the problem, but there is
- // contention as to whether this is a sufficient solution.
-// if (object->isMediaDataBeingFetched())
-// {
-// LL_INFOS("LLFloaterToolsMedia")
-// << "Selection not editable due to media data being fetched for object id "
-// << object->getID() << LL_ENDL;
-//
-// editable = false;
-// break;
-// }
- }
- }
- }
-
- // Media settings
- bool bool_has_media = false;
- struct media_functor : public LLSelectedTEGetFunctor
- {
- bool get(LLViewerObject* object, S32 face)
- {
- LLTextureEntry *te = object->getTE(face);
- if (te)
- {
- return te->hasMedia();
- }
- return false;
- }
- } func;
-
-
- // check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
-
- const LLMediaEntry default_media_data;
-
- struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
- {
- functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- LLMediaEntry get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return *(object->getTE(face)->getMediaData());
- return mMediaEntry;
- };
-
- const LLMediaEntry& mMediaEntry;
-
- } func_media_data(default_media_data);
-
- LLMediaEntry media_data_get;
- LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
-
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- std::string media_title = "";
- // update UI depending on whether "object" (prim or face) has media
- // and whether or not you are allowed to edit it.
-
- getChildView("add_media")->setEnabled(editable);
- // IF all the faces have media (or all dont have media)
- if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
- {
- // TODO: get media title and set it.
- media_info->clear();
- // if identical is set, all faces are same (whether all empty or has the same media)
- if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- // else all faces might be empty.
- }
- else // there' re Different Medias' been set on on the faces.
- {
- media_title = multi_media_info_str;
- }
-
- getChildView("delete_media")->setEnabled(bool_has_media && editable );
- // TODO: display a list of all media on the face - use 'identical' flag
- }
- else // not all face has media but at least one does.
- {
- // seleted faces have not identical value
- LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
-
- if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
- {
- media_title = multi_media_info_str;
- }
- else
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- }
-
- getChildView("delete_media")->setEnabled(TRUE);
- }
-
- navigateToTitleMedia(media_title);
- media_info->setText(media_title);
-
- // load values for media settings
- updateMediaSettings();
-
- LLFloaterMediaSettings::initValues(mMediaSettings, editable );
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to add media to a prim or prim face
-void LLFloaterTools::onClickBtnAddMedia()
-{
- // check if multiple faces are selected
- if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
- {
- LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
- }
- else
- {
- onClickBtnEditMedia();
- }
-}
-
-// static
-bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- gFloaterTools->onClickBtnEditMedia();
- break;
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to edit existing media settings on a prim or prim face
-// TODO: test if there is media on the item and only allow editing if present
-void LLFloaterTools::onClickBtnEditMedia()
-{
- refreshMedia();
- LLFloaterReg::showInstance("media_settings");
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to delete media from a prim or prim face
-void LLFloaterTools::onClickBtnDeleteMedia()
-{
- LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
-}
-
-
-// static
-bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
- if(LLFloaterReg::instanceVisible("media_settings"))
- {
- LLFloaterReg::hideInstance("media_settings");
- }
- break;
-
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::clearMediaSettings()
-{
- LLFloaterMediaSettings::clearValues(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::navigateToTitleMedia( const std::string url )
-{
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- if (url.empty() || multi_media_info_str == url)
- {
- // nothing to show
- mNeedMediaTitle = false;
- }
- else if (mTitleMedia)
- {
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
-
- if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin?
- {
- // if it's a movie, we don't want to hear it
- media_plugin->setVolume( 0 );
- };
-
- // check if url changed or if we need a new media source
- if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
- {
- mTitleMedia->navigateTo( url );
- }
-
- // flag that we need to update the title (even if no request were made)
- mNeedMediaTitle = true;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaTitle()
-{
- // only get the media name if we need it
- if ( ! mNeedMediaTitle )
- return;
-
- // get plugin impl
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
- if ( media_plugin )
- {
- // get the media name (asynchronous - must call repeatedly)
- std::string media_title = media_plugin->getMediaName();
-
- // only replace the title if what we get contains something
- if ( ! media_title.empty() )
- {
- // update the UI widget
- LLTextBox* media_title_field = getChild("media_info");
- if ( media_title_field )
- {
- media_title_field->setText( media_title );
-
- // stop looking for a title when we get one
- // FIXME: check this is the right approach
- mNeedMediaTitle = false;
- };
- };
- };
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaSettings()
-{
- bool identical( false );
- std::string base_key( "" );
- std::string value_str( "" );
- int value_int = 0;
- bool value_bool = false;
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- // TODO: (CP) refactor this using something clever or boost or both !!
-
- const LLMediaEntry default_media_data;
-
- // controls
- U8 value_u8 = default_media_data.getControls();
- struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
- {
- functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
-
- U8 get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getControls();
- return mMediaEntry.getControls();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_controls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
- base_key = std::string( LLMediaEntry::CONTROLS_KEY );
- mMediaSettings[ base_key ] = value_u8;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // First click (formerly left click)
- value_bool = default_media_data.getFirstClickInteract();
- struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getFirstClickInteract();
- return mMediaEntry.getFirstClickInteract();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_first_click(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
- base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Home URL
- value_str = default_media_data.getHomeURL();
- struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHomeURL();
- return mMediaEntry.getHomeURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_home_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
- base_key = std::string( LLMediaEntry::HOME_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Current URL
- value_str = default_media_data.getCurrentURL();
- struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getCurrentURL();
- return mMediaEntry.getCurrentURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_current_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
- base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto zoom
- value_bool = default_media_data.getAutoZoom();
- struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
- {
-
- functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoZoom();
- return mMediaEntry.getAutoZoom();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_zoom(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto play
- //value_bool = default_media_data.getAutoPlay();
- // set default to auto play TRUE -- angela EXT-5172
- value_bool = true;
- struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoPlay();
- //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_play(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
-
- // Auto scale
- // set default to auto scale TRUE -- angela EXT-5172
- //value_bool = default_media_data.getAutoScale();
- value_bool = true;
- struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoScale();
- // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_scale(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto loop
- value_bool = default_media_data.getAutoLoop();
- struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoLoop();
- return mMediaEntry.getAutoLoop();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_loop(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // width pixels (if not auto scaled)
- value_int = default_media_data.getWidthPixels();
- struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWidthPixels();
- return mMediaEntry.getWidthPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_width_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
- base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // height pixels (if not auto scaled)
- value_int = default_media_data.getHeightPixels();
- struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHeightPixels();
- return mMediaEntry.getHeightPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_height_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
- base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Enable Alt image
- value_bool = default_media_data.getAltImageEnable();
- struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAltImageEnable();
- return mMediaEntry.getAltImageEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_enable_alt_image(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
- base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_control(default_media_data);
- identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_interact(default_media_data);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist enable
- value_bool = default_media_data.getWhiteListEnable();
- struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteListEnable();
- return mMediaEntry.getWhiteListEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_enable(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
- base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist URLs
- std::vector value_vector_str = default_media_data.getWhiteList();
- struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector >
- {
- functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::vector get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteList();
- return mMediaEntry.getWhiteList();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_urls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
- base_key = std::string( LLMediaEntry::WHITELIST_KEY );
- mMediaSettings[ base_key ].clear();
- std::vector< std::string >::iterator iter = value_vector_str.begin();
- while( iter != value_vector_str.end() )
- {
- std::string white_list_url = *iter;
- mMediaSettings[ base_key ].append( white_list_url );
- ++iter;
- };
-
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-}
-
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index ffff564ad4..3bb6492a6e 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -44,7 +44,6 @@ class LLRadioGroup;
class LLSlider;
class LLTabContainer;
class LLTextBox;
-class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -98,11 +97,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);
@@ -111,13 +105,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();
@@ -193,19 +180,12 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
- LLMediaCtrl *mTitleMedia;
- bool mNeedMediaTitle;
-
private:
BOOL mDirty;
BOOL mHasSelection;
std::map mStatusText;
-
-protected:
- LLSD mMediaSettings;
-
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index d5c2ad5f81..917d6dfcd0 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -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(mPanelLandMediaHandle.get());
- if(panel_face)
- {
- panel_face->setMediaType(mime_type);
- panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
- }
-
- }
getChildView("loading_label")->setVisible( false);
closeFloater();
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 59e1f49f81..23f19dd5aa 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -127,7 +127,7 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(data);
getChild("avatar_name")->setValue("");
updateVolumeControls();
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
deleted file mode 100644
index 891bb90c0e..0000000000
--- a/indra/newview/llfloaterwebprofile.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file llfloaterwebprofile.cpp
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterwebprofile.h"
-
-#include "llviewercontrol.h"
-
-LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
- LLFloaterWebContent(key)
-{
-}
-
-void LLFloaterWebProfile::onOpen(const LLSD& key)
-{
- Params p(key);
- p.show_chrome(true);
- p.window_class("profile");
- p.allow_address_entry(false);
- p.trusted_content(true);
- LLFloaterWebContent::onOpen(p);
- applyPreferredRect();
-}
-
-// virtual
-void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
-{
- LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
-
- if (by_user && !isMinimized())
- {
- LL_DEBUGS() << "Storing new rect" << LL_ENDL;
- gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
- }
-
- LLFloaterWebContent::handleReshape(new_rect, by_user);
-}
-
-LLFloater* LLFloaterWebProfile::create(const LLSD& key)
-{
- LLFloaterWebContent::Params p(key);
- preCreate(p);
- return new LLFloaterWebProfile(p);
-}
-
-void LLFloaterWebProfile::applyPreferredRect()
-{
- const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
- LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
-
- // Don't override position that may have been set by floater stacking code.
- LLRect new_rect = getRect();
- new_rect.setLeftTopAndSize(
- new_rect.mLeft, new_rect.mTop,
- preferred_rect.getWidth(), preferred_rect.getHeight());
- setShape(new_rect);
-}
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 09235d8fb2..977023cfe4 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -1008,7 +1008,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" );
}
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0be748ace9..e395da7f1e 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -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
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 2fb912a930..f5679d7d85 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -116,6 +116,7 @@ private:
}
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);
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 91ab445273..7c8e8279c2 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -185,7 +185,7 @@ private:
std::set mLoadingAssets;
// LLEventHost interface
- boost::shared_ptr mListener;
+ std::shared_ptr mListener;
};
#endif
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e7bc2a9268..84a1278767 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
// static
void LLGroupActions::search()
{
- LLFloaterReg::showInstance("search");
+ LLFloaterReg::showInstance("search", LLSD().with("collection", "groups"));
}
// static
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 62414d3bbb..32af2592d3 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -45,7 +45,6 @@
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register r("group_list");
-S32 LLGroupListItem::sIconWidth = 0;
class LLGroupComparator : public LLFlatListView::ItemComparator
{
@@ -65,21 +64,81 @@ public:
}
};
-static const LLGroupComparator GROUP_COMPARATOR;
+class LLSharedGroupComparator : public LLFlatListView::ItemComparator
+{
+public:
+ LLSharedGroupComparator() {};
+ /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ const LLGroupListItem* group_item1 = static_cast(item1);
+ std::string name1 = group_item1->getGroupName();
+ bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true);
+
+ const LLGroupListItem* group_item2 = static_cast(item2);
+ std::string name2 = group_item2->getGroupName();
+ bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true);
+
+ if (item2_shared != item1_shared)
+ {
+ return item1_shared;
+ }
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+ }
+};
+
+static LLGroupComparator GROUP_COMPARATOR;
+static LLSharedGroupComparator SHARED_GROUP_COMPARATOR;
+
+LLGroupList::Params::Params()
+: for_agent("for_agent", true)
+{
+}
LLGroupList::LLGroupList(const Params& p)
: LLFlatListViewEx(p)
+ , mForAgent(p.for_agent)
, mDirty(true) // to force initial update
+ , mShowIcons(false)
+ , mShowNone(true)
{
- // Listen for agent group changes.
- gAgent.addListener(this, "new group");
-
- mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// Set default sort order.
- setComparator(&GROUP_COMPARATOR);
+ if (mForAgent)
+ {
+ setComparator(&GROUP_COMPARATOR);
+ }
+ else
+ {
+ // shared groups first
+ setComparator(&SHARED_GROUP_COMPARATOR);
+ }
+
+ if (mForAgent)
+ {
+ enableForAgent(true);
+ }
+}
+
+LLGroupList::~LLGroupList()
+{
+ if (mForAgent) gAgent.removeListener(this);
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
+}
+
+void LLGroupList::enableForAgent(bool show_icons)
+{
+ mForAgent = true;
+
+ mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
+
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -94,12 +153,6 @@ LLGroupList::LLGroupList(const Params& p)
mContextMenuHandle = context_menu->getHandle();
}
-LLGroupList::~LLGroupList()
-{
- gAgent.removeListener(this);
- if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
-}
-
// virtual
void LLGroupList::draw()
{
@@ -114,12 +167,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- LLToggleableMenu* context_menu = mContextMenuHandle.get();
- if (context_menu && size() > 0)
- {
- context_menu->buildDrawLabels();
- context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, context_menu, x, y);
+ if (mForAgent)
+ {
+ LLToggleableMenu* context_menu = mContextMenuHandle.get();
+ if (context_menu && size() > 0)
+ {
+ context_menu->buildDrawLabels();
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
}
return handled;
@@ -132,7 +188,7 @@ BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask)
// Handle double click only for the selected item in the list, skip clicks on empty space.
if (handled)
{
- if (mDoubleClickSignal)
+ if (mDoubleClickSignal && getItemsRect().pointInRect(x, y))
{
(*mDoubleClickSignal)(this, x, y, mask);
}
@@ -164,34 +220,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
void LLGroupList::refresh()
{
- const LLUUID& highlight_id = gAgent.getGroupID();
- S32 count = gAgent.mGroups.size();
- LLUUID id;
- bool have_filter = !mNameFilter.empty();
+ if (mForAgent)
+ {
+ const LLUUID& highlight_id = gAgent.getGroupID();
+ S32 count = gAgent.mGroups.size();
+ LLUUID id;
+ bool have_filter = !mNameFilter.empty();
- clear();
+ clear();
- for(S32 i = 0; i < count; ++i)
- {
- id = gAgent.mGroups.at(i).mID;
- const LLGroupData& group_data = gAgent.mGroups.at(i);
- if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
- continue;
- addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
- }
+ for(S32 i = 0; i < count; ++i)
+ {
+ id = gAgent.mGroups.at(i).mID;
+ const LLGroupData& group_data = gAgent.mGroups.at(i);
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
+ continue;
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
+ }
- // Sort the list.
- sort();
+ // Sort the list.
+ sort();
- // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
- // but only if some real groups exists. EXT-4838
- if (!have_filter && count > 0)
- {
- std::string loc_none = LLTrans::getString("GroupsNone");
- addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
- }
+ // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
+ // but only if some real groups exists. EXT-4838
+ if (!have_filter && count > 0 && mShowNone)
+ {
+ std::string loc_none = LLTrans::getString("GroupsNone");
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
+ }
- selectItemByUUID(highlight_id);
+ selectItemByUUID(highlight_id);
+ }
+ else
+ {
+ clear();
+
+ for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it)
+ {
+ addNewItem(it->second, it->first, LLUUID::null, ADD_BOTTOM);
+ }
+
+ // Sort the list.
+ sort();
+ }
setDirty(false);
onCommit();
@@ -212,13 +283,19 @@ void LLGroupList::toggleIcons()
}
}
+void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
+{
+ mGroups = group_list;
+ setDirty(true);
+}
+
//////////////////////////////////////////////////////////////////////////
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile)
{
- LLGroupListItem* item = new LLGroupListItem();
+ LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
item->setGroupID(id);
item->setName(name, mNameFilter);
@@ -227,7 +304,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->getChildView("info_btn")->setVisible( false);
item->getChildView("profile_btn")->setVisible( false);
item->setGroupIconVisible(mShowIcons);
-
+ if (!mShowIcons)
+ {
+ item->setVisibleInProfile(visible_in_profile);
+ }
addItem(item, id, pos);
// setCommentVisible(false);
@@ -243,6 +323,29 @@ bool LLGroupList::handleEvent(LLPointer event, const LLSD&
return true;
}
+ if (event->desc() == "value_changed")
+ {
+ LLSD data = event->getValue();
+ if (data.has("group_id") && data.has("visible"))
+ {
+ LLUUID group_id = data["group_id"].asUUID();
+ bool visible = data["visible"].asBoolean();
+
+ std::vector items;
+ getItems(items);
+ for (std::vector::iterator it = items.begin(); it != items.end(); ++it)
+ {
+ LLGroupListItem* item = dynamic_cast(*it);
+ if (item && item->getGroupID() == group_id)
+ {
+ item->setVisibleInProfile(visible);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
return false;
}
@@ -294,21 +397,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
/* LLGroupListItem implementation */
/************************************************************************/
-LLGroupListItem::LLGroupListItem()
+LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons)
: LLPanel(),
mGroupIcon(NULL),
mGroupNameBox(NULL),
mInfoBtn(NULL),
-mGroupID(LLUUID::null)
+mProfileBtn(NULL),
+mVisibilityHideBtn(NULL),
+mVisibilityShowBtn(NULL),
+mGroupID(LLUUID::null),
+mForAgent(for_agent)
{
- buildFromFile( "panel_group_list_item.xml");
-
- // Remember group icon width including its padding from the name text box,
- // so that we can hide and show the icon again later.
- if (!sIconWidth)
- {
- sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
- }
+ if (show_icons)
+ {
+ buildFromFile( "panel_group_list_item.xml");
+ }
+ else
+ {
+ buildFromFile( "panel_group_list_item_short.xml");
+ }
}
LLGroupListItem::~LLGroupListItem()
@@ -325,7 +432,25 @@ BOOL LLGroupListItem::postBuild()
mInfoBtn = getChild("info_btn");
mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
- childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
+ mProfileBtn = getChild("profile_btn");
+ mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
+
+ mVisibilityHideBtn = findChild("visibility_hide_btn");
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); });
+ }
+ mVisibilityShowBtn = findChild("visibility_show_btn");
+ if (mVisibilityShowBtn)
+ {
+ mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); });
+ }
+
+ // Remember group icon width including its padding from the name text box,
+ // so that we can hide and show the icon again later.
+ // Also note that panel_group_list_item and panel_group_list_item_short
+ // have icons of different sizes so we need to figure it per file.
+ mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
return TRUE;
}
@@ -344,7 +469,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
if (mGroupID.notNull()) // don't show the info button for the "none" group
{
mInfoBtn->setVisible(true);
- getChildView("profile_btn")->setVisible( true);
+ mProfileBtn->setVisible(true);
+ if (mForAgent && mVisibilityHideBtn)
+ {
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
+ mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ }
+ }
}
LLPanel::onMouseEnter(x, y, mask);
@@ -354,7 +488,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
getChildView("hovered_icon")->setVisible( false);
mInfoBtn->setVisible(false);
- getChildView("profile_btn")->setVisible( false);
+ mProfileBtn->setVisible(false);
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setVisible(false);
+ mVisibilityShowBtn->setVisible(false);
+ }
LLPanel::onMouseLeave(x, y, mask);
}
@@ -372,7 +511,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
mID = group_id;
mGroupID = group_id;
- setActive(group_id == gAgent.getGroupID());
+
+ if (mForAgent)
+ {
+ // Active group should be bold.
+ setBold(group_id == gAgent.getGroupID());
+ }
+ else
+ {
+ // Groups shared with the agent should be bold
+ setBold(gAgent.isInGroup(group_id, true));
+ }
LLGroupMgr::getInstance()->addObserver(this);
}
@@ -393,24 +542,28 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
// Move the group name horizontally by icon size + its distance from the group name.
LLRect name_rect = mGroupNameBox->getRect();
- name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
+ name_rect.mLeft += visible ? mIconWidth : -mIconWidth;
mGroupNameBox->setRect(name_rect);
}
+void LLGroupListItem::setVisibleInProfile(bool visible)
+{
+ mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
+}
+
//////////////////////////////////////////////////////////////////////////
// Private Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupListItem::setActive(bool active)
+void LLGroupListItem::setBold(bool bold)
{
// *BUG: setName() overrides the style params.
- // Active group should be bold.
LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
// *NOTE dzaporozhan
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
// is predefined as bold (SansSerifSmallBold, for example)
- new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
mGroupNameStyle.font = new_font;
@@ -430,11 +583,25 @@ void LLGroupListItem::onProfileBtnClick()
LLGroupActions::show(mGroupID);
}
+void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
+{
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility);
+ setVisibleInProfile(new_visibility);
+ mVisibilityHideBtn->setVisible(new_visibility);
+ mVisibilityShowBtn->setVisible(!new_visibility);
+ }
+}
+
void LLGroupListItem::changed(LLGroupChange gc)
{
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
- if(group_data)
- setGroupIconID(group_data->mInsigniaID);
+ if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
+ {
+ setGroupIconID(group_data->mInsigniaID);
+ }
}
//EOF
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 171b77fb00..5cbabb712f 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -50,12 +50,15 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
public:
struct Params : public LLInitParam::Block
{
- Params(){};
+ Optional for_agent;
+ Params();
};
LLGroupList(const Params& p);
virtual ~LLGroupList();
+ void enableForAgent(bool show_icons);
+
virtual void draw(); // from LLView
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView
@@ -63,13 +66,16 @@ public:
void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
+ void setIconsVisible(bool show_icons) { mShowIcons = show_icons; }
+ void setShowNone(bool show_none) { mShowNone = show_none; }
+ void setGroups(const std::map< std::string,LLUUID> group_list);
LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM, bool visible_in_profile = true);
bool handleEvent(LLPointer event, const LLSD& userdata); // called on agent group list changes
bool onContextMenuItemClick(const LLSD& userdata);
@@ -80,6 +86,11 @@ private:
bool mShowIcons;
bool mDirty;
std::string mNameFilter;
+
+ bool mForAgent;
+ bool mShowNone;
+ typedef std::map< std::string,LLUUID> group_map_t;
+ group_map_t mGroups;
};
class LLButton;
@@ -90,7 +101,7 @@ class LLGroupListItem : public LLPanel
, public LLGroupMgrObserver
{
public:
- LLGroupListItem();
+ LLGroupListItem(bool for_agent, bool show_icons);
~LLGroupListItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
@@ -106,19 +117,26 @@ public:
void setGroupIconVisible(bool visible);
virtual void changed(LLGroupChange gc);
+
+ void setVisibleInProfile(bool visible);
private:
- void setActive(bool active);
+ void setBold(bool bold);
void onInfoBtnClick();
void onProfileBtnClick();
+ void onVisibilityBtnClick(bool new_visibility);
LLTextBox* mGroupNameBox;
LLUUID mGroupID;
LLGroupIconCtrl* mGroupIcon;
- LLButton* mInfoBtn;
+ LLButton* mInfoBtn;
+ LLButton* mProfileBtn;
+ LLButton* mVisibilityHideBtn;
+ LLButton* mVisibilityShowBtn;
std::string mGroupName;
+ bool mForAgent;
LLStyle::Params mGroupNameStyle;
- static S32 sIconWidth; // icon width + padding
+ S32 mIconWidth;
};
#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 7be35ac260..5952edfc44 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -330,7 +330,7 @@ void LLHUDText::updateVisibility()
if (!mSourceObject)
{
- LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL;
+ // Beacons
mVisible = TRUE;
if (mOnHUDAttachment)
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b7e0a6a794..98c1d65f92 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -532,7 +532,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),
@@ -544,13 +543,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
{
@@ -651,9 +643,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();
@@ -913,11 +902,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;
@@ -1795,7 +1779,6 @@ LLIMMgr::onConfirmForceCloseError(
LLCallDialogManager::LLCallDialogManager():
mPreviousSessionlName(""),
-mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION),
mCurrentSessionlName(""),
mSession(NULL),
mOldState(LLVoiceChannel::STATE_READY)
@@ -1826,12 +1809,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;
@@ -1857,7 +1834,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;
@@ -1893,7 +1869,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;
@@ -1910,8 +1885,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 :
@@ -2031,7 +2005,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);
@@ -2052,8 +2025,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);
}
}
@@ -2097,13 +2070,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("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name);
show_oldchannel = true;
@@ -2116,10 +2083,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("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
@@ -2135,16 +2098,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
@@ -2344,18 +2302,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
@@ -2375,7 +2326,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
@@ -2384,7 +2335,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);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 79c831ebb6..fdf9806e2e 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -72,7 +72,6 @@ public:
P2P_SESSION,
GROUP_SESSION,
ADHOC_SESSION,
- AVALINE_SESSION,
NONE_SESSION,
} SType;
@@ -92,12 +91,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;
@@ -136,7 +133,6 @@ public:
bool mCallBackEnabled;
bool mTextIMPossible;
- bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
//if IM session is created for a voice call
@@ -516,7 +512,6 @@ private:
protected:
std::string mPreviousSessionlName;
- LLIMModel::LLIMSession::SType mPreviousSessionType;
std::string mCurrentSessionlName;
LLIMModel::LLIMSession* mSession;
LLVoiceChannel::EState mOldState;
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index 479e8f9abf..f382b5985f 100644
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
@@ -147,3 +147,19 @@ bool LLInspect::childHasVisiblePopupMenu()
}
return false;
}
+
+void LLInspect::repositionInspector(const LLSD& data)
+{
+ // Position the inspector relative to the mouse cursor
+ // Similar to how tooltips are positioned
+ // See LLToolTipMgr::createToolTip
+ if (data.has("pos"))
+ {
+ LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
+ }
+ else
+ {
+ LLUI::getInstance()->positionViewNearMouse(this);
+ }
+ applyRectControl();
+}
diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h
index 1f6aafc7bd..6909aa3f16 100644
--- a/indra/newview/llinspect.h
+++ b/indra/newview/llinspect.h
@@ -49,6 +49,8 @@ public:
/// Inspectors close themselves when they lose focus
/*virtual*/ void onFocusLost();
+
+ void repositionInspector(const LLSD& data);
protected:
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index f357899be0..b11c440015 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -45,7 +45,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lltextbox.h"
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
class LLFetchAvatarData;
@@ -202,17 +201,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// Generate link to avatar profile.
LLTextBase* avatar_profile_link = getChild("avatar_profile_link");
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index fa8a53c546..0a30ab9217 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -38,7 +38,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llresmgr.h" // getMonetaryString()
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
#include "lluictrl.h"
#include "llgroupiconctrl.h"
@@ -124,17 +123,7 @@ void LLInspectGroup::onOpen(const LLSD& data)
setGroupID(data["group_id"]);
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// can't call from constructor as widgets are not built yet
requestUpdate();
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index cb7031971b..5329f10612 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -50,7 +50,6 @@
#include "lltextbox.h" // for description truncation
#include "lltoggleablemenu.h"
#include "lltrans.h"
-#include "llui.h" // positionViewNearMouse()
#include "lluictrl.h"
class LLViewerObject;
@@ -198,17 +197,8 @@ void LLInspectObject::onOpen(const LLSD& data)
{
mObjectFace = data["object_face"];
}
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+
+ LLInspect::repositionInspector(data);
// Promote hovered object to a complete selection, which will also force
// a request for selected object data off the network
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index 272c8acbd5..77320510a6 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -111,17 +111,7 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
// update the inspector with the current object state
update();
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
}
void LLInspectRemoteObject::onClickMap()
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index d0034eff13..68801b0895 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -110,7 +110,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(notification_id);
}
// virtual
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 884007d2a6..f42c954185 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1115,7 +1115,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 max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4);
+ LLCachedControl max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20);
+ if (categories.size() >= max_count
+ || depth > (max_depth + 1))
{
disabled_items.push_back(std::string("New Folder"));
}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 37500176ea..216a9f4c94 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -135,15 +135,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()
{
}
@@ -165,7 +157,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;
@@ -173,6 +164,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();
@@ -344,13 +349,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 object_ids{ object_id }; // loop protection
@@ -360,19 +365,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;
}
// Get the object by id. Returns NULL if not found.
@@ -541,9 +546,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);
}
}
@@ -3899,9 +3913,9 @@ LLPointer LLInventoryModel::validate() const
{
LLPointer 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())
{
@@ -3922,7 +3936,9 @@ LLPointer 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;
@@ -3941,32 +3957,35 @@ LLPointer 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())
@@ -3976,7 +3995,8 @@ LLPointer 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++;
}
}
cat_array_t* cats;
@@ -3985,7 +4005,8 @@ LLPointer 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)
@@ -4003,7 +4024,8 @@ LLPointer 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)
@@ -4027,7 +4049,8 @@ LLPointer 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;
}
@@ -4038,7 +4061,8 @@ LLPointer 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++;
}
@@ -4048,7 +4072,8 @@ LLPointer 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
{
@@ -4062,11 +4087,12 @@ LLPointer 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
{
@@ -4077,7 +4103,8 @@ LLPointer LLInventoryModel::validate() const
<< " got " << topmost_ancestor_id
<< " expected " << getRootFolderID()
<< " or " << getLibraryRootFolderID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_recognized"]++;
+ warning_count++;
}
}
}
@@ -4093,7 +4120,7 @@ LLPointer 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
{
@@ -4111,7 +4138,7 @@ LLPointer 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++;
}
}
}
@@ -4120,7 +4147,7 @@ LLPointer 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;
}
@@ -4153,14 +4180,15 @@ LLPointer 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
{
@@ -4171,7 +4199,7 @@ LLPointer 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
{
@@ -4188,7 +4216,7 @@ LLPointer 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++;
}
}
@@ -4206,18 +4234,18 @@ LLPointer 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())
{
@@ -4289,13 +4317,15 @@ LLPointer LLInventoryModel::validate() const
if (is_automatic)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
- 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)
@@ -4306,6 +4336,7 @@ LLPointer 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
@@ -4313,13 +4344,15 @@ LLPointer 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 " << ft << " outside of root" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++;
+ warning_count++;
}
}
}
@@ -4341,12 +4374,12 @@ LLPointer 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;
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index eeec89bfb0..c4133ff9bb 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -65,15 +65,19 @@ public:
void toOstream(std::ostream& os) const;
void asLLSD(LLSD& sd) const;
+ bool mInitialized{false};
+ S32 mWarningCount{0};
+ std::map 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 mMissingRequiredSystemFolders;
std::set mDuplicateRequiredSystemFolders;
};
@@ -286,13 +290,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;
//--------------------------------------------------------------------
// Find
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 5a17332fde..de8db69e19 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -919,6 +919,36 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr()
mBitmapList.clear();
}
+LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename)
+{
+ if (!checkTextureDimensions(filename))
+ {
+ return LLUUID::null;
+ }
+
+ LLLocalBitmap* unit = new LLLocalBitmap(filename);
+
+ if (unit->getValid())
+ {
+ mBitmapList.push_back(unit);
+ return unit->getTrackingID();
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
+
+ delete unit;
+ unit = NULL;
+ }
+
+ return LLUUID::null;
+}
+
bool LLLocalBitmapMgr::addUnit()
{
bool add_successful = false;
@@ -931,32 +961,10 @@ bool LLLocalBitmapMgr::addUnit()
std::string filename = picker.getFirstFile();
while(!filename.empty())
{
- if(!checkTextureDimensions(filename))
- {
- filename = picker.getNextFile();
- continue;
- }
-
- LLLocalBitmap* unit = new LLLocalBitmap(filename);
-
- if (unit->getValid())
- {
- mBitmapList.push_back(unit);
- add_successful = true;
- }
- else
- {
- LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
- << "Filename: " << filename << LL_ENDL;
-
- LLSD notif_args;
- notif_args["FNAME"] = filename;
- LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
-
- delete unit;
- unit = NULL;
- }
-
+ if (addUnit(filename).notNull())
+ {
+ add_successful = true;
+ }
filename = picker.getNextFile();
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index def5a6bd6e..02b8834c16 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -116,6 +116,7 @@ class LLLocalBitmapMgr : public LLSingleton
~LLLocalBitmapMgr();
public:
bool addUnit();
+ LLUUID addUnit(const std::string &filename);
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 79dbe17982..af2a9f6afd 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -109,6 +109,8 @@ public:
LLLineEditor* getTextEntry() const { return mTextEntry; }
void handleLoginComplete();
+ bool isNavMeshDirty() { return mIsNavMeshDirty; }
+
private:
enum EParcelIcon
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 044c76ce2c..dd4ae4d201 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -758,7 +758,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
{
@@ -799,28 +806,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;
}
@@ -1298,6 +1304,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)();
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index fee9225f77..088507d850 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -198,7 +198,9 @@ public:
typedef boost::signals2::signal 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);
@@ -272,6 +274,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
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index bc45eb6d3a..9d0f62a30d 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -154,8 +154,7 @@ void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
if (matchPred(*it))
{
(*it)->markDead();
- // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
- c.erase(it++);
+ it = c.erase(it);
}
else
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d28e929b48..4dd0543693 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -383,6 +383,9 @@ U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
+U32 LLMeshRepository::sCacheBytesHeaders = 0;
+U32 LLMeshRepository::sCacheBytesSkins = 0;
+U32 LLMeshRepository::sCacheBytesDecomps = 0;
U32 LLMeshRepository::sCacheReads = 0;
U32 LLMeshRepository::sCacheWrites = 0;
U32 LLMeshRepository::sMaxLockHoldoffs = 0;
@@ -1877,6 +1880,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
+ LLMeshRepository::sCacheBytesHeaders += header_size;
}
@@ -3019,27 +3023,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
return -1;
}
-void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
-{
- mThread->mMeshHeader[data.mUUID] = header;
-
- // we cache the mesh for default parameters
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
-
- for (U32 i = 0; i < 4; i++)
- {
- if (data.mModel[i].notNull())
- {
- LLPointer volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
- volume->copyVolumeFaces(data.mModel[i]);
- volume->setMeshAssetLoaded(TRUE);
- }
- }
-
-}
-
// Handle failed or successful requests for mesh assets.
//
// Support for 200 responses was added for several reasons. One,
@@ -3957,6 +3940,8 @@ void LLMeshRepository::notifyLoadedMeshes()
void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
{
mSkinMap[info.mMeshID] = info;
+ // Alternative: We can get skin size from header
+ sCacheBytesSkins += info.sizeBytes();
skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
if (iter != mLoadingSkins.end())
@@ -3980,10 +3965,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
{ //just insert decomp into map
mDecompositionMap[decomp->mMeshID] = decomp;
mLoadingDecompositions.erase(decomp->mMeshID);
+ sCacheBytesDecomps += decomp->sizeBytes();
}
else
{ //merge decomp with existing entry
+ sCacheBytesDecomps -= iter->second->sizeBytes();
iter->second->merge(decomp);
+ sCacheBytesDecomps += iter->second->sizeBytes();
+
mLoadingDecompositions.erase(decomp->mMeshID);
delete decomp;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 1989350303..f61da3e571 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -554,6 +554,9 @@ public:
static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
+ static U32 sCacheBytesHeaders;
+ static U32 sCacheBytesSkins;
+ static U32 sCacheBytesDecomps;
static U32 sCacheReads;
static U32 sCacheWrites;
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
@@ -643,8 +646,6 @@ public:
std::queue mPendingPhysicsShapeRequests;
U32 mMeshThreadCount;
-
- void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
LLMeshRepoThread* mThread;
std::vector mUploads;
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 3bca4fde83..3401587450 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -2714,7 +2714,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
continue;
}
- LLModel* base_mdl = *base_iter;
base_iter++;
S32 num_faces = mdl->getNumVolumeFaces();
@@ -2789,7 +2788,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
//find closest weight to vf.mVertices[i].mPosition
LLVector3 pos(vf.mPositions[i].getF32ptr());
- const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos);
llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
LLVector4 w(0, 0, 0, 0);
@@ -2916,6 +2915,20 @@ void LLModelPreview::loadedCallback(
{
pPreview->lookupLODModelFiles(lod);
}
+
+ const LLVOAvatar* avatarp = pPreview->getPreviewAvatar();
+ if (avatarp) { // set up ground plane for possible rendering
+ const LLVector3 root_pos = avatarp->mRoot->getPosition();
+ const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();
+ const LLVector4a min = ext[0], max = ext[1];
+ const F32 center = (max[2] - min[2]) * 0.5f;
+ const F32 ground = root_pos[2] - center;
+ auto plane = pPreview->mGroundPlane;
+ plane[0] = {min[0], min[1], ground};
+ plane[1] = {max[0], min[1], ground};
+ plane[2] = {max[0], max[1], ground};
+ plane[3] = {min[0], max[1], ground};
+ }
}
}
@@ -3123,6 +3136,9 @@ BOOL LLModelPreview::render()
// (note: all these UI updates need to be somewhere that is not render)
fmp->childSetValue("upload_skin", true);
mFirstSkinUpdate = false;
+ upload_skin = true;
+ skin_weight = true;
+ mViewOption["show_skin_weight"] = true;
}
fmp->enableViewOption("show_skin_weight");
@@ -3727,6 +3743,7 @@ BOOL LLModelPreview::render()
{
getPreviewAvatar()->renderBones();
}
+ renderGroundPlane(mPelvisZOffset);
if (shader)
{
shader->bind();
@@ -3748,6 +3765,28 @@ BOOL LLModelPreview::render()
return TRUE;
}
+void LLModelPreview::renderGroundPlane(float z_offset)
+{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render
+
+ gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f );
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+ gGL.vertex3fv(mGroundPlane[1].mV);
+
+ gGL.vertex3fv(mGroundPlane[1].mV);
+ gGL.vertex3fv(mGroundPlane[2].mV);
+
+ gGL.vertex3fv(mGroundPlane[2].mV);
+ gGL.vertex3fv(mGroundPlane[3].mV);
+
+ gGL.vertex3fv(mGroundPlane[3].mV);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+
+ gGL.end();
+}
+
+
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 215f44357f..7cb5fd6845 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -224,6 +224,8 @@ private:
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
+ LLVector3 mGroundPlane[4];
+ void renderGroundPlane(float z_offset = 0.0f);
typedef enum
{
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 4a8ef53a8b..bf00d77dea 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -352,7 +352,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
void LLMuteList::updateAdd(const LLMute& mute)
{
- // External mutes (e.g. Avaline callers) are local only, don't send them to the server.
+ // External mutes are local only, don't send them to the server.
if (mute.mType == LLMute::EXTERNAL)
{
return;
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index e3ef407f76..d7d6fa1893 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -280,6 +280,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
return handled;
}
+// virtual
+BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLNameListItem* hit_item = dynamic_cast(hitItem(x, y));
+ LLFloater* floater = gFloaterView->getParentFloater(this);
+ if (floater && floater->isFrontmost() && hit_item)
+ {
+ if(hit_item->isGroup())
+ {
+ ContextMenuType prev_menu = getContextMenuType();
+ setContextMenu(MENU_GROUP);
+ BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+ setContextMenu(prev_menu);
+ return handled;
+ }
+ }
+ return LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+}
+
// public
void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
BOOL enabled)
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index d7e991c94d..4a4bd4ba09 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -180,6 +180,8 @@ public:
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
bool isSpecialType() { return (mNameListType == SPECIAL); }
void setNameListType(e_name_type type) { mNameListType = type; }
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 19dbbeb60e..2dd7cfab27 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -713,7 +713,7 @@ void LLNavigationBar::resizeLayoutPanel()
}
void LLNavigationBar::invokeSearch(std::string search_text)
{
- LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
+ LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text)));
}
void LLNavigationBar::clearHistoryCache()
@@ -733,3 +733,8 @@ int LLNavigationBar::getDefFavBarHeight()
{
return mDefaultFpRect.getHeight();
}
+
+bool LLNavigationBar::isRebakeNavMeshAvailable()
+{
+ return mCmbLocation->isNavMeshDirty();
+}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 646911a62c..11c671294a 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -102,6 +102,8 @@ public:
int getDefNavBarHeight();
int getDefFavBarHeight();
+
+ bool isRebakeNavMeshAvailable();
private:
// the distance between navigation panel and favorites panel in pixels
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 4febb72c6c..f419e2e06d 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1374,6 +1374,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
texture_floaterp->setCanApply(false, true);
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 37ed4bc74c..ff33efe4aa 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.cpp
* @brief LLPanelAvatar and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -28,173 +28,127 @@
#include "llpanelavatar.h"
#include "llagent.h"
-#include "llavataractions.h"
-#include "llcallingcard.h"
-#include "llcombobox.h"
-#include "lldateutil.h" // ageFromDate()
-#include "llimview.h"
-#include "llmenubutton.h"
-#include "llnotificationsutil.h"
-#include "llslurl.h"
-#include "lltexteditor.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
+#include "llloadingindicator.h"
#include "lltooldraganddrop.h"
-#include "llscrollcontainer.h"
-#include "llavatariconctrl.h"
-#include "llfloaterreg.h"
-#include "llnotificationsutil.h"
-#include "llviewermenu.h" // is_agent_mappable
-#include "llvoiceclient.h"
-#include "lltextbox.h"
-#include "lltrans.h"
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLDropTarget
-//
-// This handy class is a simple way to drop something on another
-// view. It handles drop events, always setting itself to the size of
-// its parent.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//////////////////////////////////////////////////////////////////////////
+// LLProfileDropTarget
-class LLDropTarget : public LLView
-{
-public:
- struct Params : public LLInitParam::Block
- {
- Optional agent_id;
- Params()
- : agent_id("agent_id")
- {
- changeDefault(mouse_opaque, false);
- changeDefault(follows.flags, FOLLOWS_ALL);
- }
- };
-
- LLDropTarget(const Params&);
- ~LLDropTarget();
-
- void doDrop(EDragAndDropType cargo_type, void* cargo_data);
-
- //
- // LLView functionality
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
-protected:
- LLUUID mAgentID;
-};
-
-LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
-: LLView(p),
- mAgentID(p.agent_id)
+LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
+: LLView(p),
+ mAgentID(p.agent_id)
{}
-LLDropTarget::~LLDropTarget()
-{}
-
-void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
+void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
- LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
+ LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
}
-BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
+BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
{
- if(getParent())
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
- cargo_type, cargo_data, accept);
+ if (getParent())
+ {
+ LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
+ cargo_type, cargo_data, accept);
- return TRUE;
- }
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
-static LLDefaultChildRegistry::Register r("drop_target");
+static LLDefaultChildRegistry::Register r("profile_drop_target");
//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileTab
LLPanelProfileTab::LLPanelProfileTab()
: LLPanel()
, mAvatarId(LLUUID::null)
+, mLoadingState(PROFILE_INIT)
+, mSelfProfile(false)
{
}
LLPanelProfileTab::~LLPanelProfileTab()
{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
}
-void LLPanelProfileTab::setAvatarId(const LLUUID& id)
+void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
{
- if(id.notNull())
- {
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
- }
- mAvatarId = id;
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
- }
+ if (avatar_id.notNull())
+ {
+ mAvatarId = avatar_id;
+ mSelfProfile = (getAvatarId() == gAgentID);
+ }
}
void LLPanelProfileTab::onOpen(const LLSD& key)
{
- // Don't reset panel if we are opening it for same avatar.
- if(getAvatarId() != key.asUUID())
- {
- resetControls();
- resetData();
+ // Update data even if we are viewing same avatar profile as some data might been changed.
+ setAvatarId(key.asUUID());
- scrollToTop();
- }
-
- // Update data even if we are viewing same avatar profile as some data might been changed.
- setAvatarId(key.asUUID());
- updateData();
- updateButtons();
+ setApplyProgress(true);
}
-void LLPanelProfileTab::scrollToTop()
+void LLPanelProfileTab::setLoaded()
{
- LLScrollContainer* scrollContainer = findChild("profile_scroll");
- if (scrollContainer)
- scrollContainer->goToTop();
+ setApplyProgress(false);
+
+ mLoadingState = PROFILE_LOADED;
}
-void LLPanelProfileTab::onMapButtonClick()
+void LLPanelProfileTab::setApplyProgress(bool started)
{
- LLAvatarActions::showOnMap(getAvatarId());
+ LLLoadingIndicator* indicator = findChild("progress_indicator");
+
+ if (indicator)
+ {
+ indicator->setVisible(started);
+
+ if (started)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ }
+
+ LLView* panel = findChild("indicator_stack");
+ if (panel)
+ {
+ panel->setVisible(started);
+ }
}
-void LLPanelProfileTab::updateButtons()
+LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
+ : LLPanelProfileTab()
{
- bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
-
- if(LLAvatarActions::isFriend(getAvatarId()))
- {
- getChildView("teleport")->setEnabled(is_buddy_online);
- }
- else
- {
- getChildView("teleport")->setEnabled(true);
- }
-
- bool enable_map_btn = (is_buddy_online &&
- is_agent_mappable(getAvatarId()))
- || gAgent.isGodlike();
- getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
+}
+
+LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()
+{
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+}
+
+void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ }
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index e33a850cfa..f182660c8e 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.h
- * @brief LLPanelAvatar and related class definitions
+ * @brief Legacy profile panel base class
*
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2019, Linden Research, Inc.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -29,80 +29,141 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
-#include "llvoiceclient.h"
#include "llavatarnamecache.h"
class LLComboBox;
class LLLineEditor;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLProfileDropTarget
+//
+// This handy class is a simple way to drop something on another
+// view. It handles drop events, always setting itself to the size of
+// its parent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLProfileDropTarget : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block
+ {
+ Optional agent_id;
+ Params()
+ : agent_id("agent_id")
+ {
+ changeDefault(mouse_opaque, false);
+ changeDefault(follows.flags, FOLLOWS_ALL);
+ }
+ };
+
+ LLProfileDropTarget(const Params&);
+ ~LLProfileDropTarget() {}
+
+ void doDrop(EDragAndDropType cargo_type, void* cargo_data);
+
+ //
+ // LLView functionality
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
+
+protected:
+ LLUUID mAgentID;
+};
+
+
/**
* Base class for any Profile View.
*/
class LLPanelProfileTab
- : public LLPanel
- , public LLAvatarPropertiesObserver
+ : public LLPanel
{
public:
- /**
- * Sets avatar ID, sets panel as observer of avatar related info replies from server.
- */
- virtual void setAvatarId(const LLUUID& id);
+ /**
+ * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+ */
+ virtual void setAvatarId(const LLUUID& avatar_id);
- /**
- * Returns avatar ID.
- */
- virtual const LLUUID& getAvatarId() { return mAvatarId; }
+ /**
+ * Returns avatar ID.
+ */
+ virtual const LLUUID& getAvatarId() { return mAvatarId; }
- /**
- * Sends update data request to server.
- */
- virtual void updateData() = 0;
+ /**
+ * Sends update data request to server.
+ */
+ virtual void updateData() {};
- /**
- * Clears panel data if viewing avatar info for first time and sends update data request.
- */
- virtual void onOpen(const LLSD& key);
+ /**
+ * Clears panel data if viewing avatar info for first time and sends update data request.
+ */
+ virtual void onOpen(const LLSD& key);
- /**
- * Profile tabs should close any opened panels here.
- *
- * Called from LLPanelProfile::onOpen() before opening new profile.
- * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
- * before new profile is displayed, otherwise new profile will
- * be hidden behind picture info panel.
- */
- virtual void onClosePanel() {}
+ /**
+ * Clears all data received from server.
+ */
+ virtual void resetData(){};
- /**
- * Resets controls visibility, state, etc.
- */
- virtual void resetControls(){};
-
- /**
- * Clears all data received from server.
- */
- virtual void resetData(){};
-
- /*virtual*/ ~LLPanelProfileTab();
+ /*virtual*/ ~LLPanelProfileTab();
protected:
- LLPanelProfileTab();
+ LLPanelProfileTab();
- /**
- * Scrolls panel to top when viewing avatar info for first time.
- */
- void scrollToTop();
+ enum ELoadingState
+ {
+ PROFILE_INIT,
+ PROFILE_LOADING,
+ PROFILE_LOADED,
+ };
- virtual void onMapButtonClick();
- virtual void updateButtons();
+ // mLoading: false: Initial state, can request
+ // true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
+ // mLoaded: false: Initial state, show loading indicator
+ // true: Data recieved, which comes in a single message, hide indicator
+ ELoadingState getLoadingState() { return mLoadingState; }
+ virtual void setLoaded();
+ void setApplyProgress(bool started);
+
+ const bool getSelfProfile() const { return mSelfProfile; }
+
+public:
+ void setIsLoading() { mLoadingState = PROFILE_LOADING; }
+ void resetLoading() { mLoadingState = PROFILE_INIT; }
+
+ bool getStarted() { return mLoadingState != PROFILE_INIT; }
+ bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; }
+
+ virtual bool hasUnsavedChanges() { return false; }
+ virtual void commitUnsavedChanges() {}
private:
- LLUUID mAvatarId;
+ LLUUID mAvatarId;
+ ELoadingState mLoadingState;
+ bool mSelfProfile;
+};
+
+class LLPanelProfilePropertiesProcessorTab
+ : public LLPanelProfileTab
+ , public LLAvatarPropertiesObserver
+{
+public:
+ LLPanelProfilePropertiesProcessorTab();
+ ~LLPanelProfilePropertiesProcessorTab();
+
+ /*virtual*/ void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Processes data received from server via LLAvatarPropertiesObserver.
+ */
+ virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
};
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index c0342eef4e..183000ceac 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.cpp
- * @brief LLPanelClassified class implementation
+ * @brief LLPanelClassifiedInfo class implementation
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -34,33 +34,21 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llagent.h"
#include "llclassifiedflags.h"
-#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llcombobox.h"
#include "lltexturectrl.h"
-#include "lltexteditor.h"
-#include "llviewerparcelmgr.h"
#include "llfloaterworldmap.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerregion.h"
-#include "llviewertexture.h"
-#include "lltrans.h"
#include "llscrollcontainer.h"
-#include "llstatusbar.h"
-#include "llviewertexture.h"
#include "llcorehttputil.h"
-const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
-
//static
LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
+static LLPanelInjector t_panel_panel_classified_info("panel_classified_info");
// "classifiedclickthrough"
// strings[0] = classified_id
@@ -118,17 +106,8 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
sAllPanels.remove(this);
}
-// static
-LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
-{
- LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
- panel->buildFromFile("panel_classified_info.xml");
- return panel;
-}
-
BOOL LLPanelClassifiedInfo::postBuild()
{
- childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
@@ -144,16 +123,6 @@ BOOL LLPanelClassifiedInfo::postBuild()
return TRUE;
}
-void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
-{
- getChild("edit_btn")->setClickedCallback(cb);
-}
-
void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
{
LLPanel::reshape(width, height, called_from_parent);
@@ -286,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
getChild("creation_date")->setValue(date_str);
setInfoLoaded(true);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
}
}
@@ -590,588 +561,4 @@ void LLPanelClassifiedInfo::onTeleportClick()
}
}
-void LLPanelClassifiedInfo::onExit()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
- gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-static const S32 CB_ITEM_MATURE = 0;
-static const S32 CB_ITEM_PG = 1;
-
-LLPanelClassifiedEdit::LLPanelClassifiedEdit()
- : LLPanelClassifiedInfo()
- , mIsNew(false)
- , mIsNewWithErrors(false)
- , mCanClose(false)
- , mPublishFloater(NULL)
-{
-}
-
-LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
-{
-}
-
-//static
-LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
-{
- LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
- panel->buildFromFile("panel_edit_classified.xml");
- return panel;
-}
-
-BOOL LLPanelClassifiedEdit::postBuild()
-{
- LLPanelClassifiedInfo::postBuild();
-
- LLUICtrl* edit_icon = getChild("edit_icon");
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
- edit_icon->setVisible(false);
-
- LLLineEditor* line_edit = getChild("classified_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- LLTextEditor* text_edit = getChild("classified_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- LLComboBox* combobox = getChild( "category");
- LLClassifiedInfo::cat_map::iterator iter;
- for (iter = LLClassifiedInfo::sCategories.begin();
- iter != LLClassifiedInfo::sCategories.end();
- iter++)
- {
- combobox->add(LLTrans::getString(iter->second));
- }
-
- combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
-
- mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
-
- return TRUE;
-}
-
-void LLPanelClassifiedEdit::fillIn(const LLSD& key)
-{
- setAvatarId(gAgent.getID());
-
- if(key.isUndefined())
- {
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID snapshot_id = LLUUID::null;
- std::string desc;
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if(parcel)
- {
- desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- getChild("classified_name")->setValue(makeClassifiedName());
- getChild("classified_desc")->setValue(desc);
- setSnapshotId(snapshot_id);
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
- // server will set valid parcel id
- setParcelId(LLUUID::null);
- }
- else
- {
- setClassifiedId(key["classified_id"]);
- setClassifiedName(key["name"]);
- setDescription(key["desc"]);
- setSnapshotId(key["snapshot_id"]);
- setCategory((U32)key["category"].asInteger());
- setContentType((U32)key["content_type"].asInteger());
- setClassifiedLocation(key["location_text"]);
- getChild("auto_renew")->setValue(key["auto_renew"]);
- getChild("price_for_listing")->setValue(key["price_for_listing"].asInteger());
- }
-}
-
-void LLPanelClassifiedEdit::onOpen(const LLSD& key)
-{
- mIsNew = key.isUndefined();
-
- scrollToTop();
-
- // classified is not created yet
- bool is_new = isNew() || isNewWithErrors();
-
- if(is_new)
- {
- resetData();
- resetControls();
-
- fillIn(key);
-
- if(isNew())
- {
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- }
- }
- else
- {
- LLPanelClassifiedInfo::onOpen(key);
- }
-
- std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
- getChild("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
-
- enableVerbs(is_new);
- enableEditing(is_new);
- showEditing(!is_new);
- resetDirty();
- setInfoLoaded(false);
-}
-
-void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO == type)
- {
- LLAvatarClassifiedInfo* c_info = static_cast(data);
- if(c_info && getClassifiedId() == c_info->classified_id)
- {
- // see LLPanelClassifiedEdit::sendUpdate() for notes
- mIsNewWithErrors = false;
- // for just created classified - panel will probably be closed when we get here.
- if(!getVisible())
- {
- return;
- }
-
- enableEditing(true);
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setParcelId(c_info->parcel_id);
- setPosGlobal(c_info->pos_global);
-
- setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
- // *HACK see LLPanelClassifiedEdit::sendUpdate()
- setCategory(c_info->category - 1);
-
- bool mature = is_cf_mature(c_info->flags);
- bool auto_renew = is_cf_auto_renew(c_info->flags);
-
- setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
- getChild("auto_renew")->setValue(auto_renew);
- getChild("price_for_listing")->setValue(c_info->price_for_listing);
- getChildView("price_for_listing")->setEnabled(isNew());
-
- resetDirty();
- setInfoLoaded(true);
- enableVerbs(false);
-
- // for just created classified - in case user opened edit panel before processProperties() callback
- getChild("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
- }
- }
-}
-
-BOOL LLPanelClassifiedEdit::isDirty() const
-{
- if(mIsNew)
- {
- return TRUE;
- }
-
- BOOL dirty = false;
-
- dirty |= LLPanelClassifiedInfo::isDirty();
- dirty |= getChild("classified_snapshot")->isDirty();
- dirty |= getChild("classified_name")->isDirty();
- dirty |= getChild("classified_desc")->isDirty();
- dirty |= getChild("category")->isDirty();
- dirty |= getChild("content_type")->isDirty();
- dirty |= getChild("auto_renew")->isDirty();
- dirty |= getChild("price_for_listing")->isDirty();
-
- return dirty;
-}
-
-void LLPanelClassifiedEdit::resetDirty()
-{
- LLPanelClassifiedInfo::resetDirty();
- getChild("classified_snapshot")->resetDirty();
- getChild("classified_name")->resetDirty();
-
- LLTextEditor* desc = getChild("classified_desc");
- // call blockUndo() to really reset dirty(and make isDirty work as intended)
- desc->blockUndo();
- desc->resetDirty();
-
- getChild("category")->resetDirty();
- getChild("content_type")->resetDirty();
- getChild("auto_renew")->resetDirty();
- getChild("price_for_listing")->resetDirty();
-}
-
-void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
-{
- mSaveButtonClickedSignal.connect(cb);
-}
-
-void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
-{
- getChild("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedEdit::resetControls()
-{
- LLPanelClassifiedInfo::resetControls();
-
- getChild("category")->setCurrentByIndex(0);
- getChild("content_type")->setCurrentByIndex(0);
- getChild("auto_renew")->setValue(false);
- getChild("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
- getChildView("price_for_listing")->setEnabled(TRUE);
-}
-
-bool LLPanelClassifiedEdit::canClose()
-{
- return mCanClose;
-}
-
-void LLPanelClassifiedEdit::draw()
-{
- LLPanel::draw();
-
- // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
- // does not trigger callbacks when user navigates through images.
- stretchSnapshot();
-}
-
-void LLPanelClassifiedEdit::stretchSnapshot()
-{
- LLPanelClassifiedInfo::stretchSnapshot();
-
- getChild("edit_icon")->setShape(mSnapshotCtrl->getRect());
-}
-
-U32 LLPanelClassifiedEdit::getContentType()
-{
- LLComboBox* ct_cb = getChild("content_type");
- return ct_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setContentType(U32 content_type)
-{
- LLComboBox* ct_cb = getChild("content_type");
- ct_cb->setCurrentByIndex(content_type);
- ct_cb->resetDirty();
-}
-
-bool LLPanelClassifiedEdit::getAutoRenew()
-{
- return getChild("auto_renew")->getValue().asBoolean();
-}
-
-void LLPanelClassifiedEdit::sendUpdate()
-{
- LLAvatarClassifiedInfo c_data;
-
- if(getClassifiedId().isNull())
- {
- setClassifiedId(LLUUID::generateNewID());
- }
-
- c_data.agent_id = gAgent.getID();
- c_data.classified_id = getClassifiedId();
- // *HACK
- // Categories on server start with 1 while combo-box index starts with 0
- c_data.category = getCategory() + 1;
- c_data.name = getClassifiedName();
- c_data.description = getDescription();
- c_data.parcel_id = getParcelId();
- c_data.snapshot_id = getSnapshotId();
- c_data.pos_global = getPosGlobal();
- c_data.flags = getFlags();
- c_data.price_for_listing = getPriceForListing();
-
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
-
- if(isNew())
- {
- // Lets assume there will be some error.
- // Successful sendClassifiedInfoUpdate will trigger processProperties and
- // let us know there was no error.
- mIsNewWithErrors = true;
- }
-}
-
-U32 LLPanelClassifiedEdit::getCategory()
-{
- LLComboBox* cat_cb = getChild("category");
- return cat_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setCategory(U32 category)
-{
- LLComboBox* cat_cb = getChild("category");
- cat_cb->setCurrentByIndex(category);
- cat_cb->resetDirty();
-}
-
-U8 LLPanelClassifiedEdit::getFlags()
-{
- bool auto_renew = getChild("auto_renew")->getValue().asBoolean();
-
- LLComboBox* content_cb = getChild("content_type");
- bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
-
- return pack_classified_flags_request(auto_renew, false, mature, false);
-}
-
-void LLPanelClassifiedEdit::enableVerbs(bool enable)
-{
- getChildView("save_changes_btn")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::enableEditing(bool enable)
-{
- getChildView("classified_snapshot")->setEnabled(enable);
- getChildView("classified_name")->setEnabled(enable);
- getChildView("classified_desc")->setEnabled(enable);
- getChildView("set_to_curr_location_btn")->setEnabled(enable);
- getChildView("category")->setEnabled(enable);
- getChildView("content_type")->setEnabled(enable);
- getChildView("price_for_listing")->setEnabled(enable);
- getChildView("auto_renew")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::showEditing(bool show)
-{
- getChildView("price_for_listing_label")->setVisible( show);
- getChildView("price_for_listing")->setVisible( show);
-}
-
-std::string LLPanelClassifiedEdit::makeClassifiedName()
-{
- std::string name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- name = parcel->getName();
- }
-
- if(!name.empty())
- {
- return name;
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- name = region->getName();
- }
-
- return name;
-}
-
-S32 LLPanelClassifiedEdit::getPriceForListing()
-{
- return getChild("price_for_listing")->getValue().asInteger();
-}
-
-void LLPanelClassifiedEdit::setPriceForListing(S32 price)
-{
- getChild("price_for_listing")->setValue(price);
-}
-
-void LLPanelClassifiedEdit::onSetLocationClick()
-{
- setPosGlobal(gAgent.getPositionGlobal());
- setParcelId(LLUUID::null);
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
-
- // mark classified as dirty
- setValue(LLSD());
-
- onChange();
-}
-
-void LLPanelClassifiedEdit::onChange()
-{
- enableVerbs(isDirty());
-}
-
-void LLPanelClassifiedEdit::onSaveClick()
-{
- mCanClose = false;
-
- if(!isValidName())
- {
- notifyInvalidName();
- return;
- }
- if(isNew() || isNewWithErrors())
- {
- if(gStatusBar->getBalance() < getPriceForListing())
- {
- LLNotificationsUtil::add("ClassifiedInsufficientFunds");
- return;
- }
-
- mPublishFloater = LLFloaterReg::findTypedInstance(
- "publish_classified", LLSD());
-
- if(!mPublishFloater)
- {
- mPublishFloater = LLFloaterReg::getTypedInstance(
- "publish_classified", LLSD());
-
- mPublishFloater->setPublishClickedCallback(boost::bind
- (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
- }
-
- // set spinner value before it has focus or value wont be set
- mPublishFloater->setPrice(getPriceForListing());
- mPublishFloater->openFloater(mPublishFloater->getKey());
- mPublishFloater->center();
- }
- else
- {
- doSave();
- }
-}
-
-void LLPanelClassifiedEdit::doSave()
-{
- mCanClose = true;
- sendUpdate();
- resetDirty();
-
- mSaveButtonClickedSignal(this, LLSD());
-}
-
-void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
-{
- setPriceForListing(mPublishFloater->getPrice());
-
- doSave();
-}
-
-std::string LLPanelClassifiedEdit::getLocationNotice()
-{
- static std::string location_notice = getString("location_notice");
- return location_notice;
-}
-
-bool LLPanelClassifiedEdit::isValidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- return false;
- }
- if (!isalnum(name[0]))
- {
- return false;
- }
-
- return true;
-}
-
-void LLPanelClassifiedEdit::notifyInvalidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- LLNotificationsUtil::add("BlankClassifiedName");
- }
- else if (!isalnum(name[0]))
- {
- LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
- }
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- ctrl->setVisible(TRUE);
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- ctrl->setVisible(FALSE);
-}
-
-void LLPanelClassifiedEdit::onTextureSelected()
-{
- setSnapshotId(mSnapshotCtrl->getValue().asUUID());
- onChange();
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
-{
-}
-
-BOOL LLPublishClassifiedFloater::postBuild()
-{
- LLFloater::postBuild();
-
- childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
- childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
-
- return TRUE;
-}
-
-void LLPublishClassifiedFloater::setPrice(S32 price)
-{
- getChild("price_for_listing")->setValue(price);
-}
-
-S32 LLPublishClassifiedFloater::getPrice()
-{
- return getChild("price_for_listing")->getValue().asInteger();
-}
-
-void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild("publish_btn")->setClickedCallback(cb);
-}
-
-void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild("cancel_btn")->setClickedCallback(cb);
-}
-
//EOF
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index b292782615..471becd0f7 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.h
- * @brief LLPanelClassified class definition
+ * @brief LLPanelClassifiedInfo class definition
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,39 +35,16 @@
#include "llfloater.h"
#include "llpanel.h"
#include "llrect.h"
-#include "lluuid.h"
-#include "v3dmath.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
class LLScrollContainer;
class LLTextureCtrl;
-class LLUICtrl;
-
-class LLPublishClassifiedFloater : public LLFloater
-{
-public:
- LLPublishClassifiedFloater(const LLSD& key);
- virtual ~LLPublishClassifiedFloater();
-
- /*virtual*/ BOOL postBuild();
-
- void setPrice(S32 price);
- S32 getPrice();
-
- void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
- void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
-
-private:
-};
class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
{
LOG_CLASS(LLPanelClassifiedInfo);
public:
- static LLPanelClassifiedInfo* create();
-
+ LLPanelClassifiedInfo();
virtual ~LLPanelClassifiedInfo();
/*virtual*/ void onOpen(const LLSD& key);
@@ -135,18 +112,12 @@ public:
const LLVector3d& global_pos,
const std::string& sim_name);
- void setExitCallback(const commit_callback_t& cb);
-
- void setEditClassifiedCallback(const commit_callback_t& cb);
-
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void draw();
protected:
- LLPanelClassifiedInfo();
-
virtual void resetData();
virtual void resetControls();
@@ -165,7 +136,6 @@ protected:
void onMapClick();
void onTeleportClick();
- void onExit();
bool mSnapshotStreched;
LLRect mSnapshotRect;
@@ -202,100 +172,4 @@ private:
static panel_list_t sAllPanels;
};
-class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
-{
- LOG_CLASS(LLPanelClassifiedEdit);
-public:
-
- static LLPanelClassifiedEdit* create();
-
- virtual ~LLPanelClassifiedEdit();
-
- /*virtual*/ BOOL postBuild();
-
- void fillIn(const LLSD& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void resetDirty();
-
- void setSaveCallback(const commit_signal_t::slot_type& cb);
-
- void setCancelCallback(const commit_signal_t::slot_type& cb);
-
- /*virtual*/ void resetControls();
-
- bool isNew() { return mIsNew; }
-
- bool isNewWithErrors() { return mIsNewWithErrors; }
-
- bool canClose();
-
- void draw();
-
- void stretchSnapshot();
-
- U32 getCategory();
-
- void setCategory(U32 category);
-
- U32 getContentType();
-
- void setContentType(U32 content_type);
-
- bool getAutoRenew();
-
- S32 getPriceForListing();
-
-protected:
-
- LLPanelClassifiedEdit();
-
- void sendUpdate();
-
- void enableVerbs(bool enable);
-
- void enableEditing(bool enable);
-
- void showEditing(bool show);
-
- std::string makeClassifiedName();
-
- void setPriceForListing(S32 price);
-
- U8 getFlags();
-
- std::string getLocationNotice();
-
- bool isValidName();
-
- void notifyInvalidName();
-
- void onSetLocationClick();
- void onChange();
- void onSaveClick();
-
- void doSave();
-
- void onPublishFloaterPublishClicked();
-
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
- void onTextureSelected();
-
-private:
- bool mIsNew;
- bool mIsNewWithErrors;
- bool mCanClose;
-
- LLPublishClassifiedFloater* mPublishFloater;
-
- commit_signal_t mSaveButtonClickedSignal;
-};
-
#endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 6e897e2c7e..ea10aa75ae 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1308,7 +1308,8 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
- gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
+ // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
+ gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
gMorphView->updateCamera();
}
}
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index 9d5afd1a6a..11111f2a2e 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -29,7 +29,6 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
-#include "llpanelavatar.h"
class LLExperienceItem;
class LLPanelProfile;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7fe5b1dd3f..178aba11a3 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -49,11 +49,15 @@
#include "llinventoryfunctions.h"
#include "llinventorymodel.h" // gInventory
#include "llinventorymodelbackgroundfetch.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llmaterialmgr.h"
+#include "llmediactrl.h"
#include "llmediaentry.h"
#include "llmenubutton.h"
#include "llnotificationsutil.h"
+#include "llpanelcontents.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -99,10 +103,9 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
- LLComboBox* combobox_matmedia = getChild("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild("radio_material_type");
- LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
+ LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
(radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
@@ -161,6 +164,8 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+ childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
+ childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
@@ -172,7 +177,6 @@ BOOL LLPanelFace::postBuild()
LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
- LLComboBox* mComboMatMedia;
LLCheckBoxCtrl *mCheckFullbright;
@@ -308,6 +312,9 @@ BOOL LLPanelFace::postBuild()
mMenuClipboardColor = getChild("clipboard_color_params_btn");
mMenuClipboardTexture = getChild("clipboard_texture_params_btn");
+
+ mTitleMedia = getChild("title_media");
+ mTitleMediaText = getChild("media_info");
clearCtrls();
@@ -316,24 +323,31 @@ BOOL LLPanelFace::postBuild()
LLPanelFace::LLPanelFace()
: LLPanel(),
- mIsAlpha(false)
+ mIsAlpha(false),
+ mComboMatMedia(NULL),
+ mTitleMedia(NULL),
+ mTitleMediaText(NULL),
+ mNeedMediaTitle(true)
{
USE_TEXTURE = LLTrans::getString("use_texture");
mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2));
mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2));
}
-
LLPanelFace::~LLPanelFace()
{
- // Children all cleaned up by default view destructor.
+ unloadMedia();
}
-
void LLPanelFace::draw()
{
updateCopyTexButton();
+ // grab media name/title and update the UI widget
+ // Todo: move it, it's preferable not to update
+ // labels inside draw
+ updateMediaTitle();
+
LLPanel::draw();
}
@@ -824,21 +838,20 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("button align")->setEnabled(editable);
+ childSetEnabled("button align", editable);
- LLComboBox* combobox_matmedia = getChild("combobox matmedia");
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
{
- combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
+ mComboMatMedia->setEnabled(editable);
}
else
{
LL_WARNS() << "failed getChild for 'combobox matmedia'" << LL_ENDL;
}
- getChildView("combobox matmedia")->setEnabled(editable);
LLRadioGroup* radio_mat_type = getChild("radio_material_type");
if(radio_mat_type)
@@ -847,7 +860,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
-
}
else
{
@@ -876,22 +888,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
getChildView("color label")->setEnabled(editable);
}
- LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch");
+ LLColorSwatchCtrl* color_swatch = findChild("colorswatch");
LLColor4 color = LLColor4::white;
bool identical_color = false;
- if(mColorSwatch)
+ if(color_swatch)
{
LLSelectedTE::getColor(color, identical_color);
- LLColor4 prev_color = mColorSwatch->get();
+ LLColor4 prev_color = color_swatch->get();
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable);
+ color_swatch->setOriginal(color);
+ color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
+ color_swatch->setValid(editable);
+ color_swatch->setEnabled( editable );
+ color_swatch->setCanApplyImmediately( editable );
}
// Color transparency
@@ -1374,7 +1386,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL identical_repeats = true;
F32 repeats = 1.0f;
- U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
+ U32 material_type = (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
switch (material_type)
@@ -1606,6 +1618,755 @@ void LLPanelFace::refresh()
getState();
}
+void LLPanelFace::refreshMedia()
+{
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* first_object = selected_objects->getFirstObject();
+
+ if (!(first_object
+ && first_object->getPCode() == LL_PCODE_VOLUME
+ && first_object->permModify()
+ ))
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ mTitleMediaText->clear();
+ clearMediaSettings();
+ return;
+ }
+
+ std::string url = first_object->getRegion()->getCapability("ObjectMedia");
+ bool has_media_capability = (!url.empty());
+
+ if (!has_media_capability)
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
+ clearMediaSettings();
+ return;
+ }
+
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for (; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify())
+ {
+ LL_INFOS("LLFloaterToolsMedia")
+ << "Selection not editable due to lack of modify permissions on object id "
+ << object->getID() << LL_ENDL;
+
+ editable = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Media settings
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor
+ {
+ bool get(LLViewerObject* object, S32 face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
+ }
+ } func;
+
+
+ // check if all faces have media(or, all dont have media)
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media);
+
+ const LLMediaEntry default_media_data;
+
+ struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
+ {
+ functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ LLMediaEntry get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return *(object->getTE(face)->getMediaData());
+ return mMediaEntry;
+ };
+
+ const LLMediaEntry& mMediaEntry;
+
+ } func_media_data(default_media_data);
+
+ LLMediaEntry media_data_get;
+ LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ std::string media_title = "";
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+
+ getChildView("add_media")->setEnabled(editable);
+ // IF all the faces have media (or all dont have media)
+ if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo)
+ {
+ // TODO: get media title and set it.
+ mTitleMediaText->clear();
+ // if identical is set, all faces are same (whether all empty or has the same media)
+ if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia))
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ // else all faces might be empty.
+ }
+ else // there' re Different Medias' been set on on the faces.
+ {
+ media_title = multi_media_info_str;
+ }
+
+ getChildView("delete_media")->setEnabled(bool_has_media && editable);
+ // TODO: display a list of all media on the face - use 'identical' flag
+ }
+ else // not all face has media but at least one does.
+ {
+ // seleted faces have not identical value
+ LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
+
+ if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ {
+ media_title = multi_media_info_str;
+ }
+ else
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ }
+
+ getChildView("delete_media")->setEnabled(TRUE);
+ }
+
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ if (materials_media == MATMEDIA_MEDIA)
+ {
+ // currently displaying media info, navigateTo and update title
+ navigateToTitleMedia(media_title);
+ }
+ else
+ {
+ // Media can be heavy, don't keep it around
+ // MAC specific: MAC doesn't support setVolume(0) so if not
+ // unloaded, it might keep playing audio until user closes editor
+ unloadMedia();
+ mNeedMediaTitle = false;
+ }
+
+ mTitleMediaText->setText(media_title);
+
+ // load values for media settings
+ updateMediaSettings();
+
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable);
+}
+
+void LLPanelFace::unloadMedia()
+{
+ // destroy media source used to grab media title
+ if (mTitleMedia)
+ mTitleMedia->unloadMediaSource();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelFace::navigateToTitleMedia( const std::string url )
+{
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ if (url.empty() || multi_media_info_str == url)
+ {
+ // nothing to show
+ mNeedMediaTitle = false;
+ }
+ else if (mTitleMedia)
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ // check if url changed or if we need a new media source
+ if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+ {
+ mTitleMedia->navigateTo( url );
+
+ LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID());
+ if (impl)
+ {
+ // if it's a page with a movie, we don't want to hear it
+ impl->setVolume(0);
+ };
+ }
+
+ // flag that we need to update the title (even if no request were made)
+ mNeedMediaTitle = true;
+ }
+}
+
+bool LLPanelFace::selectedMediaEditable()
+{
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
+ &owner_mask_on, &owner_mask_off);
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
+ &group_mask_on, &group_mask_off);
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off);
+
+ bool selected_Media_editable = false;
+
+ // if perms we got back are valid
+ if (valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms)
+ {
+
+ if ((owner_mask_on & PERM_MODIFY) ||
+ (group_mask_on & PERM_MODIFY) ||
+ (everyone_mask_on & PERM_MODIFY))
+ {
+ selected_Media_editable = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ selected_Media_editable = false;
+ };
+ };
+
+ return selected_Media_editable;
+}
+
+void LLPanelFace::clearMediaSettings()
+{
+ LLFloaterMediaSettings::clearValues(false);
+}
+
+void LLPanelFace::updateMediaSettings()
+{
+ bool identical(false);
+ std::string base_key("");
+ std::string value_str("");
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ const LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getControls();
+ return mMediaEntry.getControls();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_controls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_controls, value_u8);
+ base_key = std::string(LLMediaEntry::CONTROLS_KEY);
+ mMediaSettings[base_key] = value_u8;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ return mMediaEntry.getFirstClickInteract();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_first_click(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool);
+ base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ return mMediaEntry.getHomeURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_home_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_home_url, value_str);
+ base_key = std::string(LLMediaEntry::HOME_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ return mMediaEntry.getCurrentURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_current_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_current_url, value_str);
+ base_key = std::string(LLMediaEntry::CURRENT_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+
+ functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ return mMediaEntry.getAutoZoom();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_zoom(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto play
+ //value_bool = default_media_data.getAutoPlay();
+ // set default to auto play TRUE -- angela EXT-5172
+ value_bool = true;
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_play(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+
+ // Auto scale
+ // set default to auto scale TRUE -- angela EXT-5172
+ //value_bool = default_media_data.getAutoScale();
+ value_bool = true;
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_scale(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ return mMediaEntry.getAutoLoop();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_loop(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ return mMediaEntry.getWidthPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_width_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int);
+ base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ return mMediaEntry.getHeightPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_height_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int);
+ base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ return mMediaEntry.getAltImageEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_enable_alt_image(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool);
+ base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_interact(default_media_data);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ return mMediaEntry.getWhiteListEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_enable(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool);
+ base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist URLs
+ std::vector value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector >
+ {
+ functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::vector get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ return mMediaEntry.getWhiteList();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_urls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str);
+ base_key = std::string(LLMediaEntry::WHITELIST_KEY);
+ mMediaSettings[base_key].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while (iter != value_vector_str.end())
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[base_key].append(white_list_url);
+ ++iter;
+ };
+
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+}
+
+void LLPanelFace::updateMediaTitle()
+{
+ // only get the media name if we need it
+ if (!mNeedMediaTitle)
+ return;
+
+ // get plugin impl
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI())
+ {
+ // get the media name (asynchronous - must call repeatedly)
+ std::string media_title = media_plugin->getMediaName();
+
+ // only replace the title if what we get contains something
+ if (!media_title.empty())
+ {
+ // update the UI widget
+ if (mTitleMediaText)
+ {
+ mTitleMediaText->setText(media_title);
+
+ // stop looking for a title when we get one
+ mNeedMediaTitle = false;
+ };
+ };
+ };
+}
+
//
// Static functions
//
@@ -1664,30 +2425,29 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
self->updateShinyControls(false,true);
self->updateBumpyControls(false,true);
self->updateUI();
+ self->refreshMedia();
}
-// static
void LLPanelFace::updateVisibility()
{
- LLComboBox* combo_matmedia = getChild("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild("radio_material_type");
LLComboBox* combo_shininess = getChild("combobox shininess");
LLComboBox* combo_bumpiness = getChild("combobox bumpiness");
- if (!radio_mat_type || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+ if (!radio_mat_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
}
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
- bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
getChildView("radio_material_type")->setVisible(!show_media);
// Media controls
- getChildView("media_info")->setVisible(show_media);
+ mTitleMediaText->setVisible(show_media);
getChildView("add_media")->setVisible(show_media);
getChildView("delete_media")->setVisible(show_media);
getChildView("button align")->setVisible(show_media);
@@ -1819,12 +2579,11 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
}
- LLComboBox* combo_matmedia = getChild("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
getChildView("label glossiness")->setVisible(show_shinyctrls);
@@ -1898,11 +2657,10 @@ void LLPanelFace::updateAlphaControls()
U32 alpha_value = comboAlphaMode->getCurrentIndex();
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
- LLComboBox* combobox_matmedia = getChild("combobox matmedia");
U32 mat_media = MATMEDIA_MATERIAL;
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- mat_media = combobox_matmedia->getCurrentIndex();
+ mat_media = mComboMatMedia->getCurrentIndex();
}
U32 mat_type = MATTYPE_DIFFUSE;
@@ -2059,6 +2817,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLFloaterReg::showInstance("media_settings");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata)
+{
+ // check if multiple faces are selected
+ if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
+ }
+ else
+ {
+ onClickBtnEditMedia(ctrl, userdata);
+ }
+}
+
+// static
+bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD());
+ if (LLFloaterReg::instanceVisible("media_settings"))
+ {
+ LLFloaterReg::hideInstance("media_settings");
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+// static
+bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLFloaterReg::showInstance("media_settings");
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
@@ -2436,10 +3265,9 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLPanelFace* self = (LLPanelFace*) userdata;
LLUICtrl* repeats_ctrl = self->getChild("rptctrl");
- LLComboBox* combo_matmedia = self->getChild("combobox matmedia");
LLRadioGroup* radio_mat_type = self->getChild("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = self->mComboMatMedia->getCurrentIndex();
U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
@@ -3375,14 +4203,6 @@ bool LLPanelFace::menuEnableItem(const LLSD& userdata)
}
-// TODO: I don't know who put these in or what these are for???
-void LLPanelFace::setMediaURL(const std::string& url)
-{
-}
-void LLPanelFace::setMediaType(const std::string& mime_type)
-{
-}
-
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index e3b925c1d4..44bc442bbb 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,7 @@ class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLMaterialID;
+class LLMediaCtrl;
class LLMenuButton;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
@@ -97,11 +98,11 @@ public:
LLPanelFace();
virtual ~LLPanelFace();
- void draw();
-
void refresh();
- void setMediaURL(const std::string& url);
- void setMediaType(const std::string& mime_type);
+ void refreshMedia();
+ void unloadMedia();
+
+ /*virtual*/ void draw();
LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
{
@@ -117,6 +118,12 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
protected:
+ void navigateToTitleMedia(const std::string url);
+ bool selectedMediaEditable();
+ void clearMediaSettings();
+ void updateMediaSettings();
+ void updateMediaTitle();
+
void getState();
void sendTexture(); // applies and sends texture
@@ -155,6 +162,9 @@ protected:
void onCloseTexturePicker(const LLSD& data);
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
+
// Make UI reflect state of currently selected material (refresh)
// and UI mode (e.g. editing normal map v diffuse map)
//
@@ -199,6 +209,9 @@ protected:
static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
@@ -251,6 +264,10 @@ private:
F32 getCurrentShinyOffsetU();
F32 getCurrentShinyOffsetV();
+ LLComboBox *mComboMatMedia;
+ LLMediaCtrl *mTitleMedia;
+ LLTextBox *mTitleMediaText;
+
// Update visibility of controls to match current UI mode
// (e.g. materials vs media editing)
//
@@ -258,10 +275,6 @@ private:
//
void updateVisibility();
- // Make material(s) reflect current state of UI (apply edit)
- //
- void updateMaterial();
-
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@@ -439,6 +452,9 @@ private:
LLSD mClipboardParams;
+ LLSD mMediaSettings;
+ bool mNeedMediaTitle;
+
public:
#if defined(DEF_GET_MAT_STATE)
#undef DEF_GET_MAT_STATE
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 389baa86cd..07a8641a92 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,6 +1,6 @@
/**
- * @file llpanelavatar.cpp
- * @brief LLPanelAvatar and related class implementations
+ * @file llpanelimcontrolpanel.cpp
+ * @brief LLPanelIMControlPanel and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index e7bdc51b4a..9e3fc54477 100644
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
@@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild()
mCheckAVSoundGroup = getChild("group av sound check");
childSetCommitCallback("group av sound check", onCommitAny, this);
+ mCheckObscureMOAP = getChild("obscure_moap");
+ childSetCommitCallback("obscure_moap", onCommitAny, this);
+
return TRUE;
}
@@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh()
mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on
mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off
+
+ mCheckObscureMOAP->set(parcel->getObscureMOAP());
+ mCheckObscureMOAP->setEnabled(can_change_media);
}
}
// static
@@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
group_av_sound = self->mCheckAVSoundGroup->get();
}
+ bool obscure_moap = self->mCheckObscureMOAP->get();
+
// Remove leading/trailing whitespace (common when copying/pasting)
LLStringUtil::trim(music_url);
@@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
parcel->setMusicURL(music_url);
parcel->setAllowAnyAVSounds(any_av_sound);
parcel->setAllowGroupAVSounds(group_av_sound);
+ parcel->setObscureMOAP(obscure_moap);
// Send current parcel data upstream to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index 7e4fce80e4..b54fe62179 100644
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
@@ -53,6 +53,7 @@ private:
LLLineEditor* mMusicURLEdit;
LLCheckBoxCtrl* mCheckAVSoundAny;
LLCheckBoxCtrl* mCheckAVSoundGroup;
+ LLCheckBoxCtrl* mCheckObscureMOAP;
LLSafeHandle& mParcel;
};
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ce17da3076..c3334605ae 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -29,6 +29,7 @@
#include "llpanellandmarks.h"
#include "llbutton.h"
+#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsdutil.h"
@@ -1003,17 +1004,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
return can_be_modified;
}
-void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
-{
- pick_panel->setVisible(FALSE);
- owner->removeChild(pick_panel);
- //we need remove observer to avoid processParcelInfo in the future.
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this);
-
- delete pick_panel;
- pick_panel = NULL;
-}
-
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
{
*accept = ACCEPT_NO;
@@ -1080,49 +1070,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data)
{
- LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
LLVector3d landmark_global_pos;
landmark->getGlobalPos(landmark_global_pos);
- // let's toggle pick panel into panel places
- LLPanel* panel_places = NULL;
- LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance("places");
- if (floaterp)
- {
- panel_places = floaterp->findChild("main_panel");
- }
-
- if (!panel_places)
- {
- llassert(NULL != panel_places);
- return;
- }
- panel_places->addChild(panel_pick);
- LLRect paren_rect(panel_places->getRect());
- panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
- panel_pick->setRect(paren_rect);
- panel_pick->onOpen(LLSD());
-
LLPickData data;
data.pos_global = landmark_global_pos;
data.name = inv_item->getName();
data.desc = inv_item->getDescription();
data.snapshot_id = parcel_data.snapshot_id;
data.parcel_id = parcel_data.parcel_id;
- panel_pick->setPickData(&data);
- LLSD params;
- params["parcel_id"] = parcel_data.parcel_id;
- /* set exit callback to get back onto panel places
- in callback we will make cleaning up( delete pick_panel instance,
- remove landmark panel from observer list
- */
- panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
+ LLFloaterProfile* profile_floater = dynamic_cast(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index d7408269b5..16f3a5dc24 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -34,7 +34,6 @@
#include "llinventorymodel.h"
#include "lllandmarklist.h"
#include "llpanelplacestab.h"
-#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
class LLAccordionCtrlTab;
@@ -136,7 +135,6 @@ private:
* For now it checks cut/rename/delete/paste actions.
*/
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
- void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
deleted file mode 100644
index 55e4ffff5e..0000000000
--- a/indra/newview/llpanelme.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelme.cpp
- * @brief Side tray "Me" (My Profile) panel
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelme.h"
-
-// Viewer includes
-#include "llpanelprofile.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llhints.h"
-#include "llviewercontrol.h"
-
-// Linden libraries
-#include "llavatarnamecache.h" // IDEVO
-#include "lliconctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h" // IDEVO
-#include "lltabcontainer.h"
-#include "lltexturectrl.h"
-
-static LLPanelInjector t_panel_me_profile("panel_me");
-
-LLPanelMe::LLPanelMe(void)
- : LLPanelProfile()
-{
- setAvatarId(gAgent.getID());
-}
-
-BOOL LLPanelMe::postBuild()
-{
- LLPanelProfile::postBuild();
-
- return TRUE;
-}
-
-void LLPanelMe::onOpen(const LLSD& key)
-{
- LLPanelProfile::onOpen(key);
-}
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 9730f0f16d..e1818cc68b 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild()
childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
- // interrogates controls and updates widgets as required
- updateMediaPreview();
-
return true;
}
@@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
-
- // interrogates controls and updates widgets as required
- self->updateMediaPreview();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
deleted file mode 100644
index 40326cfb39..0000000000
--- a/indra/newview/llpanelpick.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/**
- * @file llpanelpick.cpp
- * @brief LLPanelPick class implementation
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpick.h"
-
-#include "message.h"
-
-#include "llparcel.h"
-
-#include "llbutton.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llpanel.h"
-#include "llscrollcontainer.h"
-#include "lltexteditor.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloaterworldmap.h"
-#include "lltexturectrl.h"
-#include "lluiconstants.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llworldmap.h"
-
-
-#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
-#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
-
-#define XML_NAME "pick_name"
-#define XML_DESC "pick_desc"
-#define XML_SNAPSHOT "pick_snapshot"
-#define XML_LOCATION "pick_location"
-
-#define XML_BTN_ON_TXTR "edit_icon"
-#define XML_BTN_SAVE "save_changes_btn"
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickInfo* LLPanelPickInfo::create()
-{
- LLPanelPickInfo* panel = new LLPanelPickInfo();
- panel->buildFromFile(XML_PANEL_PICK_INFO);
- return panel;
-}
-
-LLPanelPickInfo::LLPanelPickInfo()
- : LLPanel()
- , LLAvatarPropertiesObserver()
- , LLRemoteParcelInfoObserver()
- , mAvatarId(LLUUID::null)
- , mSnapshotCtrl(NULL)
- , mPickId(LLUUID::null)
- , mParcelId(LLUUID::null)
- , mRequestedId(LLUUID::null)
- , mScrollingPanelMinHeight(0)
- , mScrollingPanelWidth(0)
- , mScrollingPanel(NULL)
- , mScrollContainer(NULL)
-{
-}
-
-LLPanelPickInfo::~LLPanelPickInfo()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::onOpen(const LLSD& key)
-{
- LLUUID avatar_id = key["avatar_id"];
- if(avatar_id.isNull())
- {
- return;
- }
-
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(
- getAvatarId(), this);
- }
-
- setAvatarId(avatar_id);
-
- resetData();
- resetControls();
-
- setPickId(key["pick_id"]);
- setPickName(key["pick_name"]);
- setPickDesc(key["pick_desc"]);
- setSnapshotId(key["snapshot_id"]);
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(
- getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
- getAvatarId(), getPickId());
-}
-
-BOOL LLPanelPickInfo::postBuild()
-{
- mSnapshotCtrl = getChild(XML_SNAPSHOT);
-
- childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
- childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
- childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
-
- mScrollingPanel = getChild("scroll_content_panel");
- mScrollContainer = getChild("profile_scroll");
-
- mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
- mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
-
- LLTextEditor* text_desc = getChild(XML_DESC);
- text_desc->setContentTrusted(false);
-
- return TRUE;
-}
-
-void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
-
- if (!mScrollContainer || !mScrollingPanel)
- return;
-
- static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0);
-
- S32 scroll_height = mScrollContainer->getRect().getHeight();
- if (mScrollingPanelMinHeight >= scroll_height)
- {
- mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
- }
- else
- {
- mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
- }
-}
-
-void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICK_INFO != type)
- {
- return;
- }
- LLPickData* pick_info = static_cast(data);
- if(!pick_info
- || pick_info->creator_id != getAvatarId()
- || pick_info->pick_id != getPickId())
- {
- return;
- }
-
- mParcelId = pick_info->parcel_id;
- setSnapshotId(pick_info->snapshot_id);
- setPickName(pick_info->name);
- setPickDesc(pick_info->desc);
- setPosGlobal(pick_info->pos_global);
-
- // Send remote parcel info request to get parcel name and sim (region) name.
- sendParcelInfoRequest();
-
- // *NOTE dzaporozhan
- // We want to keep listening to APT_PICK_INFO because user may
- // edit the Pick and we have to update Pick info panel.
- // revomeObserver is called from onClickBack
-}
-
-void LLPanelPickInfo::sendParcelInfoRequest()
-{
- if (mParcelId != mRequestedId)
- {
- LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
- LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
-
- mRequestedId = mParcelId;
- }
-}
-
-void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
-{
- setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
- parcel_data.sim_name, getPosGlobal()));
-
- // We have received parcel info for the requested ID so clear it now.
- mRequestedId.setNull();
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
-{
- getChild("edit_btn")->setClickedCallback(cb);
-}
-
-// PROTECTED AREA
-
-void LLPanelPickInfo::resetControls()
-{
- if(getAvatarId() == gAgent.getID())
- {
- getChildView("edit_btn")->setEnabled(TRUE);
- getChildView("edit_btn")->setVisible( TRUE);
- }
- else
- {
- getChildView("edit_btn")->setEnabled(FALSE);
- getChildView("edit_btn")->setVisible( FALSE);
- }
-}
-
-void LLPanelPickInfo::resetData()
-{
- setPickName(LLStringUtil::null);
- setPickDesc(LLStringUtil::null);
- setPickLocation(LLStringUtil::null);
- setPickId(LLUUID::null);
- setSnapshotId(LLUUID::null);
- mPosGlobal.clearVec();
- mParcelId.setNull();
- mRequestedId.setNull();
-}
-
-// static
-std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
-{
- std::string location_text;
- location_text.append(owner_name);
- if (!original_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(original_name);
-
- }
- if (!sim_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(sim_name);
- }
-
- if (!location_text.empty()) location_text.append(" ");
-
- if (!pos_global.isNull())
- {
- S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
- }
- return location_text;
-}
-
-void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
-{
- mSnapshotCtrl->setImageAssetID(id);
- mSnapshotCtrl->setValid(TRUE);
-}
-
-void LLPanelPickInfo::setPickName(const std::string& name)
-{
- getChild(XML_NAME)->setValue(name);
-}
-
-void LLPanelPickInfo::setPickDesc(const std::string& desc)
-{
- getChild(XML_DESC)->setValue(desc);
-}
-
-void LLPanelPickInfo::setPickLocation(const std::string& location)
-{
- getChild(XML_LOCATION)->setValue(location);
-}
-
-void LLPanelPickInfo::onClickMap()
-{
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-void LLPanelPickInfo::onClickTeleport()
-{
- if (!getPosGlobal().isExactlyZero())
- {
- gAgent.teleportViaLocation(getPosGlobal());
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- }
-}
-
-void LLPanelPickInfo::onClickBack()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickEdit* LLPanelPickEdit::create()
-{
- LLPanelPickEdit* panel = new LLPanelPickEdit();
- panel->buildFromFile(XML_PANEL_EDIT_PICK);
- return panel;
-}
-
-LLPanelPickEdit::LLPanelPickEdit()
- : LLPanelPickInfo()
- , mLocationChanged(false)
- , mNeedData(true)
- , mNewPick(false)
-{
-}
-
-LLPanelPickEdit::~LLPanelPickEdit()
-{
-}
-
-void LLPanelPickEdit::onOpen(const LLSD& key)
-{
- LLUUID pick_id = key["pick_id"];
- mNeedData = true;
-
- // creating new Pick
- if(pick_id.isNull())
- {
- mNewPick = true;
-
- setAvatarId(gAgent.getID());
-
- resetData();
- resetControls();
-
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
- std::string pick_name, pick_desc, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- parcel_id = parcel->getID();
- pick_name = parcel->getName();
- pick_desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setParcelID(parcel_id);
- getChild("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
- getChild("pick_desc")->setValue(pick_desc);
- setSnapshotId(snapshot_id);
- setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
-
- enableSaveButton(true);
- }
- // editing existing pick
- else
- {
- mNewPick = false;
- LLPanelPickInfo::onOpen(key);
-
- enableSaveButton(false);
- }
-
- resetDirty();
-}
-
-void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
-{
- if(!pick_data)
- {
- return;
- }
-
- mNeedData = false;
-
- setParcelID(pick_data->parcel_id);
- getChild("pick_name")->setValue(pick_data->name);
- getChild("pick_desc")->setValue(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- setPosGlobal(pick_data->pos_global);
- setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
- pick_data->sim_name, pick_data->pos_global));
-}
-
-BOOL LLPanelPickEdit::postBuild()
-{
- LLPanelPickInfo::postBuild();
-
- mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
-
- LLLineEditor* line_edit = getChild("pick_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
-
- LLTextEditor* text_edit = getChild("pick_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
-
- childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
-
- initTexturePickerMouseEvents();
-
- return TRUE;
-}
-
-void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
-{
- getChild