diff options
| author | Mnikolenko Productengine <mnikolenko@productengine.com> | 2022-09-21 18:36:49 +0300 | 
|---|---|---|
| committer | Mnikolenko Productengine <mnikolenko@productengine.com> | 2022-09-21 18:36:49 +0300 | 
| commit | 85504f085e556d5f1c5c4fa22ed51ae43046e9c4 (patch) | |
| tree | 12ff49167f60747d7628dfd5ffbfec62ca772616 | |
| parent | 856d2a44d196059cf3f487d7facd3c180369bd20 (diff) | |
| parent | f83289d3a7e80bebe47f696f96aee1b7e64d1d69 (diff) | |
Merge branch 'master' into DRTVWR-539
501 files changed, 17398 insertions, 8705 deletions
diff --git a/autobuild.xml b/autobuild.xml index ccb5ac4e12..1d303b3e95 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -482,9 +482,9 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>2653c3627fd8687ff9e003425fd14834</string> +              <string>439d92ec73f0500ba1671faad2bd8090</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90199/821852/dullahan-1.12.3.202111032211_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-565428.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104637/916643/dullahan-1.12.4.202209142017_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-575005.tar.bz2</string>              </map>              <key>name</key>              <string>darwin64</string> @@ -494,9 +494,9 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>b4003772562a5dd40bc112eec7cba5f5</string> +              <string>2a7c01da15de77bc1fd1863327174d5e</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90201/821871/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-565428.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104638/916654/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-575005.tar.bz2</string>              </map>              <key>name</key>              <string>windows</string> @@ -506,16 +506,16 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>d9030d7a7390b3bda7de2adcc27e535a</string> +              <string>d06bee9b2517fbb09ba1a65e6d675361</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90200/821876/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-565428.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104639/916659/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-575005.tar.bz2</string>              </map>              <key>name</key>              <string>windows64</string>            </map>          </map>          <key>version</key> -        <string>1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114</string> +        <string>1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>        </map>        <key>expat</key>        <map> @@ -2393,9 +2393,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>6ce3cbaed968a69fb7a2cca80220874d</string> +              <string>b583668b28fde0490e6953f10e93e4ab</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80380/758537/slvoice-4.10.0000.32327.5fc3fe7c.558436-darwin64-558436.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98681/871545/slvoice-4.10.0000.32327.5fc3fe7c.571099-darwin64-571099.tar.bz2</string>              </map>              <key>name</key>              <string>darwin64</string> @@ -2417,9 +2417,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>2eb38c5eff4d0f18fbb89d0c30c4f0a4</string> +              <string>6e0ed41653955afe8eeb8945776cf07b</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80382/758550/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows-558436.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98683/871560/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows-571099.tar.bz2</string>              </map>              <key>name</key>              <string>windows</string> @@ -2429,16 +2429,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>9ee8f3cbc5369c598a998c61961ed16d</string> +              <string>c39735851fd05c194d0be09b8f9e8cb7</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80381/758551/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows64-558436.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98682/871552/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows64-571099.tar.bz2</string>              </map>              <key>name</key>              <string>windows64</string>            </map>          </map>          <key>version</key> -        <string>4.10.0000.32327.5fc3fe7c.558436</string> +        <string>4.10.0000.32327.5fc3fe7c.571099</string>        </map>        <key>threejs</key>        <map> 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<T, alignment>::resize(U32 size)  template <class T, U32 alignment>  T& LLAlignedArray<T, alignment>::operator[](int idx)  { -	llassert(idx < mElementCount); +	if(idx >= mElementCount || idx < 0) +    { +        LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL; +    }  	return mArray[idx];  }  template <class T, U32 alignment>  const T& LLAlignedArray<T, alignment>::operator[](int idx) const  { -	llassert(idx < mElementCount); +    if (idx >= mElementCount || idx < 0) +    { +        LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL; +    }  	return mArray[idx];  } 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 <atomic> +#include <stdexcept>  // external library headers  #include <boost/bind.hpp>  #include <boost/fiber/fiber.hpp> @@ -214,6 +215,22 @@ std::string LLCoros::logname()      return data.mName.empty()? data.getKey() : data.mName;  } +void LLCoros::saveException(const std::string& name, std::exception_ptr exc) +{ +    mExceptionQueue.emplace(name, exc); +} + +void LLCoros::rethrow() +{ +    if (! mExceptionQueue.empty()) +    { +        ExceptionData front = mExceptionQueue.front(); +        mExceptionQueue.pop(); +        LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL; +        std::rethrow_exception(front.exception); +    } +} +  void LLCoros::setStackSize(S32 stacksize)  {      LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; @@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,      }  } -void LLCoros::winlevel(const std::string& name, const callable_t& callable) +void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)  {      __try      { -        toplevelTryWrapper(name, callable); +        LLCoros::toplevelTryWrapper(name, callable);      }      __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))      { @@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)          throw std::exception(integer_string);      }  } -  #endif  void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable) @@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call      }      catch (...)      { +#if LL_WINDOWS          // Any OTHER kind of uncaught exception will cause the viewer to -        // crash, hopefully informatively. +        // crash, SEH handling should catch it and report to bugsplat.          LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));          // to not modify callstack          throw; +#else +        // Stash any OTHER kind of uncaught exception in the rethrow() queue +        // to be rethrown by the main fiber. +        LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine " +                            << name << LL_ENDL; +        LLCoros::instance().saveException(name, std::current_exception()); +#endif      }  } @@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call  void LLCoros::toplevel(std::string name, callable_t callable)  {  #if LL_WINDOWS -    // Can not use __try in functions that require unwinding, so use one more wrapper -    winlevel(name, callable); +    // Because SEH can's have unwinding, need to call a wrapper +    // 'try' is inside SEH handling to not catch LLContinue +    sehHandle(name, callable);  #else      toplevelTryWrapper(name, callable);  #endif 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 <boost/function.hpp>  #include <string> +#include <exception> +#include <queue>  // e.g. #include LLCOROS_MUTEX_HEADER  #define LLCOROS_MUTEX_HEADER   <boost/fiber/mutex.hpp> @@ -156,6 +158,19 @@ public:       * LLCoros::launch()).       */      static std::string getName(); +     +    /** +     * rethrow() is called by the thread's main fiber to propagate an +     * exception from any coroutine into the main fiber, where it can engage +     * the normal unhandled-exception machinery, up to and including crash +     * reporting. +     * +     * LLCoros maintains a queue of otherwise-uncaught exceptions from +     * terminated coroutines. Each call to rethrow() pops the first of those +     * and rethrows it. When the queue is empty (normal case), rethrow() is a +     * no-op. +     */ +    void rethrow();      /**       * This variation returns a name suitable for log messages: the explicit @@ -292,13 +307,27 @@ public:  private:      std::string generateDistinctName(const std::string& prefix) const; +    void toplevelTryWrapper(const std::string& name, const callable_t& callable);  #if LL_WINDOWS -    void winlevel(const std::string& name, const callable_t& callable); +    void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper  #endif -    void toplevelTryWrapper(const std::string& name, const callable_t& callable); -    void toplevel(std::string name, callable_t callable); +    void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper      struct CoroData;      static CoroData& get_CoroData(const std::string& caller); +    void saveException(const std::string& name, std::exception_ptr exc); + +    struct ExceptionData +    { +        ExceptionData(const std::string& nm, std::exception_ptr exc): +            name(nm), +            exception(exc) +        {} +        // name of coroutine that originally threw this exception +        std::string name; +        // the thrown exception +        std::exception_ptr exception; +    }; +    std::queue<ExceptionData> mExceptionQueue;      S32 mStackSize; 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<LLVector4a,64> pt; +	static thread_local LLAlignedArray<LLVector4a,64> pt;  	pt.resize(mTotal) ;  	for (S32 i=mTotalOut;i<mTotal;i++) @@ -6674,13 +6674,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			else  			{  				// Get s value for tex-coord. -				if (!flat) +                S32 index = mBeginS + s; +                if (index >= profile.size()) +                { +                    // edge? +                    ss = flat ? 1.f - begin_stex : 1.f; +                } +				else if (!flat)  				{ -					ss = profile[mBeginS + s][2]; +					ss = profile[index][2];  				}  				else  				{ -					ss = profile[mBeginS + s][2] - begin_stex; +					ss = profile[index][2] - begin_stex;  				}  			} @@ -6866,7 +6872,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	LLVector4a* norm = mNormals; -	static LLAlignedArray<LLVector4a, 64> triangle_normals; +    static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;      try      {          triangle_normals.resize(count); 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::vector<LLU              LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);          }      } +    catch (const LLCoros::Stop&) +    { +        LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL; +    }      catch (...)      {          LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName() 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 <boost/smart_ptr/shared_ptr.hpp>  class LLCoprocedurePool; @@ -84,7 +83,7 @@ public:  private: -    typedef boost::shared_ptr<LLCoprocedurePool> poolPtr_t; +    typedef std::shared_ptr<LLCoprocedurePool> poolPtr_t;      typedef std::map<std::string, poolPtr_t> poolMap_t;      poolMap_t mPoolMap; 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<std::string>) + sizeof(std::string) * mJointNames.size(); +    for (U32 i = 0; i < mJointNames.size(); ++i) +    { +        res += mJointNames[i].size(); // actual size, not capacity +    } + +    res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size(); +    res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size(); +    res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size(); +    res += 16 * sizeof(float); //mBindShapeMatrix +    res += sizeof(float) + 3 * sizeof(bool); + +    return res; +} +  LLModel::Decomposition::Decomposition(LLSD& data)  {  	fromLLSD(data); @@ -1659,6 +1678,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)  	}  } +U32 LLModel::Decomposition::sizeBytes() const +{ +    U32 res = sizeof(LLUUID); // mMeshID + +    res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size(); +    for (U32 i = 0; i < mHull.size(); ++i) +    { +        res += mHull[i].size() * sizeof(LLVector3); +    } + +    res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size(); + +    res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size(); +    for (U32 i = 0; i < mMesh.size(); ++i) +    { +        res += mMesh[i].sizeBytes(); +    } + +    res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2; +    res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes(); + +    return res; +} +  bool LLModel::Decomposition::hasHullList() const  {  	return !mHull.empty() ; 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<std::string> mJointNames; @@ -112,6 +113,14 @@ public:  		{  			return mPositions.empty();  		} + +        U32 sizeBytes() const +        { +            U32 res = sizeof(std::vector<LLVector3>) * 2; +            res += sizeof(LLVector3) * mPositions.size(); +            res += sizeof(LLVector3) * mNormals.size(); +            return res; +        }  	};  	class Decomposition @@ -122,6 +131,7 @@ public:  		void fromLLSD(LLSD& data);  		LLSD asLLSD() const;  		bool hasHullList() const; +        U32 sizeBytes() const;  		void merge(const Decomposition* rhs); 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<LLFloater>(); +                floaterp->closeFloater(app_quitting); +            }  		}  		cleanupHandles(); @@ -906,7 +903,10 @@ bool LLFloater::applyRectControl()  	if (last_in_group && last_in_group != this)  	{  		// other floaters in our group, position ourselves relative to them and don't save the rect -		mRectControl.clear(); +		if (mDefaultRectForGroup) +		{ +			mRectControl.clear(); +		}  		mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;  	}  	else @@ -1439,7 +1439,7 @@ void LLFloater::cleanupHandles()  		LLFloater* floaterp = dependent_it->get();  		if (!floaterp)  		{ -			mDependents.erase(dependent_it++); +            dependent_it = mDependents.erase(dependent_it);  		}  		else  		{ @@ -3481,8 +3481,15 @@ void LLFloater::stackWith(LLFloater& other)  	}  	next_rect.translate(floater_offset, -floater_offset); -	next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight()); -	 +	const LLRect& rect = getControlGroup()->getRect(mRectControl); +	if (rect.notEmpty() && !mDefaultRectForGroup && mResizable) +	{ +		next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); +	} +	else +	{ +		next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight()); +	}  	setShape(next_rect);  	if (!other.getHost()) 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<LLIconCtrl> r("icon"); @@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()  :	image("image_name"),  	color("color"),  	use_draw_context_alpha("use_draw_context_alpha", true), +    interactable("interactable", false),  	scale_image("scale_image"),  	min_width("min_width", 0),  	min_height("min_height", 0) @@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)  	mColor(p.color()),  	mImagep(p.image),  	mUseDrawContextAlpha(p.use_draw_context_alpha), +    mInteractable(p.interactable),  	mPriority(0),  	mMinWidth(p.min_width),  	mMinHeight(p.min_height), @@ -81,6 +84,16 @@ void LLIconCtrl::draw()  	LLUICtrl::draw();  } +BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask) +{ +    if (mInteractable && getEnabled()) +    { +        getWindow()->setCursor(UI_CURSOR_HAND); +        return TRUE; +    } +    return LLUICtrl::handleHover(x, y, mask); +} +  // virtual  // value might be a string or a UUID  void LLIconCtrl::setValue(const LLSD& value) 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<LLUIImage*>	image;  		Optional<LLUIColor>		color; -		Optional<bool>			use_draw_context_alpha; +		Optional<bool>			use_draw_context_alpha, +                                interactable;  		Optional<S32>			min_width,  								min_height;  		Ignored					scale_image; @@ -67,6 +68,9 @@ public:  	// llview overrides  	virtual void	draw(); +    // llview overrides +    virtual BOOL handleHover(S32 x, S32 y, MASK mask); +  	// lluictrl overrides  	virtual void	setValue(const LLSD& value ); @@ -88,6 +92,7 @@ protected:  	// If set to true (default), use the draw context transparency.  	// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.  	bool mUseDrawContextAlpha; +    bool mInteractable;  private:  	LLUIColor mColor; 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<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this); +        if (iter != sModalStack.end()) +        { +            // if already present, we want to move it to front. +            sModalStack.erase(iter); +        } + +        sModalStack.push_front(this);  	}  } 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<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0); -			S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad); +			S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;  			S32 additional_needed = tab_total_height - available_height_with_arrows; -			setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) ); +			setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );  			no_scroll = FALSE;  		}  	} 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<S32>			v_pad,  								h_pad; @@ -369,6 +370,8 @@ public:  	virtual void	onFocusReceived();  	virtual void	onFocusLost(); +    void        setParseHTML(bool parse_html) { mParseHTML = parse_html; } +  	// LLSpellCheckMenuHandler overrides  	/*virtual*/ bool		getSpellCheck() const; @@ -702,6 +705,8 @@ protected:  	bool						mAutoIndent;  	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes  	bool						mSkipTripleClick; +	bool						mAlwaysShowIcons; +  	bool						mSkipLinkUnderline;  	// support widgets 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 @@ -59,18 +59,6 @@ namespace LLTextUtil  	        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.  	 *  	 * @param[in] match an object with results of matching 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<wchar_t> buffer(MAX_PATH + 1); +                GetCurrentDirectoryW(MAX_PATH, &buffer[0]); +                settings.host_process_path = ll_convert_wide_to_string(&buffer[0]);  #endif                  settings.accept_language_list = mHostLanguage; 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;  }; @@ -214,6 +215,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom)  }  //////////////////////////////////////////////////////////////////////////////// +// *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"             />    <command name="places"             available_in_toybox="true" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b11e9cc14a..1877c30dc4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -544,17 +544,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>AvalinePhoneSeparator</key> -    <map> -      <key>Comment</key> -      <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string>-</string> -    </map>      <key>AvatarAxisDeadZone0</key>      <map>        <key>Comment</key> @@ -4758,7 +4747,7 @@        <key>Type</key>        <string>String</string>        <key>Value</key> -      <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&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]</string> +      <string>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]</string>      </map>      <key>GuidebookURL</key>      <map> @@ -5806,6 +5795,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>DiskCacheVersion</key> +    <map> +      <key>Comment</key> +      <string>Version number of disk cache</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>LocalFileSystemBrowsingEnabled</key>      <map>        <key>Comment</key> @@ -15770,6 +15770,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>AllowSelectAvatar</key> +    <map> +      <key>Comment</key> +      <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>       <key>WebProfileFloaterRect</key>      <map>        <key>Comment</key> 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 @@ -4257,6 +4268,15 @@ U32 LLAppViewer::getTextureCacheVersion()  }  //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()  {  	// Viewer object cache version, change if object update @@ -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) +// static +void LLAvatarActions::showProfile(const LLUUID& avatar_id) +{ +	if (avatar_id.notNull()) +	{ +		LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)); +	} +} + +// static +void LLAvatarActions::showPicks(const LLUUID& avatar_id) +{ +	if (avatar_id.notNull()) +	{ +        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); +        if (profilefloater) +        { +            profilefloater->showPick(); +        } +	} +} + +// static +void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id) +{ +	if (avatar_id.notNull()) +	{ +        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); +        if (profilefloater) +        { +            profilefloater->showPick(pick_id); +        } +	} +} + +// static +void LLAvatarActions::createPick()  { -	// Use different floater XML for our profile to be able to save its rect. -	return avatar_id == gAgentID ? "my_profile" : "profile"; +    LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); +    LLViewerRegion* region = gAgent.getRegion(); +    if (profilefloater && region) +    { +        LLPickData data; +        data.pos_global = gAgent.getPositionGlobal(); +        data.sim_name = region->getName(); + +        LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +        if (parcel) +        { +            data.name = parcel->getName(); +            data.desc = parcel->getDesc(); +            data.snapshot_id = parcel->getSnapshotID(); +            data.parcel_id = parcel->getID(); +        } +        else +        { +            data.name = region->getName(); +        } + +        profilefloater->createPick(data); +    }  } -static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name) +// static +bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)  { -	std::string url = getProfileURL(av_name.getAccountName()); +    if (avatar_id.notNull()) +    { +        LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); +        if (profilefloater) +        { +            return profilefloater->isPickTabSelected(); +        } +    } +    return false; +} -	// 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::showClassifieds(const LLUUID& avatar_id) +{ +	if (avatar_id.notNull()) +	{ +        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); +        if (profilefloater) +        { +            profilefloater->showClassified(); +        } +	}  }  // static -void LLAvatarActions::showProfile(const LLUUID& id) +void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)  { -	if (id.notNull()) +	if (avatar_id.notNull())  	{ -		LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2)); +        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); +        if (profilefloater) +        { +            profilefloater->showClassified(classified_id, edit); +        }  	}  } +// static +void LLAvatarActions::createClassified() +{ +    LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); +    if (profilefloater) +    { +        profilefloater->createClassified(); +    } +} +  //static  -bool LLAvatarActions::profileVisible(const LLUUID& id) +bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)  {  	LLSD sd; -	sd["id"] = id; -	LLFloater* browser = getProfileFloater(id); -	return browser && browser->isShown(); +	sd["id"] = avatar_id; +	LLFloater* floater = getProfileFloater(avatar_id); +	return floater && floater->isShown();  }  //static -LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id) +LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)  { -	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> -		(LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id))); -	return browser; +    LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); +    return floater;  }  //static  -void LLAvatarActions::hideProfile(const LLUUID& id) +void LLAvatarActions::hideProfile(const LLUUID& avatar_id)  {  	LLSD sd; -	sd["id"] = id; -	LLFloater* browser = getProfileFloater(id); -	if (browser) +	sd["id"] = avatar_id; +	LLFloater* floater = getProfileFloater(avatar_id); +	if (floater)  	{ -		browser->closeFloater(); +		floater->closeFloater();  	}  } @@ -990,7 +1094,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL  }  // static -void LLAvatarActions::toggleBlock(const LLUUID& id) +bool LLAvatarActions::toggleBlock(const LLUUID& id)  {  	LLAvatarName av_name;  	LLAvatarNameCache::get(id, &av_name); @@ -1000,10 +1104,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)  	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))  	{  		LLMuteList::getInstance()->remove(mute); +		return false;  	}  	else  	{  		LLMuteList::getInstance()->add(mute); +		return true;  	}  } 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<LLPanel*> selected_items; -	getSelectedItems(selected_items); -	std::vector<LLPanel*>::iterator it = selected_items.begin(); -	 -	for(; it != selected_items.end(); ++it) -	{ -		if (dynamic_cast<LLAvalineListItem*>(*it)) -			return true; -	} - -	return false; -} -  void LLAvatarList::setVisible(BOOL visible)  {  	if ( visible == FALSE && mContextMenu ) @@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_  	}  	return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);  } - -/************************************************************************/ -/*             class LLAvalineListItem                                  */ -/************************************************************************/ -LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false) -, mIsHideNumber(hide_number) -{ -	// should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called. -	buildFromFile( "panel_avatar_list_item.xml"); -} - -BOOL LLAvalineListItem::postBuild() -{ -	BOOL rv = LLAvatarListItem::postBuild(); - -	if (rv) -	{ -		setOnline(true); -		showLastInteractionTime(false); -		setShowProfileBtn(false); -		setShowInfoBtn(false); -		mAvatarIcon->setValue("Avaline_Icon"); -		mAvatarIcon->setToolTip(std::string("")); -	} -	return rv; -} - -// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number -void LLAvalineListItem::setName(const std::string& name) -{ -	if (mIsHideNumber) -	{ -		static U32 order = 0; -		typedef std::map<LLUUID, U32> avaline_callers_nums_t; -		static avaline_callers_nums_t mAvalineCallersNums; - -		llassert(getAvatarId() != LLUUID::null); - -		const LLUUID &uuid = getAvatarId(); - -		if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end()) -		{ -			mAvalineCallersNums[uuid] = ++order; -			LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL; -		} -		LLStringUtil::format_map_t args; -		args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]); -		std::string hidden_name = LLTrans::getString("AvalineCaller", args); - -		LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL; -		LLAvatarListItem::setAvatarName(hidden_name); -		LLAvatarListItem::setAvatarToolTip(hidden_name); -	} -	else -	{ -		const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name); -		LLAvatarListItem::setAvatarName(formatted_phone); -		LLAvatarListItem::setAvatarToolTip(formatted_phone); -	} -} 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<std::string> strings; -	strings.push_back( avatar_id.asString() ); -	send_generic_message(method, strings); +    std::string cap; + +    switch (type) +    { +    case APT_PROPERTIES: +        // indicate we're going to make a request +        sendAvatarPropertiesRequestMessage(avatar_id); +        // can use getRegionCapability("AgentProfile"), but it is heavy +        // initAgentProfileCapRequest(avatar_id, cap); +        break; +    case APT_PICKS: +    case APT_GROUPS: +    case APT_NOTES: +        if (cap.empty()) +        { +            // indicate we're going to make a request +            sendGenericRequest(avatar_id, type, method); +        } +        else +        { +            initAgentProfileCapRequest(avatar_id, cap); +        } +        break; +    default: +        sendGenericRequest(avatar_id, type, method); +        break; +    }  } -void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) +void LLAvatarPropertiesProcessor::sendGenericRequest(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, the AvatarPropertiesRequest message   -	// won't work so don't bother trying -	if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) -	{ -		return; -	} +    // indicate we're going to make a request +    addPendingRequest(avatar_id, type); -	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); +    std::vector<std::string> strings; +    strings.push_back(avatar_id.asString()); +    send_generic_message(method, strings); +} -	LLMessageSystem *msg = gMessageSystem; +void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id) +{ +    addPendingRequest(avatar_id, APT_PROPERTIES); -	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(); +    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) +{ +    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<LLTextBox>("time_box")->getValue().asString(); + +                // Just add current date if not full. +                // Should be fine since both times are supposed to be stl +                if (!time_string.empty() && time_string.size() < 7) +                { +                    time_string = "[" + LLTrans::getString("TimeMonth") + "]/[" +                        + LLTrans::getString("TimeDay") + "]/[" +                        + LLTrans::getString("TimeYear") + "] " + time_string; + +                    LLSD substitution; +                    // To avoid adding today's date to yesterday's timestamp, +                    // use creation time instead of current time +                    substitution["datetime"] = (S32)mCreationTime; +                    LLStringUtil::format(time_string, substitution); +                } +            } +            LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText); +        }  		else if(level == "block_unblock")  		{  			LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat); @@ -477,6 +521,10 @@ public:  		{  			return canModerate(userdata);  		} +        else if (level == "report_abuse") +        { +            return gAgentID != mAvatarID; +        }  		else if (level == "can_ban_member")  		{  			return canBanGroupMember(getAvatarId()); @@ -634,6 +682,12 @@ public:  		mSessionID = chat.mSessionID;  		mSourceType = chat.mSourceType; +        // To be able to report a message, we need a copy of it's text +        // and it's easier to store text directly than trying to get +        // it from a lltextsegment or chat's mEditor +        mText = chat.mText; +        mTime = chat.mTime; +  		//*TODO overly defensive thing, source type should be maintained out there  		if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))  		{ @@ -983,6 +1037,9 @@ protected:  	EChatSourceType		mSourceType;  	std::string			mFrom;  	LLUUID				mSessionID; +    std::string			mText; +    F64					mTime; // IM's frame time +    time_t				mCreationTime; // Views's time  	S32					mMinUserNameWidth;  	const LLFontGL*		mUserNameFont; 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; i<avatar_ids.size(); i++)  	{  		LLUUID& av = avatar_ids[i]; -		if(av == gAgent.getID()) continue; +		if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue;  		LLSD element;  		element["id"] = av; // value  		LLAvatarName av_name; diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index a3037ed651..392633bd7d 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT  	mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);  	mDummyAvatar->mSpecialRenderMode = 1;  	mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); -	mDummyAvatar->hideSkirt(); + +    // on idle overall apperance update will set skirt to visible, so either +    // call early or account for mSpecialRenderMode in updateMeshVisibility +    mDummyAvatar->updateOverallAppearance(); +    mDummyAvatar->hideHair(); +    mDummyAvatar->hideSkirt();  	// stop extraneous animations  	mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE ); @@ -1135,6 +1140,7 @@ BOOL	LLPreviewAnimation::render()  		{  			LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();  			avatarp->dirtyMesh(); +            gPipeline.enableLightsPreview();  			avatarPoolp->renderAvatars(avatarp);  // renders only one avatar  		}  	} 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<LLPanel>("main_panel", true); +    if (panel) +    { +        panel->onOpen(key); +    } +    if (key.has("classified_name")) +    { +        setTitle(key["classified_name"].asString()); +    } +    LLFloater::onOpen(key); +} + +BOOL LLFloaterClassified::postBuild() +{ +    return TRUE; +} + + +bool LLFloaterClassified::matchesKey(const LLSD& key) +{ +    bool is_mkey_valid = mKey.has("classified_id"); +    bool is_key_valid = key.has("classified_id"); +    if (is_mkey_valid && is_key_valid) +    { +        return key["classified_id"].asUUID() == mKey["classified_id"].asUUID(); +    } +    return is_mkey_valid == is_key_valid; +} + +// eof diff --git a/indra/newview/llfloaterwebprofile.h b/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 - -#include "llfloaterwebcontent.h" -#include "llviewermediaobserver.h" +#ifndef LL_LLFLOATERCLASSIFIED_H +#define LL_LLFLOATERCLASSIFIED_H -#include <string> +#include "llfloater.h" -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<LLUICtrl>("display_name_editor")->clear(); +	getChild<LLUICtrl>("display_name_confirm")->clear(); + +	LLAvatarName av_name; +	LLAvatarNameCache::get(gAgent.getID(), &av_name); + +	F64 now_secs = LLDate::now().secondsSinceEpoch(); + +	if (now_secs < av_name.mNextUpdate) +	{ +		// ...can't update until some time in the future +		F64 next_update_local_secs = +			av_name.mNextUpdate - LLStringOps::getLocalTimeOffset(); +		LLDate next_update_local(next_update_local_secs); +		// display as "July 18 12:17 PM" +		std::string next_update_string = +		next_update_local.toHTTPDateString("%B %d %I:%M %p"); +		getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string); +		getChild<LLUICtrl>("lockout_text")->setVisible(true); +		getChild<LLUICtrl>("save_btn")->setEnabled(false); +		getChild<LLUICtrl>("display_name_editor")->setEnabled(false); +		getChild<LLUICtrl>("display_name_confirm")->setEnabled(false); +		getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE); +		 +	} +	else +	{ +		getChild<LLUICtrl>("lockout_text")->setVisible(false); +		getChild<LLUICtrl>("save_btn")->setEnabled(true); +		getChild<LLUICtrl>("display_name_editor")->setEnabled(true); +		getChild<LLUICtrl>("display_name_confirm")->setEnabled(true); + +	} +} + +BOOL LLFloaterDisplayName::postBuild() +{ +	getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));	 +	getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));	 +	 +	center(); + +	return TRUE; +} + +void LLFloaterDisplayName::onCacheSetName(bool success, +										  const std::string& reason, +										  const LLSD& content) +{ +	if (success) +	{ +		// Inform the user that the change took place, but will take a while +		// to percolate. +		LLSD args; +		args["DISPLAY_NAME"] = content["display_name"]; +		LLNotificationsUtil::add("SetDisplayNameSuccess", args); +		return; +	} + +	// Request failed, notify the user +	std::string error_tag = content["error_tag"].asString(); +	LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL; + +	// We might have a localized string for this message +	// error_args will usually be empty from the server. +	if (!error_tag.empty() +		&& LLNotifications::getInstance()->templateExists(error_tag)) +	{ +		LLNotificationsUtil::add(error_tag); +		return; +	} + +	// The server error might have a localized message for us +	std::string lang_code = LLUI::getLanguage(); +	LLSD error_desc = content["error_description"]; +	if (error_desc.has( lang_code )) +	{ +		LLSD args; +		args["MESSAGE"] = error_desc[lang_code].asString(); +		LLNotificationsUtil::add("GenericAlert", args); +		return; +	} + +	// No specific error, throw a generic one +	LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); +} + +void LLFloaterDisplayName::onCancel() +{ +	setVisible(false); +} + +void LLFloaterDisplayName::onSave() +{ +	std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString(); +	std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString(); + +	if (display_name_utf8.compare(display_name_confirm)) +	{ +		LLNotificationsUtil::add("SetDisplayNameMismatch"); +		return; +	} + +	const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes +	LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8); +	if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH) +	{ +		LLSD args; +		args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH); +		LLNotificationsUtil::add("SetDisplayNameFailedLength", args); +		return; +	} +	 +    if (LLAvatarNameCache::getInstance()->hasNameLookupURL()) +	{ +		LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));	 +	} +	else +	{ +		LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); +	} + +	setVisible(false); +} + + +////////////////////////////////////////////////////////////////////////////// +// LLInspectObjectUtil +////////////////////////////////////////////////////////////////////////////// +void LLFloaterDisplayNameUtil::registerFloater() +{ +	LLFloaterReg::add("display_name", "floater_display_name.xml", +					  &LLFloaterReg::build<LLFloaterDisplayName>); +} diff --git a/indra/newview/llpanelme.h b/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 @@ -157,6 +157,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)  {  	if(mPanelMediaSettingsGeneral) 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<LLPanel>("physics simplification"); +    LLView* child = simplification_panel->getFirstChild(); +    while (child) +    { +        child->setEnabled(false); +        child = simplification_panel->findNextSibling(child); +    }  }  // Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function 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<LLGiveMoneyInfo> give_money_ptr; +typedef std::shared_ptr<LLGiveMoneyInfo> 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<const LLAvatarData*>( pData );  		if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))  		{ -			storeAvatarProperties( pAvatarData ); -			processProfileProperties( pAvatarData ); +            mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH); +            mAvatarDataInitialized = true; +            getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);  		}  	}	  } -void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData ) +void LLFloaterPreference::saveAvatarProperties( void )  { -	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; +    const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue(); -		mAvatarDataInitialized = true; -	} -} +    if ((LLStartUp::getStartupState() == STATE_STARTED) +        && mAvatarDataInitialized +        && (allowPublish != mAllowPublish)) +    { +        std::string cap_url = gAgent.getRegionCapability("AgentProfile"); +        if (!cap_url.empty()) +        { +            mAllowPublish = allowPublish; -void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData ) -{ -	getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );	 +            LLCoros::instance().launch("requestAgentUserInfoCoro", +                boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish)); +        } +    }  } -void LLFloaterPreference::saveAvatarProperties( void ) +void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)  { -	const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue(); +    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; -	if (allowPublish) -	{ -		mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH; -	} +    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); +    httpOpts->setFollowRedirects(true); -	// -	// 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; +    std::string finalUrl = cap_url + "/" + gAgentID.asString(); +    LLSD data; +    data["allow_publish"] = allow_publish; -		LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties ); -	} +    LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    if (!status) +    { +        LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL; +        return; +    } + +    LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;  }  BOOL LLFloaterPreference::postBuild() @@ -911,7 +910,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)  	else  	{  		// Show beep, pop up dialog, etc. -		LL_INFOS() << "Can't close preferences!" << LL_ENDL; +		LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;  	}  	LLPanelLogin::updateLocationSelectorsVisibility();	 @@ -1502,13 +1501,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map      if (!LLXMLNode::parseFile(filename, root, NULL))      { -        LL_WARNS() << "Unable to parse file " << filename << LL_ENDL; +        LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;          return false;      }      if (!root->hasName("labels"))      { -        LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL; +        LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;          return false;      } @@ -1528,7 +1527,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map      }      else      { -        LL_WARNS() << filename << " failed to load" << LL_ENDL; +        LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;          return false;      } @@ -2435,7 +2434,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena      LLScrollListCtrl::Contents contents;      if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))      { -        LL_WARNS() << "Failed to load " << filename << LL_ENDL; +        LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;          return false;      }      LLXUIParser parser; @@ -2462,7 +2461,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)      LLScrollListCtrl::Contents contents;      if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))      { -        LL_WARNS() << "Failed to load " << filename << LL_ENDL; +        LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;          return false;      }      LLXUIParser parser; @@ -2568,7 +2567,7 @@ void LLPanelPreferenceControls::populateControlTable()          {              // Either unknown mode or MODE_SAVED_SETTINGS              // It doesn't have UI or actual settings yet -            LL_WARNS() << "Unimplemented mode" << LL_ENDL; +            LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;              // Searchable columns were removed, mark searchables for an update              LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); @@ -2608,7 +2607,7 @@ void LLPanelPreferenceControls::populateControlTable()      }      else      { -        LL_WARNS() << "Unimplemented mode" << LL_ENDL; +        LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;      }      // explicit update to make sure table is ready for llsearchableui @@ -2663,10 +2662,15 @@ void LLPanelPreferenceControls::cancel()          if (mConflictHandler[i].hasUnsavedChanges())          {              mConflictHandler[i].clear(); +            if (mEditingMode == i) +            { +                // cancel() can be called either when preferences floater closes +                // or when child floater closes (like advanced graphical settings) +                // in which case we need to clear and repopulate table +                regenerateControls(); +            }          }      } -    pControlsTable->clearRows(); -    pControlsTable->clearColumns();  }  void LLPanelPreferenceControls::saveSettings() 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<std::string>& names); @@ -217,7 +216,7 @@ private:  	bool mOriginalHideOnlineStatus;  	std::string mDirectoryVisibility; -	LLAvatarData mAvatarProperties; +	bool mAllowPublish; // Allow showing agent in search  	std::string mSavedCameraPreset;  	std::string mSavedGraphicsPreset;  	LOG_CLASS(LLFloaterPreference); 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<LLPanelProfile>(PANEL_PROFILE_VIEW); + +    return TRUE; +} + +void LLFloaterProfile::onClickCloseBtn(bool app_quitting) +{ +    if (!app_quitting) +    { +        if (mPanelProfile->hasUnpublishedClassifieds()) +        { +            LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(), +                boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false)); +        } +        else if (mPanelProfile->hasUnsavedChanges()) +        { +            LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(), +                boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true)); +        } +        else +        { +            closeFloater(); +        } +    } +    else +    { +        closeFloater(); +    } +} + +void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    if (can_save) +    { +        // savable content + +        if (option == 0) // Save +        { +            mPanelProfile->commitUnsavedChanges(); +            closeFloater(); +        } +        if (option == 1) // Discard +        { +            closeFloater(); +        } +        // else cancel +    } +    else +    { +        // classifieds + +        if (option == 0) // Ok +        { +            closeFloater(); +        } +        // else cancel +    } + +} + +void LLFloaterProfile::createPick(const LLPickData &data) +{ +    mPanelProfile->createPick(data); +} + +void LLFloaterProfile::showPick(const LLUUID& pick_id) +{ +    mPanelProfile->showPick(pick_id); +} + +bool LLFloaterProfile::isPickTabSelected() +{ +    return mPanelProfile->isPickTabSelected(); +} + +void LLFloaterProfile::refreshName() +{ +    if (!mNameCallbackConnection.connected()) +    { +        mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2)); +    } + +    LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife"); +    if (panel) +    { +        panel->refreshName(); +    } +} + +void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit) +{ +    mPanelProfile->showClassified(classified_id, edit); +} + +void LLFloaterProfile::createClassified() +{ +    mPanelProfile->createClassified(); +} + +void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ +    mNameCallbackConnection.disconnect(); +    setTitle(av_name.getCompleteName()); +} + +// eof 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<LLIconCtrl>("profile_pic"); + +    mCloseButton = getChild<LLButton>("close_btn"); +    mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr); + +	return TRUE; +} + +// virtual +void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent) +{ +	LLFloater::reshape(width, height, called_from_parent); +} + +// It takes a while until we get height and width information. +// When we receive it, reshape the window accordingly. +void LLFloaterProfileTexture::updateDimensions() +{ +    if (mImage.isNull()) +    { +        return; +    } +    if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) +    { +        return; +    } + +    S32 img_width = mImage->getFullWidth(); +    S32 img_height = mImage->getFullHeight(); + +    if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED +        || mLastWidth != img_width +        || mLastHeight != img_height) +    { +        mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED; +        // Asset has been fully loaded +        mUpdateDimensions = TRUE; +    } + +    mLastHeight = img_height; +    mLastWidth = img_width; + +    // Reshape the floater only when required +    if (mUpdateDimensions) +    { +        mUpdateDimensions = FALSE; + +        LLRect old_floater_rect = getRect(); +        LLRect old_image_rect = mProfileIcon->getRect(); +        S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth; +        S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight; + +        const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256 + +        S32 biggest_dim = llmax(width, height); +        if (biggest_dim > MAX_DIMENTIONS) +        { +            F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim; +            width *= scale_down; +            height *= scale_down; +        } + +        //reshape floater +        reshape(width, height); + +        gFloaterView->adjustToFitScreen(this, FALSE); +    } +} + +void LLFloaterProfileTexture::draw() +{ +    // drawFrustum +    LLView *owner = mOwnerHandle.get(); +    static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); +    drawConeToOwner(mContextConeOpacity, max_opacity, owner); + +    LLFloater::draw(); +} + +void LLFloaterProfileTexture::onOpen(const LLSD& key) +{ +    mCloseButton->setFocus(true); +} + +void LLFloaterProfileTexture::resetAsset() +{ +    mProfileIcon->setValue("Generic_Person_Large"); +    mImageID = LLUUID::null; +    if (mImage.notNull()) +    { +        mImage->setBoostLevel(mImageOldBoostLevel); +        mImage = NULL; +    } +} +void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id) +{ +    if (mImageID != image_id) +    { +        if (mImage.notNull()) +        { +            mImage->setBoostLevel(mImageOldBoostLevel); +            mImage = NULL; +        } +    } +    else +    { +        return; +    } + +    mProfileIcon->setValue(image_id); +    mImageID = image_id; +    mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +    mImageOldBoostLevel = mImage->getBoostLevel(); + +    if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) +    { +        mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded, +            0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList); + +        mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); +        mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING; +    } +    else +    { +        mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED; +    } + +    mUpdateDimensions = TRUE; +    updateDimensions(); +} + +// static +void LLFloaterProfileTexture::onTextureLoaded( +    BOOL success, +    LLViewerFetchedTexture *src_vi, +    LLImageRaw* src, +    LLImageRaw* aux_src, +    S32 discard_level, +    BOOL final, +    void* userdata) +{ +    LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata; + +    if (!handle->isDead()) +    { +        LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get()); +        if (floater && success) +        { +            floater->mUpdateDimensions = TRUE; +            floater->updateDimensions(); +        } +    } + +    if (final || !success) +    { +        delete handle; +    } +} 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<LLViewerFetchedTexture> mImage; +    S32 mImageOldBoostLevel; +    S32 mAssetStatus; +    F32 mContextConeOpacity; +    S32 mLastHeight; +    S32 mLastWidth; +    BOOL mUpdateDimensions; + +    LLHandle<LLView> mOwnerHandle; +    LLIconCtrl* mProfileIcon; +    LLButton* mCloseButton; + +    LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList; +}; +#endif  // LL_LLFLOATERPROFILETEXTURE_H 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<LLFloaterReporter>("reporter"); +    if (self) +    { +        std::string description = self->getString("chat_report_format", args); +        self->getChild<LLUICtrl>("details_edit")->setValue(description); +    } +} +  void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)  {  	getChild<LLUICtrl>("object_name")->setValue(object_name); @@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)  	mSnapshotTimer.stop();  	gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);  } - - -// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) -// { -// 	LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); -// 	if (self) -// 	{ -// 		self->getChild<LLUICtrl>("details_edit")->setValue(description); - -// 		for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); -// 		self->mMCDList.clear(); -// 		if (mcd) -// 		{ -// 			self->mMCDList.push_back(new LLMeanCollisionData(mcd)); -// 		} -// 	} -// } - -// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) -// { -// 	LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); -// 	if (self) -// 	{ -// 		LLTextEditor* text = self->getChild<LLTextEditor>("details_edit"); -// 		if (text) -// 		{	 -// 			text->insertText(description); -// 		} -// 		if (mcd) -// 		{ -// 			self->mMCDList.push_back(new LLMeanCollisionData(mcd)); -// 		} -// 	} -// } 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<LLMeanCollisionData*> 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<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it) +            { +                collection_args += "&collection_chosen=" + std::string(*it); +            } +            subs["COLLECTION"] = collection_args; +        } +    } +  	// add the user's preferred maturity (can be changed via prefs)  	std::string maturity;  	if (gAgent.prefersAdult())  	{ -		maturity = "42";  // PG,Mature,Adult +		maturity = "gma";  // PG,Mature,Adult  	}  	else if (gAgent.prefersMature())  	{ -		maturity = "21";  // PG,Mature +		maturity = "gm";  // PG,Mature  	}  	else  	{ -		maturity = "13";  // PG +		maturity = "g";  // PG  	}  	subs["MATURITY"] = maturity; 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<SearchQuery>  	{  		Optional<std::string> category; +        Optional<std::string> collection;  		Optional<std::string> query;  		SearchQuery(); @@ -84,7 +85,8 @@ public:  private:  	/*virtual*/ BOOL postBuild(); -	LLSD        mCategoryPaths; +    std::set<std::string> mSearchType; +    std::set<std::string> mCollectionType;  	U8          mSearchGodLevel;  }; 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<LLRadioGroup>("move_radio_group");  	mRadioGroupEdit		= getChild<LLRadioGroup>("edit_radio_group");  	mBtnGridOptions		= getChild<LLButton>("Options..."); -	mTitleMedia			= getChild<LLMediaCtrl>("title_media");  	mBtnLink			= getChild<LLButton>("link_btn");  	mBtnUnlink			= getChild<LLButton>("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<LLTextBox>("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<LLVOVolume*>(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> -	{ -		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<LLTextBox>("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<std::string> value_vector_str = default_media_data.getWhiteList(); -    struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> > -    { -		functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {} -         -        std::vector<std::string> 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<std::string, std::string> 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<LLPanelFace*>(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<LLUICtrl>("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::findFriendFolderUUIDImpl() const +const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const  { -	const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); +    if (parent_id.isNull()) +    { +        return LLUUID::null; +    } -	std::string friendFolderName = get_friend_folder_name(); +    LLInventoryModel::cat_array_t* cats; +    LLInventoryModel::item_array_t* items; +    gInventory.getDirectDescendentsOf(parent_id, cats, items); -	return findChildFolderUUID(callingCardsFolderID, friendFolderName); +    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;  } -const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const +// Inventorry -> +//   Calling Cards - > +//     Friends - > (the only expected folder) +//       All (the only expected folder) + +const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const  { -	LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); +    const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + +    return findFirstCallingCardSubfolder(callingCardsFolderID); +} -	std::string friendAllSubfolderName = get_friend_all_subfolder_name(); +const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const +{ +    LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); -	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<LLUUID> mLoadingAssets;  	// LLEventHost interface -	boost::shared_ptr<LLGestureListener> mListener; +	std::shared_ptr<LLGestureListener> 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<LLGroupList> 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<const LLGroupListItem*>(item1); +        std::string name1 = group_item1->getGroupName(); +        bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true); + +        const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(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(); - -	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); -	} - -	// 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); -	} - -	selectItemByUUID(highlight_id); +    if (mForAgent) +    { +        const LLUUID& 		highlight_id	= gAgent.getGroupID(); +        S32					count			= gAgent.mGroups.size(); +        LLUUID				id; +        bool				have_filter		= !mNameFilter.empty(); + +        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, group_data.mListInProfile); +        } + +        // 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 && mShowNone) +        { +            std::string loc_none = LLTrans::getString("GroupsNone"); +            addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP); +        } + +        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<LLOldEvents::LLEvent> 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<LLPanel*> items; +            getItems(items); +            for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it) +            { +                LLGroupListItem* item = dynamic_cast<LLGroupListItem*>(*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<LLButton>("info_btn");  	mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this)); -	childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this)); +    mProfileBtn = getChild<LLButton>("profile_btn"); +    mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); }); + +    mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn"); +    if (mVisibilityHideBtn) +    { +        mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); }); +    } +    mVisibilityShowBtn = findChild<LLButton>("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, LLFlatListViewEx::Params>  	{ -		Params(){}; +        Optional<bool> 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<LLOldEvents::LLEvent> 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<LLUICtrl>("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<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);  		// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice, @@ -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<LLTextBase>("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<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4); +        LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20); +        if (categories.size() >= max_count +            || depth > (max_depth + 1))          {              disabled_items.push_back(std::string("New Folder"));          } 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<LLUUID> 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<LLInventoryValidationInfo> LLInventoryModel::validate() const  {  	LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;  	S32 fatal_errs = 0; -	S32 warnings = 0; -    S32 loops = 0; -    S32 orphaned = 0; +	S32 warning_count= 0; +    S32 loop_count = 0; +    S32 orphaned_count = 0;  	if (getRootFolderID().isNull())  	{ @@ -3922,7 +3936,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  		// ParentChild should be one larger because of the special entry for null uuid.  		LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size()  							  << " parent/child " << mParentChildCategoryTree.size() << LL_ENDL; -		warnings++; + +		validation_info->mWarnings["category_map_size"]++; +		warning_count++;  	}  	S32 cat_lock = 0;  	S32 item_lock = 0; @@ -3941,32 +3957,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  		if (!cat)  		{  			LL_WARNS("Inventory") << "null cat" << LL_ENDL; -			warnings++; +			validation_info->mWarnings["null_cat"]++; +			warning_count++;  			continue;  		}  		LLUUID topmost_ancestor_id;  		// Will leave as null uuid on failure -        EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id); +        EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);          switch (res)          { -        case ANSCESTOR_MISSING: -            orphaned++; +        case ANCESTOR_MISSING: +            orphaned_count++;              break; -        case ANSCESTOR_LOOP: -            loops++; +        case ANCESTOR_LOOP: +            loop_count++;              break; -        case ANSCESTOR_OK: +        case ANCESTOR_OK:              break;          default:              LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL; -            warnings++; +			validation_info->mWarnings["unknown_ancestor_status"]++; +            warning_count++;              break;          }  		if (cat_id != cat->getUUID())  		{  			LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL; -			warnings++; +			validation_info->mWarnings["cat_id_index_mismatch"]++; +			warning_count++;  		}  		if (cat->getParentUUID().isNull()) @@ -3976,7 +3995,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  				LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root ("  									  << getRootFolderID() << ") or library root ("  									  << getLibraryRootFolderID() << ")" << LL_ENDL; -				warnings++; +				validation_info->mWarnings["null_parent"]++; +				warning_count++;  			}  		}  		cat_array_t* cats; @@ -3985,7 +4005,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  		if (!cats || !items)  		{  			LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL; -			warnings++; +			validation_info->mWarnings["direct_descendents"]++; +			warning_count++;  			continue;  		}  		if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) @@ -4003,7 +4024,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  									  << " cached " << cat->getDescendentCount()  									  << " expected " << cats->size() << "+" << items->size()  									  << "=" << cats->size() +items->size() << LL_ENDL; -				warnings++; +				validation_info->mWarnings["invalid_descendent_count"]++; +				warning_count++;  			}  		}  		if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) @@ -4027,7 +4049,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  			if (!item)  			{  				LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL; -				warnings++; +				validation_info->mWarnings["null_item_at_index"]++; +				warning_count++;  				continue;  			} @@ -4038,7 +4061,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  				LL_WARNS("Inventory") << "wrong parent for " << item_id << " found "  									  << item->getParentUUID() << " expected " << cat_id  									  << LL_ENDL; -				warnings++; +				validation_info->mWarnings["wrong_parent_for_item"]++; +				warning_count++;  			} @@ -4048,7 +4072,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  			{  				LL_WARNS("Inventory") << "item " << item_id << " found as child of "  									  << cat_id << " but not in top level mItemMap" << LL_ENDL; -				warnings++; +				validation_info->mWarnings["item_not_in_top_map"]++; +				warning_count++;  			}  			else  			{ @@ -4062,11 +4087,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  			// Topmost ancestor should be root or library.  			LLUUID topmost_ancestor_id; -            EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); -			if (found != ANSCESTOR_OK) +            EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); +			if (found != ANCESTOR_OK)  			{  				LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL; -				warnings++; +				validation_info->mWarnings["topmost_ancestor_not_found"]++; +				warning_count++;  			}  			else  			{ @@ -4077,7 +4103,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  										  << " got " << topmost_ancestor_id  										  << " expected " << getRootFolderID()  										  << " or " << getLibraryRootFolderID() << LL_ENDL; -					warnings++; +					validation_info->mWarnings["topmost_ancestor_not_recognized"]++; +					warning_count++;  				}  			}  		} @@ -4093,7 +4120,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  			{  				LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()  									  << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL; -                orphaned++; +                orphaned_count++;  			}  			else  			{ @@ -4111,7 +4138,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  				{  					LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()  										  << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL; -                    orphaned++; +                    orphaned_count++;  				}  			}  		} @@ -4120,7 +4147,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  		LLFolderType::EType folder_type = cat->getPreferredType();  		bool cat_is_in_library = false;  		LLUUID topmost_id; -		if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID()) +		if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID())  		{  			cat_is_in_library = true;  		} @@ -4153,14 +4180,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  		if (item->getUUID() != item_id)  		{  			LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL; -			warnings++; +			validation_info->mWarnings["item_id_mismatch"]++; +			warning_count++;  		}  		const LLUUID& parent_id = item->getParentUUID();  		if (parent_id.isNull())  		{  			LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL; -            orphaned++; +            orphaned_count++;  		}  		else  		{ @@ -4171,7 +4199,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  			{  				LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()  									  << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL; -                orphaned++; +                orphaned_count++;  			}  			else  			{ @@ -4188,7 +4216,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  				{  					LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()  										  << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL; -                    orphaned++; +                    orphaned_count++;  				}  			} @@ -4206,18 +4234,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  				LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()  									  << " missing backlink info at target_id " << target_id  									  << LL_ENDL; -                orphaned++; +                orphaned_count++;  			}  			// Links should have referents.  			if (item->getActualType() == LLAssetType::AT_LINK && !target_item)  			{  				LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL; -                orphaned++; +                orphaned_count++;  			}  			else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)  			{  				LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL; -                orphaned++; +                orphaned_count++;  			}  			if (target_item && target_item->getIsLinkType())  			{ @@ -4289,13 +4317,15 @@ LLPointer<LLInventoryValidationInfo> 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<LLInventoryValidationInfo> LLInventoryModel::validate() const                  {                      // It is a fatal problem or can lead to fatal problems for COF,                      // outfits, trash and other non-automatic folders. +					validation_info->mFatalSystemDuplicate++;                      fatal_errs++;                  }                  else @@ -4313,13 +4344,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const                      // For automatic folders it's not a fatal issue and shouldn't                      // break inventory or other functionality further                      // Exception: FT_SETTINGS is not automatic, but only deserves a warning. -                    warnings++; +					validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++; +                    warning_count++;                  }  			}  			if (count_elsewhere > 0)  			{  				LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL; -				warnings++; +				validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++; +				warning_count++;  			}  		}  	} @@ -4341,12 +4374,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const  	// FIXME need to fail login and tell user to retry, contact support if problem persists.  	bool valid = (fatal_errs == 0); -	LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL; +	LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL;  	validation_info->mFatalErrorCount = fatal_errs; -	validation_info->mWarningCount = warnings; -    validation_info->mLoopCount = loops; -    validation_info->mOrphanedCount = orphaned; +	validation_info->mWarningCount = warning_count; +    validation_info->mLoopCount = loop_count; +    validation_info->mOrphanedCount = orphaned_count;  	return validation_info;   } 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<std::string,U32> mWarnings; + +    S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves +    S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders + +	S32 mFatalErrorCount{0}; +	bool mFatalNoRootFolder{false}; +	S32 mFatalSystemDuplicate{0}; +	bool mFatalNoLibraryRootFolder{false}; +	bool mFatalQADebugMode{false}; -	S32 mFatalErrorCount; -	S32 mWarningCount; -    S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves -    S32 mOrphanedCount; // Missing or orphaned items, links and folders -	bool mInitialized; -	bool mFatalNoRootFolder; -	bool mFatalNoLibraryRootFolder; -	bool mFatalQADebugMode;  	std::set<LLFolderType::EType> mMissingRequiredSystemFolders;  	std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders;  }; @@ -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>  	~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<void ()> status_updated_signal_t;      void initializeSLM(const status_updated_signal_t::slot_type& cb);  	U32  getSLMStatus() const { return mMarketPlaceStatus; } +    std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; }  	void setSLMStatus(U32 status); +    void setSLMConnectionFailure(const std::string& reason);      void getSLMListings();      bool isEmpty() { return (mMarketplaceItems.size() == 0); }      void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb); @@ -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<LLVolume> 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<LLUUID> mPendingPhysicsShapeRequests;  	U32 mMeshThreadCount; - -	void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);  	LLMeshRepoThread* mThread;  	std::vector<LLMeshUploadThread*> 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<LLNameListItem*>(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. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLDropTarget : public LLView -{ -public: -	struct Params : public LLInitParam::Block<Params, LLView::Params> -	{ -		Optional<LLUUID> 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) -{} -LLDropTarget::~LLDropTarget() +////////////////////////////////////////////////////////////////////////// +// LLProfileDropTarget + +LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p) +:   LLView(p), +    mAgentID(p.agent_id)  {} -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<LLDropTarget> r("drop_target"); +static LLDefaultChildRegistry::Register<LLProfileDropTarget> 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(); - -		scrollToTop(); -	} - -	// Update data even if we are viewing same avatar profile as some data might been changed. -	setAvatarId(key.asUUID()); -	updateData(); -	updateButtons(); +    // Update data even if we are viewing same avatar profile as some data might been changed. +    setAvatarId(key.asUUID()); + +    setApplyProgress(true); +} + +void LLPanelProfileTab::setLoaded() +{ +    setApplyProgress(false); + +    mLoadingState = PROFILE_LOADED; +} + +void LLPanelProfileTab::setApplyProgress(bool started) +{ +    LLLoadingIndicator* indicator = findChild<LLLoadingIndicator>("progress_indicator"); + +    if (indicator) +    { +        indicator->setVisible(started); + +        if (started) +        { +            indicator->start(); +        } +        else +        { +            indicator->stop(); +        } +    } + +    LLView* panel = findChild<LLView>("indicator_stack"); +    if (panel) +    { +        panel->setVisible(started); +    }  } -void LLPanelProfileTab::scrollToTop() +LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab() +    : LLPanelProfileTab()  { -	LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll"); -	if (scrollContainer) -		scrollContainer->goToTop();  } -void LLPanelProfileTab::onMapButtonClick() +LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()  { -	LLAvatarActions::showOnMap(getAvatarId()); +    if (getAvatarId().notNull()) +    { +        LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); +    }  } -void LLPanelProfileTab::updateButtons() +void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)  { -	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); +    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<Params, LLView::Params> +    { +        Optional<LLUUID> 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); - -	/** -	 * Returns avatar ID. -	 */ -	virtual const LLUUID& getAvatarId() { return mAvatarId; } - -	/** -	 * Sends update data request to server. -	 */ -	virtual void updateData() = 0; - -	/** -	 * 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() {} - -	/** -	 * Resets controls visibility, state, etc. -	 */ -	virtual void resetControls(){}; - -	/** -	 * Clears all data received from server. -	 */ -	virtual void resetData(){}; - -	/*virtual*/ ~LLPanelProfileTab(); +    /** +     * 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; } + +    /** +     * 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 all data received from server. +     */ +    virtual void resetData(){}; + +    /*virtual*/ ~LLPanelProfileTab();  protected: -	LLPanelProfileTab(); +    LLPanelProfileTab(); + +    enum ELoadingState +    { +        PROFILE_INIT, +        PROFILE_LOADING, +        PROFILE_LOADED, +    }; + + +    // 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; } -	/** -	 * Scrolls panel to top when viewing avatar info for first time. -	 */ -	void scrollToTop(); +public: +    void setIsLoading() { mLoadingState = PROFILE_LOADING; } +    void resetLoading() { mLoadingState = PROFILE_INIT; } -	virtual void onMapButtonClick(); +    bool getStarted() { return mLoadingState != PROFILE_INIT; } +    bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; } -	virtual void updateButtons(); +    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<LLPanelClassifiedInfo> 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<LLButton>("back_btn")->setClickedCallback(cb); -} - -void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb) -{ -	getChild<LLButton>("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<LLUICtrl>("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<LLUICtrl>("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<LLLineEditor>("classified_name"); -	line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL); - -	LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc"); -	text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this)); - -	LLComboBox* combobox = getChild<LLComboBox>( "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<LLUICtrl>("classified_name")->setValue(makeClassifiedName()); -		getChild<LLUICtrl>("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<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]); -		getChild<LLUICtrl>("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<LLUICtrl>("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<LLAvatarClassifiedInfo*>(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<LLUICtrl>("auto_renew")->setValue(auto_renew); -			getChild<LLUICtrl>("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<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label")); -		} -	} -} - -BOOL LLPanelClassifiedEdit::isDirty() const -{ -	if(mIsNew)  -	{ -		return TRUE; -	} - -	BOOL dirty = false; - -	dirty |= LLPanelClassifiedInfo::isDirty(); -	dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty(); -	dirty |= getChild<LLUICtrl>("classified_name")->isDirty(); -	dirty |= getChild<LLUICtrl>("classified_desc")->isDirty(); -	dirty |= getChild<LLUICtrl>("category")->isDirty(); -	dirty |= getChild<LLUICtrl>("content_type")->isDirty(); -	dirty |= getChild<LLUICtrl>("auto_renew")->isDirty(); -	dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty(); - -	return dirty; -} - -void LLPanelClassifiedEdit::resetDirty() -{ -	LLPanelClassifiedInfo::resetDirty(); -	getChild<LLUICtrl>("classified_snapshot")->resetDirty(); -	getChild<LLUICtrl>("classified_name")->resetDirty(); - -	LLTextEditor* desc = getChild<LLTextEditor>("classified_desc"); -	// call blockUndo() to really reset dirty(and make isDirty work as intended) -	desc->blockUndo(); -	desc->resetDirty(); - -	getChild<LLUICtrl>("category")->resetDirty(); -	getChild<LLUICtrl>("content_type")->resetDirty(); -	getChild<LLUICtrl>("auto_renew")->resetDirty(); -	getChild<LLUICtrl>("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<LLButton>("cancel_btn")->setClickedCallback(cb); -} - -void LLPanelClassifiedEdit::resetControls() -{ -	LLPanelClassifiedInfo::resetControls(); - -	getChild<LLComboBox>("category")->setCurrentByIndex(0); -	getChild<LLComboBox>("content_type")->setCurrentByIndex(0); -	getChild<LLUICtrl>("auto_renew")->setValue(false); -	getChild<LLUICtrl>("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<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect()); -} - -U32 LLPanelClassifiedEdit::getContentType() -{ -	LLComboBox* ct_cb = getChild<LLComboBox>("content_type"); -	return ct_cb->getCurrentIndex(); -} - -void LLPanelClassifiedEdit::setContentType(U32 content_type) -{ -	LLComboBox* ct_cb = getChild<LLComboBox>("content_type"); -	ct_cb->setCurrentByIndex(content_type); -	ct_cb->resetDirty(); -} - -bool LLPanelClassifiedEdit::getAutoRenew() -{ -	return getChild<LLUICtrl>("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<LLComboBox>("category"); -	return cat_cb->getCurrentIndex(); -} - -void LLPanelClassifiedEdit::setCategory(U32 category) -{ -	LLComboBox* cat_cb = getChild<LLComboBox>("category"); -	cat_cb->setCurrentByIndex(category); -	cat_cb->resetDirty(); -} - -U8 LLPanelClassifiedEdit::getFlags() -{ -	bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean(); - -	LLComboBox* content_cb = getChild<LLComboBox>("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<LLUICtrl>("price_for_listing")->getValue().asInteger(); -} - -void LLPanelClassifiedEdit::setPriceForListing(S32 price) -{ -	getChild<LLUICtrl>("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<LLPublishClassifiedFloater>( -			"publish_classified", LLSD()); - -		if(!mPublishFloater) -		{ -			mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>( -				"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<LLUICtrl>("price_for_listing")->setValue(price); -} - -S32 LLPublishClassifiedFloater::getPrice() -{ -	return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger(); -} - -void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb) -{ -	getChild<LLButton>("publish_btn")->setClickedCallback(cb); -} - -void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb) -{ -	getChild<LLButton>("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<LLComboBox>("combobox matmedia");  	LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("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<LLMenuButton>("clipboard_color_params_btn");      mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn"); +     +    mTitleMedia = getChild<LLMediaCtrl>("title_media"); +    mTitleMediaText = getChild<LLTextBox>("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<LLComboBox>("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<LLRadioGroup>("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<LLColorSwatchCtrl>("colorswatch"); +		LLColorSwatchCtrl*	color_swatch = findChild<LLColorSwatchCtrl>("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<LLVOVolume*>(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> +    { +        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<std::string> value_vector_str = default_media_data.getWhiteList(); +    struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> > +    { +        functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {} + +        std::vector<std::string> 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<LLComboBox>("combobox matmedia");  	LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");  	LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");  	LLComboBox* combo_bumpiness = getChild<LLComboBox>("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<LLComboBox>("combobox matmedia");  	LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("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<LLComboBox>("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<LLUICtrl>("rptctrl"); -	LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");  	LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("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<LLCheckBoxCtrl>("group av sound check");  	childSetCommitCallback("group av sound check", onCommitAny, this); +    mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("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<LLParcelSelection>&	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<LLFloaterSidePanelContainer>("places"); -	if (floaterp) -	{ -		panel_places = floaterp->findChild<LLPanel>("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<LLFloaterProfile*>(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<LLPanelMe> 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<LLTextureCtrl>(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<LLPanel>("scroll_content_panel"); -	mScrollContainer = getChild<LLScrollContainer>("profile_scroll"); - -	mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight(); -	mScrollingPanelWidth = mScrollingPanel->getRect().getWidth(); - -	LLTextEditor* text_desc = getChild<LLTextEditor>(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<S32> 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<LLPickData*>(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<LLButton>("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<LLButton>("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<LLUICtrl>(XML_NAME)->setValue(name); -} - -void LLPanelPickInfo::setPickDesc(const std::string& desc) -{ -	getChild<LLUICtrl>(XML_DESC)->setValue(desc); -} - -void LLPanelPickInfo::setPickLocation(const std::string& location) -{ -	getChild<LLUICtrl>(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<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name); -		getChild<LLUICtrl>("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<LLUICtrl>("pick_name")->setValue(pick_data->name); -	getChild<LLUICtrl>("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<LLLineEditor>("pick_name"); -	line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL); - -	LLTextEditor* text_edit = getChild<LLTextEditor>("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<LLButton>("save_changes_btn")->setClickedCallback(cb); -} - -void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb) -{ -	getChild<LLButton>("cancel_btn")->setClickedCallback(cb); -} - -void LLPanelPickEdit::resetDirty() -{ -	LLPanelPickInfo::resetDirty(); - -	getChild<LLLineEditor>("pick_name")->resetDirty(); -	getChild<LLTextEditor>("pick_desc")->resetDirty(); -	mSnapshotCtrl->resetDirty(); -	mLocationChanged = false; -} - -BOOL LLPanelPickEdit::isDirty() const -{ -	if( mNewPick -		|| LLPanelPickInfo::isDirty() -		|| mLocationChanged -		|| mSnapshotCtrl->isDirty() -		|| getChild<LLLineEditor>("pick_name")->isDirty() -		|| getChild<LLTextEditor>("pick_desc")->isDirty()) -	{ -		return TRUE; -	} -	return FALSE; -} - -// PROTECTED AREA - -void LLPanelPickEdit::sendUpdate() -{ -	LLPickData pick_data; - -	// If we don't have a pick id yet, we'll need to generate one, -	// otherwise we'll keep overwriting pick_id 00000 in the database. -	if (getPickId().isNull())  -	{ -		getPickId().generate(); -	} - -	pick_data.agent_id = gAgent.getID(); -	pick_data.session_id = gAgent.getSessionID(); -	pick_data.pick_id = getPickId(); -	pick_data.creator_id = gAgent.getID();; - -	//legacy var  need to be deleted -	pick_data.top_pick = FALSE;  -	pick_data.parcel_id = mParcelId; -	pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString(); -	pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString(); -	pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); -	pick_data.pos_global = getPosGlobal(); -	pick_data.sort_order = 0; -	pick_data.enabled = TRUE; - -	LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data); - -	if(mNewPick) -	{ -		// Assume a successful create pick operation, make new number of picks -		// available immediately. Actual number of picks will be requested in  -		// LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond. -		LLAgentPicksInfo::getInstance()->incrementNumberOfPicks(); -	} -} - -void LLPanelPickEdit::onSnapshotChanged() -{ -	enableSaveButton(true); -} - -void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl) -{ -	enableSaveButton(isDirty()); -} - -void LLPanelPickEdit::resetData() -{ -	LLPanelPickInfo::resetData(); -	mLocationChanged = false; -} - -void LLPanelPickEdit::enableSaveButton(bool enable) -{ -	getChildView(XML_BTN_SAVE)->setEnabled(enable); -} - -void LLPanelPickEdit::onClickSetLocation() -{ -	// Save location for later use. -	setPosGlobal(gAgent.getPositionGlobal()); - -	std::string parcel_name, region_name; - -	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); -	if (parcel) -	{ -		mParcelId = parcel->getID(); -		parcel_name = parcel->getName(); -	} - -	LLViewerRegion* region = gAgent.getRegion(); -	if(region) -	{ -		region_name = region->getName(); -	} - -	setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); - -	mLocationChanged = true; -	enableSaveButton(TRUE); -} - -void LLPanelPickEdit::onClickSave() -{ -	sendUpdate(); - -	mLocationChanged = false; - -	LLSD params; -	params["action"] = "save_new_pick"; -	notifyParent(params); -} - -std::string LLPanelPickEdit::getLocationNotice() -{ -	static std::string notice = getString("location_notice"); -	return notice; -} - -void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type) -{ -	if(mNeedData) -	{ -		LLPanelPickInfo::processProperties(data, type); -	} -} - -// PRIVATE AREA - -void LLPanelPickEdit::initTexturePickerMouseEvents() -{ -	text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR); -	mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1)); -	mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1)); -	 -	text_icon->setVisible(FALSE); -} -		 -void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl) -{ -        text_icon->setVisible(TRUE); -} - -void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) -{ -	text_icon->setVisible(FALSE); -} diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h deleted file mode 100644 index 7a8bd66fcf..0000000000 --- a/indra/newview/llpanelpick.h +++ /dev/null @@ -1,264 +0,0 @@ -/**  - * @file llpanelpick.h - * @brief LLPanelPick class definition - * - * $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. - -#ifndef LL_LLPANELPICK_H -#define LL_LLPANELPICK_H - -#include "llpanel.h" -#include "llremoteparcelrequest.h" -#include "llavatarpropertiesprocessor.h" - -class LLIconCtrl; -class LLTextureCtrl; -class LLScrollContainer; -class LLMessageSystem; -class LLAvatarPropertiesObserver; - -/** - * Panel for displaying Pick Information - snapshot, name, description, etc. - */ -class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver -{ -	LOG_CLASS(LLPanelPickInfo); -public: -	 -	// Creates new panel -	static LLPanelPickInfo* create(); - -	virtual ~LLPanelPickInfo(); - -	/** -	 * Initializes panel properties -	 * -	 * By default Pick will be created for current Agent location. -	 * Use setPickData to change Pick properties. -	 */ -	/*virtual*/ void onOpen(const LLSD& key); - -	/*virtual*/ BOOL postBuild(); - -	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - -	/** -	 * Sends remote parcel info request to resolve parcel name from its ID. -	 */ -	void sendParcelInfoRequest(); - -	/** -	 * Sets "Back" button click callback -	 */ -	virtual void setExitCallback(const commit_callback_t& cb); - -	/** -	 * Sets "Edit" button click callback -	 */ -	virtual void setEditPickCallback(const commit_callback_t& cb); - -	//This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing -	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); -	/*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; } -	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {}; - -protected: - -	LLPanelPickInfo(); -	 -	/** -	 * Resets Pick information -	 */ -	virtual void resetData(); - -	/** -	 * Resets UI controls (visibility, values) -	 */ -	virtual void resetControls(); - -	/**  -	* "Location text" is actually the owner name, the original -	* name that owner gave the parcel, and the location. -	*/ -	static std::string createLocationText( -		const std::string& owner_name,  -		const std::string& original_name, -		const std::string& sim_name,  -		const LLVector3d& pos_global); - -	virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } -	virtual LLUUID& getAvatarId() { return mAvatarId; } - -	/** -	 * Sets snapshot id. -	 * -	 * Will mark snapshot control as valid if id is not null. -	 * Will mark snapshot control as invalid if id is null. If null id is a valid value, -	 * you have to manually mark snapshot is valid. -	 */ -	virtual void setSnapshotId(const LLUUID& id); -	 -	virtual void setPickId(const LLUUID& id) { mPickId = id; } -	virtual LLUUID& getPickId() { return mPickId; } -	 -	virtual void setPickName(const std::string& name); -	 -	virtual void setPickDesc(const std::string& desc); -	 -	virtual void setPickLocation(const std::string& location); -	 -	virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } -	virtual LLVector3d& getPosGlobal() { return mPosGlobal; } - -	/** -	 * Callback for "Map" button, opens Map -	 */ -	void onClickMap(); - -	/** -	 * Callback for "Teleport" button, teleports user to Pick location. -	 */ -	void onClickTeleport(); - -	void onClickBack(); - -protected: - -	S32						mScrollingPanelMinHeight; -	S32						mScrollingPanelWidth; -	LLScrollContainer*		mScrollContainer; -	LLPanel*				mScrollingPanel; -	LLTextureCtrl*			mSnapshotCtrl; - -	LLUUID mAvatarId; -	LLVector3d mPosGlobal; -	LLUUID mParcelId; -	LLUUID mPickId; -	LLUUID mRequestedId; -}; - -/** - * Panel for creating/editing Pick. - */ -class LLPanelPickEdit : public LLPanelPickInfo -{ -	LOG_CLASS(LLPanelPickEdit); -public: - -	/** -	 * Creates new panel -	 */ -	static LLPanelPickEdit* create(); - -	/*virtual*/ ~LLPanelPickEdit(); - -	/*virtual*/ void onOpen(const LLSD& key); - -	virtual void setPickData(const LLPickData* pick_data); - -	/*virtual*/ BOOL postBuild(); - -	/** -	 * Sets "Save" button click callback -	 */ -	virtual void setSaveCallback(const commit_callback_t& cb); - -	/** -	 * Sets "Cancel" button click callback -	 */ -	virtual void setCancelCallback(const commit_callback_t& cb); - -	/** -	 * Resets panel and all cantrols to unedited state -	 */ -	/*virtual*/ void resetDirty(); - -	/** -	 * Returns true if any of Pick properties was changed by user. -	 */ -	/*virtual*/ BOOL isDirty() const; - -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - -protected: - -	LLPanelPickEdit(); - -	/** -	 * Sends Pick properties to server. -	 */ -	void sendUpdate(); - -	/** -	 * Called when snapshot image changes. -	 */ -	void onSnapshotChanged(); -	 -	/** -	 * Callback for Pick snapshot, name and description changed event. -	 */ -	void onPickChanged(LLUICtrl* ctrl); - -	/*virtual*/ void resetData(); - -	/** -	 * Enables/disables "Save" button -	 */ -	void enableSaveButton(bool enable); - -	/** -	 * Callback for "Set Location" button click -	 */ -	void onClickSetLocation(); - -	/** -	 * Callback for "Save" button click -	 */ -	void onClickSave(); - -	std::string getLocationNotice(); - -protected: - -	bool mLocationChanged; -	bool mNeedData; -	bool mNewPick; - -private: - -	void initTexturePickerMouseEvents(); -        void onTexturePickerMouseEnter(LLUICtrl* ctrl); -	void onTexturePickerMouseLeave(LLUICtrl* ctrl); - -private: - -	LLIconCtrl* text_icon; -}; - -#endif // LL_LLPANELPICK_H diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp deleted file mode 100644 index 8294977f99..0000000000 --- a/indra/newview/llpanelpicks.cpp +++ /dev/null @@ -1,1484 +0,0 @@ -/**  - * @file llpanelpicks.cpp - * @brief LLPanelPicks and related class implementations - * - * $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 "llpanelpicks.h" - -#include "llagent.h" -#include "llagentpicksinfo.h" -#include "llcommandhandler.h" -#include "lldispatcher.h" -#include "llflatlistview.h" -#include "llfloaterreg.h" -#include "llfloatersidepanelcontainer.h" -#include "llfloaterworldmap.h" -#include "llnotificationsutil.h" -#include "llstartup.h" -#include "lltexturectrl.h" -#include "lltoggleablemenu.h" -#include "lltrans.h" -#include "llviewergenericmessage.h"	// send_generic_message -#include "llmenugl.h" -#include "llviewermenu.h" -#include "llregistry.h" - -#include "llaccordionctrl.h" -#include "llaccordionctrltab.h" -#include "llavatarpropertiesprocessor.h" -#include "llfloatersidepanelcontainer.h" -#include "llpanelavatar.h" -#include "llpanelprofile.h" -#include "llpanelpick.h" -#include "llpanelclassified.h" - -static const std::string XML_BTN_NEW = "new_btn"; -static const std::string XML_BTN_DELETE = "trash_btn"; -static const std::string XML_BTN_INFO = "info_btn"; -static const std::string XML_BTN_TELEPORT = "teleport_btn"; -static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn"; - -static const std::string PICK_ID("pick_id"); -static const std::string PICK_CREATOR_ID("pick_creator_id"); -static const std::string PICK_NAME("pick_name"); - -static const std::string CLASSIFIED_ID("classified_id"); -static const std::string CLASSIFIED_NAME("classified_name"); - - -static LLPanelInjector<LLPanelPicks> t_panel_picks("panel_picks"); - - -class LLPickHandler : public LLCommandHandler, -					  public LLAvatarPropertiesObserver -{ -public: - -	std::set<LLUUID> mPickIds; -	 -	// requires trusted browser to trigger -	LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { } - -	bool handle(const LLSD& params, const LLSD& query_map, -		LLMediaCtrl* web) -	{ -		if (LLStartUp::getStartupState() < STATE_STARTED) -		{ -			return true; -		} - -		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks")) -		{ -			LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); -			return true; -		} - -		// handle app/classified/create urls first -		if (params.size() == 1 && params[0].asString() == "create") -		{ -			createPick(); -			return true; -		} - -		// then handle the general app/pick/{UUID}/{CMD} urls -		if (params.size() < 2) -		{ -			return false; -		} - -		// get the ID for the pick_id -		LLUUID pick_id; -		if (!pick_id.set(params[0], FALSE)) -		{ -			return false; -		} - -		// edit the pick in the side tray. -		// need to ask the server for more info first though... -		const std::string verb = params[1].asString(); -		if (verb == "edit") -		{		 -			mPickIds.insert(pick_id); -			LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this); -			LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(gAgent.getID(),pick_id); -			return true; -		} -		else -		{ -			LL_WARNS() << "unknown verb " << verb << LL_ENDL; -			return false; -		} -	} - -	void createPick() -	{ -		// open the new pick panel on the Picks floater -		LLFloater* picks_floater = LLFloaterReg::showInstance("picks"); - -		LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks"); -		if (picks) -		{ -			picks->createNewPick(); -		} -	} - -	void editPick(LLPickData* pick_info) -	{ -		LLSD params; -		params["open_tab_name"] = "panel_picks"; -		params["show_tab_panel"] = "edit_pick"; -		params["pick_id"] = pick_info->pick_id; -		params["avatar_id"] = pick_info->creator_id; -		params["snapshot_id"] = pick_info->snapshot_id; -		params["pick_name"] = pick_info->name; -		params["pick_desc"] = pick_info->desc; -		LLFloaterSidePanelContainer::showPanel("picks", params); -	} -	 -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type) -	{ -		if (APT_PICK_INFO != type) -		{ -			return; -		} - -		// is this the pick that we asked for? -		LLPickData* pick_info = static_cast<LLPickData*>(data); -		if (!pick_info || mPickIds.find(pick_info->pick_id) == mPickIds.end()) -		{ -			return; -		} - -		// open the edit side tray for this pick -		if (pick_info->creator_id == gAgent.getID()) -		{ -			editPick(pick_info); -		} -		else -		{ -			LL_WARNS() << "Can't edit a pick you did not create" << LL_ENDL; -		} - -		// remove our observer now that we're done -		mPickIds.erase(pick_info->pick_id); -		LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this); -	} -}; - -LLPickHandler gPickHandler; - -class LLClassifiedHandler : -	public LLCommandHandler, -	public LLAvatarPropertiesObserver -{ -public: -	// throttle calls from untrusted browsers -	LLClassifiedHandler() :	LLCommandHandler("classified", UNTRUSTED_THROTTLE) {} - -	std::set<LLUUID> mClassifiedIds; - -	std::string mRequestVerb; -	 -	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) -	{ -		if (LLStartUp::getStartupState() < STATE_STARTED) -		{ -			return true; -		} - -		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds")) -		{ -			LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); -			return true; -		} - -		// handle app/classified/create urls first -		if (params.size() == 1 && params[0].asString() == "create") -		{ -			createClassified(); -			return true; -		} - -		// then handle the general app/classified/{UUID}/{CMD} urls -		if (params.size() < 2) -		{ -			return false; -		} - -		// get the ID for the classified -		LLUUID classified_id; -		if (!classified_id.set(params[0], FALSE)) -		{ -			return false; -		} - -		// show the classified in the side tray. -		// need to ask the server for more info first though... -		const std::string verb = params[1].asString(); -		if (verb == "about") -		{ -			mRequestVerb = verb; -			mClassifiedIds.insert(classified_id); -			LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this); -			LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id); -			return true; -		} -		else if (verb == "edit") -		{ -			mRequestVerb = verb; -			mClassifiedIds.insert(classified_id); -			LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this); -			LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id); -			return true; -		} - -		return false; -	} - -	void createClassified() -	{ -		// open the new classified panel on the Picks floater -		LLFloater* picks_floater = LLFloaterReg::showInstance("picks"); - -		LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks"); -		if (picks) -		{ -			picks->createNewClassified(); -		} -	} - -	void openClassified(LLAvatarClassifiedInfo* c_info) -	{ -		if (mRequestVerb == "about") -		{ -			// open the classified info panel on the Me > Picks sidetray -			LLSD params; -			params["id"] = c_info->creator_id; -			params["open_tab_name"] = "panel_picks"; -			params["show_tab_panel"] = "classified_details"; -			params["classified_id"] = c_info->classified_id; -			params["classified_creator_id"] = c_info->creator_id; -			params["classified_snapshot_id"] = c_info->snapshot_id; -			params["classified_name"] = c_info->name; -			params["classified_desc"] = c_info->description; -			params["from_search"] = true; -			LLFloaterSidePanelContainer::showPanel("picks", params); -		} -		else if (mRequestVerb == "edit") -		{ -			if (c_info->creator_id == gAgent.getID()) -			{ -				LL_WARNS() << "edit in progress" << LL_ENDL; -				// open the new classified panel on the Me > Picks sidetray -				LLSD params; -				params["id"] = gAgent.getID(); -				params["open_tab_name"] = "panel_picks"; -				params["show_tab_panel"] = "edit_classified"; -				params["classified_id"] = c_info->classified_id; -				LLFloaterSidePanelContainer::showPanel("my_profile", params); -			} -			else -			{ -				LL_WARNS() << "Can't edit a classified you did not create" << LL_ENDL; -			} -		} -	} - -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type) -	{ -		if (APT_CLASSIFIED_INFO != type) -		{ -			return; -		} - -		// is this the classified that we asked for? -		LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); -		if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end()) -		{ -			return; -		} - -		// open the detail side tray for this classified -		openClassified(c_info); - -		// remove our observer now that we're done -		mClassifiedIds.erase(c_info->classified_id); -		LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this); -	} - -}; -LLClassifiedHandler gClassifiedHandler; - -////////////////////////////////////////////////////////////////////////// - - -//----------------------------------------------------------------------------- -// LLPanelPicks -//----------------------------------------------------------------------------- -LLPanelPicks::LLPanelPicks() -:	LLPanelProfileTab(), -	mPopupMenu(NULL), -	mProfilePanel(NULL), -	mPickPanel(NULL), -	mPicksList(NULL), -	mClassifiedsList(NULL), -	mPanelPickInfo(NULL), -	mPanelPickEdit(NULL), -	mPlusMenu(NULL), -	mPicksAccTab(NULL), -	mClassifiedsAccTab(NULL), -	mPanelClassifiedInfo(NULL), -	mNoClassifieds(false), -	mNoPicks(false) -{ -} - -LLPanelPicks::~LLPanelPicks() -{ -	if(getAvatarId().notNull()) -	{ -		LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); -	} -} - -void* LLPanelPicks::create(void* data /* = NULL */) -{ -	return new LLPanelPicks(); -} - -void LLPanelPicks::updateData() -{ -	// Send Picks request only when we need to, not on every onOpen(during tab switch). -	if(isDirty()) -	{ -		mNoPicks = false; -		mNoClassifieds = false; - -		mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText")); -		mNoItemsLabel->setVisible(TRUE); - -		mPicksList->clear(); -		LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId()); - -		mClassifiedsList->clear(); -		LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId()); -	} -} - -void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) -{ -	if(APT_PICKS == type) -	{ -		LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); -		if(avatar_picks && getAvatarId() == avatar_picks->target_id) -		{ -			LLAvatarName av_name; -			LLAvatarNameCache::get(getAvatarId(), &av_name); -			getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName()); -			 -			// Save selection, to be able to edit same item after saving changes. See EXT-3023. -			LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID]; - -			mPicksList->clear(); - -			LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); -			for(; avatar_picks->picks_list.end() != it; ++it) -			{ -				LLUUID pick_id = it->first; -				std::string pick_name = it->second; - -				LLPickItem* picture = LLPickItem::create(); -				picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this)); -				picture->setPickName(pick_name); -				picture->setPickId(pick_id); -				picture->setCreatorId(getAvatarId()); - -				LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture); -				picture->update(); - -				LLSD pick_value = LLSD(); -				pick_value.insert(PICK_ID, pick_id); -				pick_value.insert(PICK_NAME, pick_name); -				pick_value.insert(PICK_CREATOR_ID, getAvatarId()); - -				mPicksList->addItem(picture, pick_value); - -				// Restore selection by item id.  -				if ( pick_id == selected_id ) -					mPicksList->selectItemByValue(pick_value); - -				picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1)); -				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4)); -				picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this)); -			} - -			showAccordion("tab_picks", mPicksList->size()); - -			resetDirty(); -			updateButtons(); -		} -		 -		mNoPicks = !mPicksList->size(); -	} -	else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type)) -	{ -		LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data); -		if(c_info && getAvatarId() == c_info->target_id) -		{ -			// do not clear classified list in case we will receive two or more data packets. -			// list has been cleared in updateData(). (fix for EXT-6436) - -			LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin(); -			for(; c_info->classifieds_list.end() != it; ++it) -			{ -				LLAvatarClassifieds::classified_data c_data = *it; - -				LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id); -				c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this)); -				c_item->setClassifiedName(c_data.name); - -				LLSD pick_value = LLSD(); -				pick_value.insert(CLASSIFIED_ID, c_data.classified_id); -				pick_value.insert(CLASSIFIED_NAME, c_data.name); - -				if (!findClassifiedById(c_data.classified_id)) -				{ -					mClassifiedsList->addItem(c_item, pick_value); -				} - -				c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1)); -				c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4)); -				c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this)); -			} - -			showAccordion("tab_classifieds", mClassifiedsList->size()); - -			resetDirty(); -			updateButtons(); -		} -		 -		mNoClassifieds = !mClassifiedsList->size(); -	} - -    updateNoItemsLabel(); -} - -LLPickItem* LLPanelPicks::getSelectedPickItem() -{ -	LLPanel* selected_item = mPicksList->getSelectedItem(); -	if (!selected_item) return NULL; - -	return dynamic_cast<LLPickItem*>(selected_item); -} - -LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem() -{ -	LLPanel* selected_item = mClassifiedsList->getSelectedItem(); -	if (!selected_item)  -	{ -		return NULL; -	} -	return dynamic_cast<LLClassifiedItem*>(selected_item); -} - -BOOL LLPanelPicks::postBuild() -{ -	mPicksList = getChild<LLFlatListView>("picks_list"); -	mClassifiedsList = getChild<LLFlatListView>("classifieds_list"); - -	mPicksList->setCommitOnSelectionChange(true); -	mClassifiedsList->setCommitOnSelectionChange(true); - -	mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList)); -	mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList)); - -	mPicksList->setNoItemsCommentText(getString("no_picks")); -	mClassifiedsList->setNoItemsCommentText(getString("no_classifieds")); - -	mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text"); - -	childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this)); -	childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this)); -	childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this)); -	childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this)); -	childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this)); - -	mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks"); -	mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab)); -	mPicksAccTab->setDisplayChildren(true); - -	mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds"); -	mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab)); -	mClassifiedsAccTab->setDisplayChildren(false); -	 -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; -	registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this)); -	registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));  -	registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this)); -	registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this)); -	registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this)); -	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar; -	enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2)); - -	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar; -	plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2)); -	mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2)); -	mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	 -	return TRUE; -} - -void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param) -{ -	std::string value = param.asString(); - -	if("new_pick" == value) -	{ -		createNewPick(); -	} -	else if("new_classified" == value) -	{ -		createNewClassified(); -	} -} - -bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const -{ -	std::string command_name = userdata.asString(); - -	if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached()) -	{ -		return false; -	} - -	return true; -} - -bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item) -{ -	if(c_item) -	{ -		LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()]; -		if(panel) -		{ -			 return !panel->isNewWithErrors(); -		} - -		// we've got this classified from server - it's published -		return true; -	} -	return false; -} - -void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab) -{ -	if(!mPicksAccTab->getDisplayChildren()) -	{ -		mPicksList->resetSelection(true); -	} -	if(!mClassifiedsAccTab->getDisplayChildren()) -	{ -		mClassifiedsList->resetSelection(true); -	} - -	updateButtons(); -} - -void LLPanelPicks::onOpen(const LLSD& key) -{ -	const LLUUID id(key.asUUID()); -	BOOL self = (gAgent.getID() == id); - -	// only agent can edit her picks  -	getChildView("edit_panel")->setEnabled(self); -	getChildView("edit_panel")->setVisible( self); - -	// Disable buttons when viewing profile for first time -	if(getAvatarId() != id) -	{ -		getChildView(XML_BTN_INFO)->setEnabled(FALSE); -		getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE); -		getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE); -	} - -	// and see a special title - set as invisible by default in xml file -	if (self) -	{ -		getChildView("pick_title")->setVisible( !self); -		getChildView("pick_title_agent")->setVisible( self); - -		mPopupMenu->setItemVisible("pick_delete", TRUE); -		mPopupMenu->setItemVisible("pick_edit", TRUE); -		mPopupMenu->setItemVisible("pick_separator", TRUE); -	} - -	if(getAvatarId() != id) -	{ -		showAccordion("tab_picks", false); -		showAccordion("tab_classifieds", false); - -		mPicksList->goToTop(); -		// Set dummy value to make panel dirty and make it reload picks -		setValue(LLSD()); -	} - -	LLPanelProfileTab::onOpen(key); -} - -void LLPanelPicks::onClosePanel() -{ -	if (mPanelClassifiedInfo) -	{ -		onPanelClassifiedClose(mPanelClassifiedInfo); -	} -	if (mPanelPickInfo) -	{ -		onPanelPickClose(mPanelPickInfo); -	} -} - -void LLPanelPicks::onListCommit(const LLFlatListView* f_list) -{ -	// Make sure only one of the lists has selection. -	if(f_list == mPicksList) -	{ -		mClassifiedsList->resetSelection(true); -	} -	else if(f_list == mClassifiedsList) -	{ -		mPicksList->resetSelection(true); -	} -	else -	{ -		LL_WARNS() << "Unknown list" << LL_ENDL; -	} - -	updateButtons(); -} - -//static -void LLPanelPicks::onClickDelete() -{ -	LLSD value = mPicksList->getSelectedValue(); -	if (value.isDefined()) -	{ -		LLSD args;  -		args["PICK"] = value[PICK_NAME];  -		LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2));  -		return; -	} - -	value = mClassifiedsList->getSelectedValue(); -	if(value.isDefined()) -	{ -		LLSD args;  -		args["NAME"] = value[CLASSIFIED_NAME];  -		LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2));  -		return; -	} -} - -bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response)  -{ -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -	LLSD pick_value = mPicksList->getSelectedValue(); - -	if (0 == option) -	{ -		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]); -		mPicksList->removeItemByValue(pick_value); -         -        mNoPicks = !mPicksList->size(); -        if (mNoPicks) -        { -            showAccordion("tab_picks", false); -        } -        updateNoItemsLabel(); -	} -	updateButtons(); -	return false; -} - -bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)  -{ -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -	LLSD value = mClassifiedsList->getSelectedValue(); - -	if (0 == option) -	{ -		LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]); -		mClassifiedsList->removeItemByValue(value); - -        mNoClassifieds = !mClassifiedsList->size(); -        if (mNoClassifieds) -        { -            showAccordion("tab_classifieds", false); -        } -        updateNoItemsLabel(); -	} -	updateButtons(); -	return false; -} - -bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response ) -{ -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - -	if (0 == option) -	{ -		onClickTeleport(); -	} -	return false; -} - -//static -void LLPanelPicks::onClickTeleport() -{ -	LLPickItem* pick_item = getSelectedPickItem(); -	LLClassifiedItem* c_item = getSelectedClassifiedItem(); - -	LLVector3d pos; -	if(pick_item) -		pos = pick_item->getPosGlobal(); -	else if(c_item) -	{ -		pos = c_item->getPosGlobal(); -		LLPanelClassifiedInfo::sendClickMessage("teleport", false, -			c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); -	} - -	if (!pos.isExactlyZero()) -	{ -		gAgent.teleportViaLocation(pos); -		LLFloaterWorldMap::getInstance()->trackLocation(pos); -	} -} - -//static -void LLPanelPicks::onClickMap() -{ -	LLPickItem* pick_item = getSelectedPickItem(); -	LLClassifiedItem* c_item = getSelectedClassifiedItem(); - -	LLVector3d pos; -	if (pick_item) -		pos = pick_item->getPosGlobal(); -	else if(c_item) -	{ -		LLPanelClassifiedInfo::sendClickMessage("map", false, -			c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); -		pos = c_item->getPosGlobal(); -	} - -	LLFloaterWorldMap::getInstance()->trackLocation(pos); -	LLFloaterReg::showInstance("world_map", "center"); -} - - -void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask) -{ -	updateButtons(); - -	if (mPopupMenu) -	{ -		mPopupMenu->buildDrawLabels(); -		mPopupMenu->updateParent(LLMenuGL::sMenuContainer); -		((LLContextMenu*)mPopupMenu)->show(x, y); -		LLMenuGL::showPopup(item, mPopupMenu, x, y); -	} -} - -void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item) -{ -	LLSD pick_value = mPicksList->getSelectedValue(); -	if (pick_value.isUndefined()) return; -	 -	LLSD args;  -	args["PICK"] = pick_value[PICK_NAME];  -	LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));  -} - -void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item) -{ -	LLSD value = mClassifiedsList->getSelectedValue(); -	if (value.isUndefined()) return; - -	LLSD args;  -	args["CLASSIFIED"] = value[CLASSIFIED_NAME];  -	LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));  -} - -void LLPanelPicks::updateButtons() -{ -	bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0; - -	if (getAvatarId() == gAgentID) -	{ -		getChildView(XML_BTN_DELETE)->setEnabled(has_selected); -	} - -	getChildView(XML_BTN_INFO)->setEnabled(has_selected); -	getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected); -	getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected); - -	LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); -	if(c_item) -	{ -		getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item)); -	} -} - -void LLPanelPicks::updateNoItemsLabel() -{ -    bool no_data = mNoPicks && mNoClassifieds; -    mNoItemsLabel->setVisible(no_data); -    if (no_data) -    { -        if (getAvatarId() == gAgentID) -        { -            mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText")); -        } -        else -        { -            mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText")); -        } -    } -} - -void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) -{ -	mProfilePanel = profile_panel; -} - - -void LLPanelPicks::buildPickPanel() -{ -// 	if (mPickPanel == NULL) -// 	{ -// 		mPickPanel = new LLPanelPick(); -// 		mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL)); -// 	} -} - -void LLPanelPicks::onClickPlusBtn() -{ -	LLRect rect(getChildView(XML_BTN_NEW)->getRect()); - -	mPlusMenu->updateParent(LLMenuGL::sMenuContainer); -	mPlusMenu->setButtonRect(rect, this); -	LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop); -} - -void LLPanelPicks::createNewPick() -{ -	createPickEditPanel(); - -	getProfilePanel()->openPanel(mPanelPickEdit, LLSD()); -} - -void LLPanelPicks::createNewClassified() -{ -	LLPanelClassifiedEdit* panel = NULL; -	createClassifiedEditPanel(&panel); - -	getProfilePanel()->openPanel(panel, LLSD()); -} - -void LLPanelPicks::onClickInfo() -{ -	if(mPicksList->numSelected() > 0) -	{ -		openPickInfo(); -	} -	else if(mClassifiedsList->numSelected() > 0) -	{ -		openClassifiedInfo(); -	} -} - -void LLPanelPicks::openPickInfo() -{ -	LLSD selected_value = mPicksList->getSelectedValue(); -	if (selected_value.isUndefined()) return; - -	LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem(); - -	createPickInfoPanel(); - -	LLSD params; -	params["pick_id"] = pick->getPickId(); -	params["avatar_id"] = pick->getCreatorId(); -	params["snapshot_id"] = pick->getSnapshotId(); -	params["pick_name"] = pick->getPickName(); -	params["pick_desc"] = pick->getPickDesc(); - -	getProfilePanel()->openPanel(mPanelPickInfo, params); -} - -void LLPanelPicks::openClassifiedInfo() -{ -	LLSD selected_value = mClassifiedsList->getSelectedValue(); -	if (selected_value.isUndefined()) return; - -	LLClassifiedItem* c_item = getSelectedClassifiedItem(); -	LLSD params; -	params["classified_id"] = c_item->getClassifiedId(); -	params["classified_creator_id"] = c_item->getAvatarId(); -	params["classified_snapshot_id"] = c_item->getSnapshotId(); -	params["classified_name"] = c_item->getClassifiedName(); -	params["classified_desc"] = c_item->getDescription(); -	params["from_search"] = false; - -	openClassifiedInfo(params); -} - -void LLPanelPicks::openClassifiedInfo(const LLSD ¶ms) -{ -	createClassifiedInfoPanel(); -	getProfilePanel()->openPanel(mPanelClassifiedInfo, params); -} - -void LLPanelPicks::openClassifiedEdit(const LLSD& params) -{ -	LLUUID classified_id = params["classified_id"].asUUID();; -	LL_INFOS() << "opening classified " << classified_id << " for edit" << LL_ENDL; -	editClassified(classified_id); -} - -void LLPanelPicks::showAccordion(const std::string& name, bool show) -{ -	LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name); -	tab->setVisible(show); -	LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion"); -	acc->arrange(); -} - -void LLPanelPicks::onPanelPickClose(LLPanel* panel) -{ -	getProfilePanel()->closePanel(panel); -} - -void LLPanelPicks::onPanelPickSave(LLPanel* panel) -{ -	onPanelPickClose(panel); -	updateButtons(); -} - -void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel) -{ -	if(!panel->canClose()) -	{ -		return; -	} - -	if(panel->isNew()) -	{ -		mEditClassifiedPanels[panel->getClassifiedId()] = panel; - -		LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId()); -		c_item->fillIn(panel); - -		LLSD c_value; -		c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId()); -		c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName()); -		mClassifiedsList->addItem(c_item, c_value, ADD_TOP); - -		c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1)); -		c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4)); -		c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this)); -		c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this)); - -		// order does matter, showAccordion will invoke arrange for accordions. -		mClassifiedsAccTab->changeOpenClose(false); -		showAccordion("tab_classifieds", true); -	} -	else if(panel->isNewWithErrors()) -	{ -		LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); -		llassert(c_item); -		if (c_item) -		{ -			c_item->fillIn(panel); -		} -	} -	else  -	{ -		onPanelClassifiedClose(panel); -		return; -	} - -	onPanelPickClose(panel); -	updateButtons(); -} - -void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel) -{ -	if(panel->getInfoLoaded() && !panel->isDirty()) -	{ -		std::vector<LLSD> values; -		mClassifiedsList->getValues(values); -		for(size_t n = 0; n < values.size(); ++n) -		{ -			LLUUID c_id = values[n][CLASSIFIED_ID].asUUID(); -			if(panel->getClassifiedId() == c_id) -			{ -				LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>( -					mClassifiedsList->getItemByValue(values[n])); -				llassert(c_item); -				if (c_item) -				{ -					c_item->setClassifiedName(panel->getClassifiedName()); -					c_item->setDescription(panel->getDescription()); -					c_item->setSnapshotId(panel->getSnapshotId()); -				} -			} -		} -	} - -	onPanelPickClose(panel); -	updateButtons(); -} - -void LLPanelPicks::createPickInfoPanel() -{ -	if(!mPanelPickInfo) -	{ -		mPanelPickInfo = LLPanelPickInfo::create(); -		mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo)); -		mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this)); -		mPanelPickInfo->setVisible(FALSE); -	} -} - -void LLPanelPicks::createClassifiedInfoPanel() -{ -	mPanelClassifiedInfo = LLPanelClassifiedInfo::create(); -	mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo)); -	mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this)); -	mPanelClassifiedInfo->setVisible(FALSE); -} - -void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel) -{ -	if(panel) -	{ -		LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create(); -		new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel)); -		new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel)); -		new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel)); -		new_panel->setVisible(FALSE); -		*panel = new_panel; -	} -} - -void LLPanelPicks::createPickEditPanel() -{ -	mPanelPickEdit = LLPanelPickEdit::create(); -	mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); -	mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit)); -	mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); -	mPanelPickEdit->setVisible(FALSE); -} - -// void LLPanelPicks::openPickEditPanel(LLPickItem* pick) -// { -// 	if(!pick) -// 	{ -// 		return; -// 	} -// } - -// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick) -// { -// 	if(!mPanelPickInfo) -// 	{ -// 		mPanelPickInfo = LLPanelPickInfo::create(); -// 		mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo)); -// 		mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this)); -// 		mPanelPickInfo->setVisible(FALSE); -// 	} -//  -// 	LLSD params; -// 	params["pick_id"] = pick->getPickId(); -// 	params["avatar_id"] = pick->getCreatorId(); -// 	params["snapshot_id"] = pick->getSnapshotId(); -// 	params["pick_name"] = pick->getPickName(); -// 	params["pick_desc"] = pick->getPickDesc(); -//  -// 	getProfilePanel()->openPanel(mPanelPickInfo, params); -// } - -void LLPanelPicks::openPickEdit(const LLSD& params) -{ -	createPickEditPanel(); -	getProfilePanel()->openPanel(mPanelPickEdit, params); -} - -void LLPanelPicks::onPanelPickEdit() -{ -	LLSD selected_value = mPicksList->getSelectedValue(); -	if (selected_value.isUndefined()) return; - -	LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem()); -	 -	createPickEditPanel(); - -	LLSD params; -	params["pick_id"] = pick->getPickId(); -	params["avatar_id"] = pick->getCreatorId(); -	params["snapshot_id"] = pick->getSnapshotId(); -	params["pick_name"] = pick->getPickName(); -	params["pick_desc"] = pick->getPickDesc(); - -	getProfilePanel()->openPanel(mPanelPickEdit, params); -} - -void LLPanelPicks::onPanelClassifiedEdit() -{ -	LLSD selected_value = mClassifiedsList->getSelectedValue(); -	if (selected_value.isUndefined())  -	{ -		return; -	} - -	LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); -	llassert(c_item); -	if (!c_item) -	{ -		return; -	} -	editClassified(c_item->getClassifiedId()); -} - -LLClassifiedItem *LLPanelPicks::findClassifiedById(const LLUUID& classified_id) -{ -	// HACK - find item by classified id.  Should be a better way. -	std::vector<LLPanel*> items; -	mClassifiedsList->getItems(items); -	LLClassifiedItem* c_item = NULL; -	for(std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it) -	{ -		LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(*it); -		if (test_item && test_item->getClassifiedId() == classified_id) -		{ -			c_item = test_item; -			break; -		} -	} -	return c_item; -} - -void LLPanelPicks::editClassified(const LLUUID&  classified_id) -{ -	LLClassifiedItem* c_item = findClassifiedById(classified_id); -	if (!c_item) -	{ -		LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL; -		return; -	} - -	LLSD params; -	params["classified_id"] = c_item->getClassifiedId(); -	params["classified_creator_id"] = c_item->getAvatarId(); -	params["snapshot_id"] = c_item->getSnapshotId(); -	params["name"] = c_item->getClassifiedName(); -	params["desc"] = c_item->getDescription(); -	params["category"] = (S32)c_item->getCategory(); -	params["content_type"] = (S32)c_item->getContentType(); -	params["auto_renew"] = c_item->getAutoRenew(); -	params["price_for_listing"] = c_item->getPriceForListing(); -	params["location_text"] = c_item->getLocationText(); - -	LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()]; -	if(!panel) -	{ -		createClassifiedEditPanel(&panel); -		mEditClassifiedPanels[c_item->getClassifiedId()] = panel; -	} -	getProfilePanel()->openPanel(panel, params); -	panel->setPosGlobal(c_item->getPosGlobal()); -} - -void LLPanelPicks::onClickMenuEdit() -{ -	if(getSelectedPickItem()) -	{ -		onPanelPickEdit(); -	} -	else if(getSelectedClassifiedItem()) -	{ -		onPanelClassifiedEdit(); -	} -} - -bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data) -{ -	std::string param = user_data.asString(); - -	LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); -	if(c_item && "info" == param) -	{ -		// dont show Info panel if classified was not created -		return isClassifiedPublished(c_item); -	} - -	return true; -} - -inline LLPanelProfile* LLPanelPicks::getProfilePanel() -{ -	llassert_always(NULL != mProfilePanel); -	return mProfilePanel; -} - -//----------------------------------------------------------------------------- -// LLPanelPicks -//----------------------------------------------------------------------------- -LLPickItem::LLPickItem() -: LLPanel() -, mPickID(LLUUID::null) -, mCreatorID(LLUUID::null) -, mParcelID(LLUUID::null) -, mSnapshotID(LLUUID::null) -, mNeedData(true) -{ -	buildFromFile("panel_pick_list_item.xml"); -} - -LLPickItem::~LLPickItem() -{ -	if (mCreatorID.notNull()) -	{ -		LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); -	} - -} - -LLPickItem* LLPickItem::create() -{ -	return new LLPickItem(); -} - -void LLPickItem::init(LLPickData* pick_data) -{ -	setPickDesc(pick_data->desc); -	setSnapshotId(pick_data->snapshot_id); -	mPosGlobal = pick_data->pos_global; -	mSimName = pick_data->sim_name; -	mPickDescription = pick_data->desc; -	mUserName = pick_data->user_name; -	mOriginalName = pick_data->original_name; - -	LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture"); -	picture->setImageAssetID(pick_data->snapshot_id); -} - -void LLPickItem::setPickName(const std::string& name) -{ -	mPickName = name; -	getChild<LLUICtrl>("picture_name")->setValue(name); - -} - -const std::string& LLPickItem::getPickName() -{ -	return mPickName; -} - -const LLUUID& LLPickItem::getCreatorId() -{ -	return mCreatorID; -} - -const LLUUID& LLPickItem::getSnapshotId() -{ -	return mSnapshotID; -} - -void LLPickItem::setPickDesc(const std::string& descr) -{ -	getChild<LLUICtrl>("picture_descr")->setValue(descr); -} - -void LLPickItem::setPickId(const LLUUID& id) -{ -	mPickID = id; -} - -const LLUUID& LLPickItem::getPickId() -{ -	return mPickID; -} - -const LLVector3d& LLPickItem::getPosGlobal() -{ -	return mPosGlobal; -} - -const std::string LLPickItem::getDescription() -{ -	return getChild<LLUICtrl>("picture_descr")->getValue().asString(); -} - -void LLPickItem::update() -{ -	setNeedData(true); -	LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID); -} - -void LLPickItem::processProperties(void *data, EAvatarProcessorType type) -{ -	if (APT_PICK_INFO != type)  -	{ -		return; -	} - -	LLPickData* pick_data = static_cast<LLPickData *>(data); -	if (!pick_data || mPickID != pick_data->pick_id)  -	{ -		return; -	} - -	init(pick_data); -	setNeedData(false); -	LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); -} - -void set_child_visible(LLView* parent, const std::string& child_name, bool visible) -{ -	parent->getChildView(child_name)->setVisible(visible); -} - -BOOL LLPickItem::postBuild() -{ -	setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true)); -	setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false)); -	return TRUE; -} - -void LLPickItem::setValue(const LLSD& value) -{ -	if (!value.isMap()) return;; -	if (!value.has("selected")) return; -	getChildView("selected_icon")->setVisible( value["selected"]); -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id) - : LLPanel() - , mAvatarId(avatar_id) - , mClassifiedId(classified_id) -{ -	buildFromFile("panel_classifieds_list_item.xml"); - -	LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); -	LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); -} - -LLClassifiedItem::~LLClassifiedItem() -{ -	LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); -} - -void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type) -{ -	if(APT_CLASSIFIED_INFO != type) -	{ -		return; -	} - -	LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); -	if( !c_info || c_info->classified_id != getClassifiedId() ) -	{ -		return; -	} - -	setClassifiedName(c_info->name); -	setDescription(c_info->description); -	setSnapshotId(c_info->snapshot_id); -	setPosGlobal(c_info->pos_global); - -	LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); -} - -BOOL LLClassifiedItem::postBuild() -{ -	setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true)); -	setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false)); -	return TRUE; -} - -void LLClassifiedItem::setValue(const LLSD& value) -{ -	if (!value.isMap()) return;; -	if (!value.has("selected")) return; -	getChildView("selected_icon")->setVisible( value["selected"]); -} - -void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel) -{ -	if(!panel) -	{ -		return; -	} - -	setClassifiedName(panel->getClassifiedName()); -	setDescription(panel->getDescription()); -	setSnapshotId(panel->getSnapshotId()); -	setCategory(panel->getCategory()); -	setContentType(panel->getContentType()); -	setAutoRenew(panel->getAutoRenew()); -	setPriceForListing(panel->getPriceForListing()); -	setPosGlobal(panel->getPosGlobal()); -	setLocationText(panel->getClassifiedLocation()); -} - -void LLClassifiedItem::setClassifiedName(const std::string& name) -{ -	getChild<LLUICtrl>("name")->setValue(name); -} - -void LLClassifiedItem::setDescription(const std::string& desc) -{ -	getChild<LLUICtrl>("description")->setValue(desc); -} - -void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id) -{ -	getChild<LLUICtrl>("picture")->setValue(snapshot_id); -} - -LLUUID LLClassifiedItem::getSnapshotId() -{ -	return getChild<LLUICtrl>("picture")->getValue(); -} - -//EOF diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h deleted file mode 100644 index fd7688b99d..0000000000 --- a/indra/newview/llpanelpicks.h +++ /dev/null @@ -1,315 +0,0 @@ -/**  - * @file llpanelpicks.h - * @brief LLPanelPicks and related class definitions - * - * $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$ - */ - -#ifndef LL_LLPANELPICKS_H -#define LL_LLPANELPICKS_H - -#include "llpanel.h" -#include "v3dmath.h" -#include "lluuid.h" -#include "llavatarpropertiesprocessor.h" -#include "llpanelavatar.h" -#include "llregistry.h" - -class LLAccordionCtrlTab; -class LLPanelProfile; -class LLMessageSystem; -class LLVector3d; -class LLPanelProfileTab; -class LLAgent; -class LLMenuGL; -class LLPickItem; -class LLClassifiedItem; -class LLFlatListView; -class LLPanelPickInfo; -class LLPanelPickEdit; -class LLToggleableMenu; -class LLPanelClassifiedInfo; -class LLPanelClassifiedEdit; - -// *TODO -// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks -// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment) - -class LLPanelPicks  -	: public LLPanelProfileTab -{ -public: -	LLPanelPicks(); -	~LLPanelPicks(); - -	static void* create(void* data); - -	/*virtual*/ BOOL postBuild(void); - -	/*virtual*/ void onOpen(const LLSD& key); - -	/*virtual*/ void onClosePanel(); - -	void processProperties(void* data, EAvatarProcessorType type); - -	void updateData(); - -	// returns the selected pick item -	LLPickItem* getSelectedPickItem(); -	LLClassifiedItem* getSelectedClassifiedItem(); -	LLClassifiedItem* findClassifiedById(const LLUUID& classified_id); - -	//*NOTE top down approch when panel toggling is done only by  -	// parent panels failed to work (picks related code was in my profile panel) -	void setProfilePanel(LLPanelProfile* profile_panel); - -	void createNewPick(); -	void createNewClassified(); - -protected: -	/*virtual*/void updateButtons(); -	void updateNoItemsLabel(); - -private: -	void onClickDelete(); -	void onClickTeleport(); -	void onClickMap(); - -	void onPlusMenuItemClicked(const LLSD& param); -	bool isActionEnabled(const LLSD& userdata) const; - -	bool isClassifiedPublished(LLClassifiedItem* c_item); - -	void onListCommit(const LLFlatListView* f_list); -	void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab); - -	//------------------------------------------------ -	// Callbacks which require panel toggling -	//------------------------------------------------ -	void onClickPlusBtn(); -	void onClickInfo(); -	void onPanelPickClose(LLPanel* panel); -	void onPanelPickSave(LLPanel* panel); -	void onPanelClassifiedSave(LLPanelClassifiedEdit* panel); -	void onPanelClassifiedClose(LLPanelClassifiedInfo* panel); -	void openPickEdit(const LLSD& params); -	void onPanelPickEdit(); -	void onPanelClassifiedEdit(); -	void editClassified(const LLUUID&  classified_id); -	void onClickMenuEdit(); - -	bool onEnableMenuItem(const LLSD& user_data); - -	void openPickInfo(); -	void openClassifiedInfo(); -	void openClassifiedInfo(const LLSD& params); -	void openClassifiedEdit(const LLSD& params); -	friend class LLPanelProfile; - -	void showAccordion(const std::string& name, bool show); - -	void buildPickPanel(); - -	bool callbackDeletePick(const LLSD& notification, const LLSD& response); -	bool callbackDeleteClassified(const LLSD& notification, const LLSD& response); -	bool callbackTeleport(const LLSD& notification, const LLSD& response); - - -	virtual void onDoubleClickPickItem(LLUICtrl* item); -	virtual void onDoubleClickClassifiedItem(LLUICtrl* item); -	virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask); - -	LLPanelProfile* getProfilePanel(); - -	void createPickInfoPanel(); -	void createPickEditPanel(); -	void createClassifiedInfoPanel(); -	void createClassifiedEditPanel(LLPanelClassifiedEdit** panel); - -	LLMenuGL* mPopupMenu; -	LLPanelProfile* mProfilePanel; -	LLPanelPickInfo* mPickPanel; -	LLFlatListView* mPicksList; -	LLFlatListView* mClassifiedsList; -	LLPanelPickInfo* mPanelPickInfo; -	LLPanelClassifiedInfo* mPanelClassifiedInfo; -	LLPanelPickEdit* mPanelPickEdit; -	LLToggleableMenu* mPlusMenu; -	LLUICtrl* mNoItemsLabel; - -	// <classified_id, edit_panel> -	typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t; - -	// This map is needed for newly created classifieds. The purpose of panel is to -	// sit in this map and listen to LLPanelClassifiedEdit::processProperties callback. -	panel_classified_edit_map_t mEditClassifiedPanels; - -	LLAccordionCtrlTab* mPicksAccTab; -	LLAccordionCtrlTab* mClassifiedsAccTab; - -	//true if picks list is empty after processing picks -	bool mNoPicks; -	//true if classifieds list is empty after processing classifieds -	bool mNoClassifieds; -}; - -class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver -{ -public: - -	LLPickItem(); - -	static LLPickItem* create(); - -	void init(LLPickData* pick_data); - -	void setPickName(const std::string& name); - -	void setPickDesc(const std::string& descr); - -	void setPickId(const LLUUID& id); - -	void setCreatorId(const LLUUID& id) {mCreatorID = id;}; - -	void setSnapshotId(const LLUUID& id) {mSnapshotID = id;}; - -	void setNeedData(bool need){mNeedData = need;}; - -	const LLUUID& getPickId();  - -	const std::string& getPickName(); - -	const LLUUID& getCreatorId(); - -	const LLUUID& getSnapshotId(); - -	const LLVector3d& getPosGlobal(); - -	const std::string getDescription(); - -	const std::string& getSimName() { return mSimName; } - -	const std::string& getUserName() { return mUserName; } - -	const std::string& getOriginalName() { return mOriginalName; } - -	const std::string& getPickDesc() { return mPickDescription; } - -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - -	void update(); - -	~LLPickItem(); - -	/*virtual*/ BOOL postBuild(); - -	/** setting on/off background icon to indicate selected state */ -	/*virtual*/ void setValue(const LLSD& value); - -protected: - -	LLUUID mPickID; -	LLUUID mCreatorID; -	LLUUID mParcelID; -	LLUUID mSnapshotID; -	LLVector3d mPosGlobal; -	bool mNeedData; - -	std::string mPickName; -	std::string mUserName; -	std::string mOriginalName; -	std::string mPickDescription; -	std::string mSimName; -}; - -class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver -{ -public: - -	LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id); -	 -	virtual ~LLClassifiedItem(); - -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - -	/*virtual*/ BOOL postBuild(); - -	/*virtual*/ void setValue(const LLSD& value); - -	void fillIn(LLPanelClassifiedEdit* panel); - -	LLUUID getAvatarId() {return mAvatarId;} -	 -	void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;} - -	LLUUID getClassifiedId() {return mClassifiedId;} - -	void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;} - -	void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } - -	const LLVector3d getPosGlobal() { return mPosGlobal; } - -	void setLocationText(const std::string location) { mLocationText = location; } - -	std::string getLocationText() { return mLocationText; } - -	void setClassifiedName (const std::string& name); - -	std::string getClassifiedName() { return getChild<LLUICtrl>("name")->getValue().asString(); } - -	void setDescription(const std::string& desc); - -	std::string getDescription() { return getChild<LLUICtrl>("description")->getValue().asString(); } - -	void setSnapshotId(const LLUUID& snapshot_id); - -	LLUUID getSnapshotId(); - -	void setCategory(U32 cat) { mCategory = cat; } - -	U32 getCategory() { return mCategory; } - -	void setContentType(U32 ct) { mContentType = ct; } - -	U32 getContentType() { return mContentType; } - -	void setAutoRenew(U32 renew) { mAutoRenew = renew; } - -	bool getAutoRenew() { return mAutoRenew; } - -	void setPriceForListing(S32 price) { mPriceForListing = price; } - -	S32 getPriceForListing() { return mPriceForListing; } - -private: -	LLUUID mAvatarId; -	LLUUID mClassifiedId; -	LLVector3d mPosGlobal; -	std::string mLocationText; -	U32 mCategory; -	U32 mContentType; -	bool mAutoRenew; -	S32 mPriceForListing; -}; - -#endif // LL_LLPANELPICKS_H diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 9157df789f..fb5957ff8f 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -27,6 +27,8 @@  #include "llviewerprecompiledheaders.h"  #include "llpanelplaceinfo.h" +#include "llfloaterprofile.h" +#include "llfloaterreg.h"  #include "llavatarname.h"  #include "llsdutil.h" @@ -42,7 +44,6 @@  #include "llagent.h"  #include "llexpandabletextbox.h" -#include "llpanelpick.h"  #include "llslurl.h"  #include "lltexturectrl.h"  #include "llviewerregion.h" @@ -287,7 +288,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)  	}  } -void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel) +void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)  {  	LLPickData data;  	data.pos_global = pos_global; @@ -296,7 +297,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*  	data.desc = mDescEditor->getText();  	data.snapshot_id = mSnapshotCtrl->getImageAssetID();  	data.parcel_id = mParcelID; -	pick_panel->setPickData(&data); + +    LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID))); +    if (profile_floater) +    { +        profile_floater->createPick(data); +    }  }  // static diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 8bf67cfe7d..533215016a 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -38,7 +38,6 @@ class LLAvatarName;  class LLExpandableTextBox;  class LLIconCtrl;  class LLInventoryItem; -class LLPanelPickEdit;  class LLParcel;  class LLScrollContainer;  class LLTextBox; @@ -94,7 +93,7 @@ public:  	// Create a pick for the location specified  	// by global_pos. -	void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel); +	void createPick(const LLVector3d& pos_global);  protected:  	static void onNameCache(LLTextBox* text, const std::string& full_name); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 69f181e1b3..74ec576554 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -63,7 +63,6 @@  #include "lllayoutstack.h"  #include "llpanellandmarkinfo.h"  #include "llpanellandmarks.h" -#include "llpanelpick.h"  #include "llpanelplaceprofile.h"  #include "llpanelteleporthistory.h"  #include "llremoteparcelrequest.h" @@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces()  		mFilterEditor(NULL),  		mPlaceProfile(NULL),  		mLandmarkInfo(NULL), -		mPickPanel(NULL),  		mItem(NULL),  		mPlaceMenu(NULL),  		mLandmarkMenu(NULL), @@ -952,28 +950,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)  	}  	else if (item == "pick")  	{ -		if (mPickPanel == NULL) -		{ -			mPickPanel = LLPanelPickEdit::create(); -			addChild(mPickPanel); - -			mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); -			mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); -			mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); -		} - -		togglePickPanel(TRUE); -		mPickPanel->onOpen(LLSD()); -  		LLPanelPlaceInfo* panel = getCurrentInfoPanel();  		if (panel)  		{ -			panel->createPick(mPosGlobal, mPickPanel); +			panel->createPick(mPosGlobal);  		} - -		LLRect rect = getRect(); -		mPickPanel->reshape(rect.getWidth(), rect.getHeight()); -		mPickPanel->setRect(rect);  	}  	else if (item == "add_to_favbar")  	{ @@ -1050,17 +1031,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t      return false;  } -void LLPanelPlaces::togglePickPanel(BOOL visible) -{ -	if (mPickPanel) -	{ -		mPickPanel->setVisible(visible); -		mPlaceProfile->setVisible(!visible); -		updateVerbs(); -	} - -} -  void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  {  	if (!mPlaceProfile || !mLandmarkInfo) @@ -1309,15 +1279,11 @@ void LLPanelPlaces::updateVerbs()  	bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;  	bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE; -	bool is_pick_panel_visible = false; -	if(mPickPanel) -	{ -		is_pick_panel_visible = mPickPanel->isInVisibleChain(); -	} +  	bool have_3d_pos = ! mPosGlobal.isExactlyZero(); -	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible); -	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible); +	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); +	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);  	mSaveBtn->setVisible(isLandmarkEditModeOn);  	mCancelBtn->setVisible(isLandmarkEditModeOn);  	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 3b87eb6cb9..e554099343 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -38,7 +38,6 @@ class LLLandmark;  class LLPanelLandmarkInfo;  class LLPanelPlaceProfile; -class LLPanelPickEdit;  class LLPanelPlaceInfo;  class LLPanelPlacesTab;  class LLParcelSelection; @@ -95,7 +94,6 @@ private:  	void onOverflowButtonClicked();  	void onOverflowMenuItemClicked(const LLSD& param);  	bool onOverflowMenuItemEnable(const LLSD& param); -	void onCreateLandmarkButtonClicked(const LLUUID& folder_id);  	void onBackButtonClicked();      void onGearMenuClick();      void onSortingMenuClick(); @@ -103,9 +101,6 @@ private:      void onRemoveButtonClicked();      bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept); - -	void toggleMediaPanel(); -	void togglePickPanel(BOOL visible);  	void togglePlaceInfoPanel(BOOL visible);  	/*virtual*/ void onVisibilityChange(BOOL new_visibility); @@ -122,7 +117,6 @@ private:  	LLPanelPlaceProfile*		mPlaceProfile;  	LLPanelLandmarkInfo*		mLandmarkInfo; -	LLPanelPickEdit*			mPickPanel;  	LLToggleableMenu*			mPlaceMenu;  	LLToggleableMenu*			mLandmarkMenu; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 5f13b223fb..f4eaa78f11 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1,25 +1,25 @@ -/**  +/**  * @file llpanelprofile.cpp  * @brief Profile panel implementation  * -* $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$  */ @@ -27,32 +27,433 @@  #include "llviewerprecompiledheaders.h"  #include "llpanelprofile.h" -#include "llagent.h" +// Common +#include "llavatarnamecache.h" +#include "llsdutil.h" +#include "llslurl.h" +#include "lldateutil.h" //ageFromDate + +// UI +#include "llavatariconctrl.h" +#include "llclipboard.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llloadingindicator.h" +#include "llmenubutton.h" +#include "lltabcontainer.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lltoggleablemenu.h" +#include "llgrouplist.h" +#include "llurlaction.h" + +// Image +#include "llimagej2c.h" + +// Newview +#include "llagent.h" //gAgent +#include "llagentpicksinfo.h"  #include "llavataractions.h" -#include "llfloaterreg.h" +#include "llavatarpropertiesprocessor.h" +#include "llcallingcard.h"  #include "llcommandhandler.h" -#include "llnotificationsutil.h" -#include "llpanelpicks.h" -#include "lltabcontainer.h" -#include "llviewercontrol.h" -#include "llviewernetwork.h" +#include "llfloaterprofiletexture.h" +#include "llfloaterreg.h" +#include "llfloaterreporter.h" +#include "llfilepicker.h" +#include "llfirstuse.h" +#include "llgroupactions.h" +#include "lllogchat.h"  #include "llmutelist.h" +#include "llnotificationsutil.h"  #include "llpanelblockedlist.h" +#include "llpanelprofileclassifieds.h" +#include "llpanelprofilepicks.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewermenu.h" //is_agent_mappable +#include "llviewermenufile.h" +#include "llviewertexturelist.h" +#include "llvoiceclient.h"  #include "llweb.h" -static const std::string PANEL_PICKS = "panel_picks"; -std::string getProfileURL(const std::string& agent_name) +static LLPanelInjector<LLPanelProfileSecondLife> t_panel_profile_secondlife("panel_profile_secondlife"); +static LLPanelInjector<LLPanelProfileWeb> t_panel_web("panel_profile_web"); +static LLPanelInjector<LLPanelProfilePicks> t_panel_picks("panel_profile_picks"); +static LLPanelInjector<LLPanelProfileFirstLife> t_panel_firstlife("panel_profile_firstlife"); +static LLPanelInjector<LLPanelProfileNotes> t_panel_notes("panel_profile_notes"); +static LLPanelInjector<LLPanelProfile>          t_panel_profile("panel_profile"); + +static const std::string PANEL_SECONDLIFE   = "panel_profile_secondlife"; +static const std::string PANEL_WEB          = "panel_profile_web"; +static const std::string PANEL_PICKS        = "panel_profile_picks"; +static const std::string PANEL_CLASSIFIEDS  = "panel_profile_classifieds"; +static const std::string PANEL_FIRSTLIFE    = "panel_profile_firstlife"; +static const std::string PANEL_NOTES        = "panel_profile_notes"; +static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; + +static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile"; +static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage"; + + +////////////////////////////////////////////////////////////////////////// + +void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)  { -	std::string url = "[WEB_PROFILE_URL][AGENT_NAME]"; -	LLSD subs; -	subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL(); -	subs["AGENT_NAME"] = agent_name; -	url = LLWeb::expandURLSubstitutions(url, subs); -	LLStringUtil::toLower(url); -	return url; +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_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 + "/" + 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); + +    LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL; + +    if (!status +        || !result.has("id") +        || agent_id != result["id"].asUUID()) +    { +        LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; +        return; +    } + +    LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)); +    if (!floater_profile) +    { +        // floater is dead, so panels are dead as well +        return; +    } + +    LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE); +    LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel); +    if (!panel_profile) +    { +        LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; +        return; +    } + + +    // Avatar Data + +    LLAvatarData *avatar_data = &panel_profile->mAvatarData; +    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; + +    if (result["online"].asBoolean()) +    { +        avatar_data->flags |= AVATAR_ONLINE; +    } +    if (result["allow_publish"].asBoolean()) +    { +        avatar_data->flags |= AVATAR_ALLOW_PUBLISH; +    } +    if (result["identified"].asBoolean()) +    { +        avatar_data->flags |= AVATAR_IDENTIFIED; +    } +    if (result["transacted"].asBoolean()) +    { +        avatar_data->flags |= AVATAR_TRANSACTED; +    } + +    avatar_data->caption_index = 0; +    if (result.has("charter_member")) // won't be present if "caption" is set +    { +        avatar_data->caption_index = result["charter_member"].asInteger(); +    } +    else if (result.has("caption")) +    { +        avatar_data->caption_text = result["caption"].asString(); +    } + +    panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE); +    LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel); +    if (panel_sl) +    { +        panel_sl->processProfileProperties(avatar_data); +    } + +    panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE); +    LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel); +    if (panel_web) +    { +        panel_web->setLoaded(); +    } + +    panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE); +    LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel); +    if (panel_first) +    { +        panel_first->processProperties(avatar_data); +    } + +    // 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()); +    } + +    panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE); +    LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel); +    if (panel_picks) +    { +        // Refresh pick limit before processing +        LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks); +        panel_picks->processProperties(&avatar_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); +    } + +    if (panel_sl) +    { +        panel_sl->processGroupProperties(&avatar_groups); +    } + +    // Notes +    LLAvatarNotes avatar_notes; + +    avatar_notes.agent_id = agent_id; +    avatar_notes.target_id = agent_id; +    avatar_notes.notes = result["notes"].asString(); + +    panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE); +    LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel); +    if (panel_notes) +    { +        panel_notes->processProperties(&avatar_notes); +    } +} + +//TODO: changes take two minutes to propagate! +// Add some storage that holds updated data for two minutes +// for new instances to reuse the data +// Profile data is only relevant to won avatar, but notes +// are for everybody +void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) +{ +    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 + "/" + agent_id.asString(); + +    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("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; +        return; +    } + +    LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; +} + +LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_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); +     +    LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    if (!status) +    { +        // todo: notification? +        LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; +        return LLUUID::null; +    } +    if (!result.has("uploader")) +    { +        // todo: notification? +        LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; +        return LLUUID::null; +    } +    std::string uploader_cap = result["uploader"].asString(); +    if (uploader_cap.empty()) +    { +        LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; +        return LLUUID::null; +    } + +    // Upload the image + +    LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); +    LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); +    LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); +    S64 length; + +    { +        llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); +        if (!instream.is_open()) +        { +            LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; +            return LLUUID::null; +        } +        length = instream.tellg(); +    } + +    uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional +    uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! +    uploaderhttpOpts->setFollowRedirects(true); + +    result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); + +    httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    LL_WARNS("AvatarProperties") << result << LL_ENDL; + +    if (!status) +    { +        LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; +        return LLUUID::null; +    } + +    if (result["state"].asString() != "complete") +    { +        if (result.has("message")) +        { +            LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; +        } +        else +        { +            LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; +        } +        return LLUUID::null; +    } + +    return result["new_asset"].asUUID();  } +enum EProfileImageType +{ +    PROFILE_IMAGE_SL, +    PROFILE_IMAGE_FL, +}; + +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle) +{ +    LLSD data; +    switch (type) +    { +    case PROFILE_IMAGE_SL: +        data["profile-image-asset"] = "sl_image_id"; +        break; +    case PROFILE_IMAGE_FL: +        data["profile-image-asset"] = "fl_image_id"; +        break; +    } + +    LLUUID result = post_profile_image(cap_url, data, path_to_image, handle); + +    // reset loading indicator +    if (!handle->isDead()) +    { +        switch (type) +        { +        case PROFILE_IMAGE_SL: +            { +                LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); +                if (result.notNull()) +                { +                    panel->setProfileImageUploaded(result); +                } +                else +                { +                    // failure, just stop progress indicator +                    panel->setProfileImageUploading(false); +                } +                break; +            } +        case PROFILE_IMAGE_FL: +            { +                LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get()); +                if (result.notNull()) +                { +                    panel->setProfileImageUploaded(result); +                } +                else +                { +                    // failure, just stop progress indicator +                    panel->setProfileImageUploading(false); +                } +                break; +            } +        } +    } + +    // Cleanup +    LLFile::remove(path_to_image); +    delete handle; +} + +////////////////////////////////////////////////////////////////////////// +// LLProfileHandler +  class LLProfileHandler : public LLCommandHandler  {  public: @@ -73,6 +474,10 @@ public:  };  LLProfileHandler gProfileHandler; + +////////////////////////////////////////////////////////////////////////// +// LLAgentHandler +  class LLAgentHandler : public LLCommandHandler  {  public: @@ -178,279 +583,2070 @@ public:  			}  			return true;  		} + +        // reportAbuse is here due to convoluted avatar handling +        // in LLScrollListCtrl and LLTextBase +        if (verb == "reportAbuse" && web == NULL)  +        { +            LLAvatarName av_name; +            if (LLAvatarNameCache::get(avatar_id, &av_name)) +            { +                LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName()); +            } +            else +            { +                LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable"); +            } +            return true; +        }  		return false;  	}  };  LLAgentHandler gAgentHandler; -//-- LLPanelProfile::ChildStack begins ---------------------------------------- -LLPanelProfile::ChildStack::ChildStack() -:	mParent(NULL) +///---------------------------------------------------------------------------- +/// LLFloaterProfilePermissions +///---------------------------------------------------------------------------- + +class LLFloaterProfilePermissions +    : public LLFloater +    , public LLFriendObserver  { +public: +    LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id); +    ~LLFloaterProfilePermissions(); +    BOOL postBuild() override; +    void onOpen(const LLSD& key) override; +    void draw() override; +    void changed(U32 mask) override; // LLFriendObserver + +    void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); +    bool hasUnsavedChanges() { return mHasUnsavedPermChanges; } + +    void onApplyRights(); + +private: +    void fillRightsData(); +    void rightsConfirmationCallback(const LLSD& notification, const LLSD& response); +    void confirmModifyRights(bool grant); +    void onCommitSeeOnlineRights(); +    void onCommitEditRights(); +    void onCancel(); + +    LLTextBase*         mDescription; +    LLCheckBoxCtrl*     mOnlineStatus; +    LLCheckBoxCtrl*     mMapRights; +    LLCheckBoxCtrl*     mEditObjectRights; +    LLButton*           mOkBtn; +    LLButton*           mCancelBtn; + +    LLUUID              mAvatarID; +    F32                 mContextConeOpacity; +    bool                mHasUnsavedPermChanges; +    LLHandle<LLView>    mOwnerHandle; + +    boost::signals2::connection	mAvatarNameCacheConnection; +}; + +LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id) +    : LLFloater(LLSD()) +    , mAvatarID(avatar_id) +    , mContextConeOpacity(0.0f) +    , mHasUnsavedPermChanges(false) +    , mOwnerHandle(owner->getHandle()) +{ +    buildFromFile("floater_profile_permissions.xml");  } -LLPanelProfile::ChildStack::~ChildStack() +LLFloaterProfilePermissions::~LLFloaterProfilePermissions()  { -	while (mStack.size() != 0) -	{ -		view_list_t& top = mStack.back(); -		for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) -		{ -			LLView* viewp = *it; -			if (viewp) -			{ -				viewp->die(); -			} -		} -		mStack.pop_back(); -	} +    mAvatarNameCacheConnection.disconnect(); +    if (mAvatarID.notNull()) +    { +        LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); +    }  } -void LLPanelProfile::ChildStack::setParent(LLPanel* parent) +BOOL LLFloaterProfilePermissions::postBuild()  { -	llassert_always(parent != NULL); -	mParent = parent; +    mDescription = getChild<LLTextBase>("perm_description"); +    mOnlineStatus = getChild<LLCheckBoxCtrl>("online_check"); +    mMapRights = getChild<LLCheckBoxCtrl>("map_check"); +    mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check"); +    mOkBtn = getChild<LLButton>("perms_btn_ok"); +    mCancelBtn = getChild<LLButton>("perms_btn_cancel"); + +    mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr); +    mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr); +    mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr); +    mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr); +    mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr); + +    return TRUE;  } -/// Save current parent's child views and remove them from the child list. -bool LLPanelProfile::ChildStack::push() +void LLFloaterProfilePermissions::onOpen(const LLSD& key)  { -	view_list_t vlist = *mParent->getChildList(); +    if (LLAvatarActions::isFriend(mAvatarID)) +    { +        LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this); +        fillRightsData(); +    } -	for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it) -	{ -		LLView* viewp = *it; -		mParent->removeChild(viewp); -	} +    mCancelBtn->setFocus(true); -	mStack.push_back(vlist); -	dump(); -	return true; +    mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2));  } -/// Restore saved children (adding them back to the child list). -bool LLPanelProfile::ChildStack::pop() +void LLFloaterProfilePermissions::draw()  { -	if (mStack.size() == 0) -	{ -		LL_WARNS() << "Empty stack" << LL_ENDL; -		llassert(mStack.size() == 0); -		return false; -	} +    // drawFrustum +    LLView *owner = mOwnerHandle.get(); +    static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); +    drawConeToOwner(mContextConeOpacity, max_opacity, owner); +    LLFloater::draw(); +} -	view_list_t& top = mStack.back(); -	for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) -	{ -		LLView* viewp = *it; -		mParent->addChild(viewp); -	} +void LLFloaterProfilePermissions::changed(U32 mask) +{ +    if (mask != LLFriendObserver::ONLINE) +    { +        fillRightsData(); +    } +} -	mStack.pop_back(); -	dump(); -	return true; +void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ +    mAvatarNameCacheConnection.disconnect(); + +    LLStringUtil::format_map_t args; +    args["[AGENT_NAME]"] = av_name.getDisplayName(); +    std::string descritpion = getString("description_string", args); +    mDescription->setValue(descritpion);  } -/// Temporarily add all saved children back. -void LLPanelProfile::ChildStack::preParentReshape() +void LLFloaterProfilePermissions::fillRightsData()  { -	mSavedStack = mStack; -	while(mStack.size() > 0) -	{ -		pop(); -	} +    const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); +    // If true - we are viewing friend's profile, enable check boxes and set values. +    if (relation) +    { +        S32 rights = relation->getRightsGrantedTo(); + +        BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE; +        mOnlineStatus->setValue(see_online); +        mMapRights->setEnabled(see_online); +        mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); +        mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); +    } +    else +    { +        closeFloater(); +        LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL; +    }  } -/// Add the temporarily saved children back. -void LLPanelProfile::ChildStack::postParentReshape() +void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification, +    const LLSD& response)  { -	mStack = mSavedStack; -	mSavedStack = stack_t(); +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    if (option != 0) // canceled +    { +        mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); +    } +    else +    { +        mHasUnsavedPermChanges = true; +    } +} -	for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it) -	{ -		const view_list_t& vlist = (*stack_it); -		for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) -		{ -			LLView* viewp = *list_it; -			LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL; -			mParent->removeChild(viewp); -		} -	} +void LLFloaterProfilePermissions::confirmModifyRights(bool grant) +{ +    LLSD args; +    args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString(); +    LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(), +        boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2));  } -void LLPanelProfile::ChildStack::dump() +void LLFloaterProfilePermissions::onCommitSeeOnlineRights()  { -	unsigned lvl = 0; -	LL_DEBUGS() << "child stack dump:" << LL_ENDL; -	for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl) -	{ -		std::ostringstream dbg_line; -		dbg_line << "lvl #" << lvl << ":"; -		const view_list_t& vlist = (*stack_it); -		for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) -		{ -			dbg_line << " " << (*list_it)->getName(); -		} -		LL_DEBUGS() << dbg_line.str() << LL_ENDL; -	} +    bool see_online = mOnlineStatus->getValue().asBoolean(); +    mMapRights->setEnabled(see_online); +    if (see_online) +    { +        const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); +        if (relation) +        { +            S32 rights = relation->getRightsGrantedTo(); +            mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); +        } +        else +        { +            closeFloater(); +            LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL; +        } +    } +    else +    { +        mMapRights->setValue(FALSE); +    } +    mHasUnsavedPermChanges = true;  } -//-- LLPanelProfile::ChildStack ends ------------------------------------------ +void LLFloaterProfilePermissions::onCommitEditRights() +{ +    const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); -LLPanelProfile::LLPanelProfile() - : LLPanel() - , mAvatarId(LLUUID::null) +    if (!buddy_relationship) +    { +        LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL; +        closeFloater(); +        return; +    } + +    bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); + +    // if modify objects checkbox clicked +    if (buddy_relationship->isRightGrantedTo( +        LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) +    { +        confirmModifyRights(allow_modify_objects); +    } +} + +void LLFloaterProfilePermissions::onApplyRights() +{ +    const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + +    if (!buddy_relationship) +    { +        LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; +        return; +    } + +    S32 rights = 0; + +    if (mOnlineStatus->getValue().asBoolean()) +    { +        rights |= LLRelationship::GRANT_ONLINE_STATUS; +    } +    if (mMapRights->getValue().asBoolean()) +    { +        rights |= LLRelationship::GRANT_MAP_LOCATION; +    } +    if (mEditObjectRights->getValue().asBoolean()) +    { +        rights |= LLRelationship::GRANT_MODIFY_OBJECTS; +    } + +    LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights); + +    closeFloater(); +} + +void LLFloaterProfilePermissions::onCancel()  { -	mChildStack.setParent(this); +    closeFloater();  } -BOOL LLPanelProfile::postBuild() +////////////////////////////////////////////////////////////////////////// +// LLPanelProfileSecondLife + +LLPanelProfileSecondLife::LLPanelProfileSecondLife() +    : LLPanelProfileTab() +    , mAvatarNameCacheConnection() +    , mHasUnsavedDescriptionChanges(false) +    , mWaitingForImageUpload(false) +    , mAllowPublish(false) +{ +} + +LLPanelProfileSecondLife::~LLPanelProfileSecondLife() +{ +    if (getAvatarId().notNull()) +    { +        LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); +    } + +    if (LLVoiceClient::instanceExists()) +    { +        LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); +    } + +    if (mAvatarNameCacheConnection.connected()) +    { +        mAvatarNameCacheConnection.disconnect(); +    } +} + +BOOL LLPanelProfileSecondLife::postBuild() +{ +    mGroupList              = getChild<LLGroupList>("group_list"); +    mShowInSearchCombo      = getChild<LLComboBox>("show_in_search"); +    mSecondLifePic          = getChild<LLIconCtrl>("2nd_life_pic"); +    mSecondLifePicLayout    = getChild<LLPanel>("image_panel"); +    mDescriptionEdit        = getChild<LLTextEditor>("sl_description_edit"); +    mAgentActionMenuButton  = getChild<LLMenuButton>("agent_actions_menu"); +    mSaveDescriptionChanges = getChild<LLButton>("save_description_changes"); +    mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes"); +    mCanSeeOnlineIcon       = getChild<LLIconCtrl>("can_see_online"); +    mCantSeeOnlineIcon      = getChild<LLIconCtrl>("cant_see_online"); +    mCanSeeOnMapIcon        = getChild<LLIconCtrl>("can_see_on_map"); +    mCantSeeOnMapIcon       = getChild<LLIconCtrl>("cant_see_on_map"); +    mCanEditObjectsIcon     = getChild<LLIconCtrl>("can_edit_objects"); +    mCantEditObjectsIcon    = getChild<LLIconCtrl>("cant_edit_objects"); + +    mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr); +    mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); +    mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); +    mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); +    mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); +    mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); + +    mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); +    mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); +    mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); +    mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); +    mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); +    mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); +    mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); }); + +    return TRUE; +} + +void LLPanelProfileSecondLife::onOpen(const LLSD& key) +{ +    LLPanelProfileTab::onOpen(key); + +    resetData(); + +    LLUUID avatar_id = getAvatarId(); + +    BOOL own_profile = getSelfProfile(); + +    mGroupList->setShowNone(!own_profile); + +    childSetVisible("notes_panel", !own_profile); +    childSetVisible("settings_panel", own_profile); +    childSetVisible("about_buttons_panel", own_profile); + +    if (own_profile) +    { +        // Group list control cannot toggle ForAgent loading +        // Less than ideal, but viewing own profile via search is edge case +        mGroupList->enableForAgent(false); +    } + +    // Init menu, menu needs to be created in scope of a registar to work correctly. +    LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; +    commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); + +    LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; +    enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); }); +    enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); }); + +    if (own_profile) +    { +        mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT); +    } +    else +    { +        // Todo: use PeopleContextMenu instead? +        mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); +    } + +    mDescriptionEdit->setParseHTML(!own_profile); + +    if (!own_profile) +    { +        mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE); +        updateOnlineStatus(); +        fillRightsData(); +    } + +    mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); +} + +void LLPanelProfileSecondLife::updateData() +{ +    LLUUID avatar_id = getAvatarId(); +    if (!getStarted() && avatar_id.notNull()) +    { +        setIsLoading(); + +        std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +        if (!cap_url.empty()) +        { +            LLCoros::instance().launch("requestAgentUserInfoCoro", +                boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); +        } +        else +        { +            LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; +        } +    } +} + +void LLPanelProfileSecondLife::refreshName() +{ +    if (!mAvatarNameCacheConnection.connected()) +    { +        mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); +    } +} + +void LLPanelProfileSecondLife::resetData() +{ +    resetLoading(); + +    // Set default image and 1:1 dimensions for it +    mSecondLifePic->setValue("Generic_Person_Large"); +    mImageId = LLUUID::null; + +    LLRect imageRect = mSecondLifePicLayout->getRect(); +    mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); + +    setDescriptionText(LLStringUtil::null); +    mGroups.clear(); +    mGroupList->setGroups(mGroups); + +    bool own_profile = getSelfProfile(); +    mCanSeeOnlineIcon->setVisible(false); +    mCantSeeOnlineIcon->setVisible(!own_profile); +    mCanSeeOnMapIcon->setVisible(false); +    mCantSeeOnMapIcon->setVisible(!own_profile); +    mCanEditObjectsIcon->setVisible(false); +    mCantEditObjectsIcon->setVisible(!own_profile); + +    mCanSeeOnlineIcon->setEnabled(false); +    mCantSeeOnlineIcon->setEnabled(false); +    mCanSeeOnMapIcon->setEnabled(false); +    mCantSeeOnMapIcon->setEnabled(false); +    mCanEditObjectsIcon->setEnabled(false); +    mCantEditObjectsIcon->setEnabled(false); + +    childSetVisible("partner_layout", FALSE); +} + +void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) +{ +    LLUUID avatar_id = getAvatarId(); +    const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); +    if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile()) +    { +        // Relies onto friend observer to get information about online status updates. +        // Once SL-17506 gets implemented, condition might need to become: +        // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE) +        processOnlineStatus(relationship != NULL, +                            gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS), +                            (avatar_data->flags & AVATAR_ONLINE)); +    } + +    fillCommonData(avatar_data); + +    fillPartnerData(avatar_data); + +    fillAccountStatus(avatar_data); + +    setLoaded(); +} + +void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups) +{ + +    LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); +    const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); + +    for (; it_end != it; ++it) +    { +        LLAvatarGroups::LLGroupData group_data = *it; +        mGroups[group_data.group_name] = group_data.group_id; +    } + +    mGroupList->setGroups(mGroups); +} + +void LLPanelProfileSecondLife::openGroupProfile() +{ +    LLUUID group_id = mGroupList->getSelectedUUID(); +    LLGroupActions::show(group_id); +} + +void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ +    mAvatarNameCacheConnection.disconnect(); +    getChild<LLUICtrl>("display_name")->setValue(av_name.getDisplayName()); +    getChild<LLUICtrl>("user_name")->setValue(av_name.getAccountName()); +} + +void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) +{ +    LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator"); +    indicator->setVisible(loading); +    if (loading) +    { +        indicator->start(); +    } +    else +    { +        indicator->stop(); +    } +    mWaitingForImageUpload = loading; +} + +void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id) +{ +    mSecondLifePic->setValue(image_asset_id); +    mImageId = image_asset_id; + +    LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id); +    if (imagep->getFullHeight()) +    { +        onImageLoaded(true, imagep); +    } +    else +    { +        imagep->setLoadedCallback(onImageLoaded, +            MAX_DISCARD_LEVEL, +            FALSE, +            FALSE, +            new LLHandle<LLPanel>(getHandle()), +            NULL, +            FALSE); +    } + +    LLFloater *floater = mFloaterProfileTextureHandle.get(); +    if (floater) +    { +        LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); +        if (mImageId.notNull()) +        { +            texture_view->loadAsset(mImageId); +        } +        else +        { +            texture_view->resetAsset(); +        } +    } + +    setProfileImageUploading(false); +} + +bool LLPanelProfileSecondLife::hasUnsavedChanges() +{ +    LLFloater *floater = mFloaterPermissionsHandle.get(); +    if (floater) +    { +        LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater); +        if (perm && perm->hasUnsavedChanges()) +        { +            return true; +        } +    } +    // if floater +    return mHasUnsavedDescriptionChanges; +} + +void LLPanelProfileSecondLife::commitUnsavedChanges() +{ +    LLFloater *floater = mFloaterPermissionsHandle.get(); +    if (floater) +    { +        LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater); +        if (perm && perm->hasUnsavedChanges()) +        { +            perm->onApplyRights(); +        } +    } +    if (mHasUnsavedDescriptionChanges) +    { +        onSaveDescriptionChanges(); +    } +} + +void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) +{ +    // Refresh avatar id in cache with new info to prevent re-requests +    // and to make sure icons in text will be up to date +    LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); + +    fillAgeData(avatar_data->born_on); + +    setDescriptionText(avatar_data->about_text); + +    if (avatar_data->image_id.notNull()) +    { +        mSecondLifePic->setValue(avatar_data->image_id); +        mImageId = avatar_data->image_id; +    } +    else +    { +        mSecondLifePic->setValue("Generic_Person_Large"); +        mImageId = LLUUID::null; +    } + +    // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic +    LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); +    if (imagep->getFullHeight()) +    { +        onImageLoaded(true, imagep); +    } +    else +    { +        imagep->setLoadedCallback(onImageLoaded, +                                  MAX_DISCARD_LEVEL, +                                  FALSE, +                                  FALSE, +                                  new LLHandle<LLPanel>(getHandle()), +                                  NULL, +                                  FALSE); +    } + +    if (getSelfProfile()) +    { +        mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH; +        mShowInSearchCombo->setValue((BOOL)mAllowPublish); +    } +} + +void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) +{ +    LLTextBox* partner_text_ctrl = getChild<LLTextBox>("partner_link"); +    if (avatar_data->partner_id.notNull()) +    { +        childSetVisible("partner_layout", TRUE); +        LLStringUtil::format_map_t args; +        args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); +        std::string partner_text = getString("partner_text", args); +        partner_text_ctrl->setText(partner_text); +    } +    else +    { +        childSetVisible("partner_layout", FALSE); +    } +} + +void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data) +{ +    LLStringUtil::format_map_t args; +    args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data); +    args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); + +    std::string caption_text = getString("CaptionTextAcctInfo", args); +    getChild<LLUICtrl>("account_info")->setValue(caption_text); +} + +void LLPanelProfileSecondLife::fillRightsData() +{ +    if (getSelfProfile()) +    { +        return; +    } + +    const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); +    // If true - we are viewing friend's profile, enable check boxes and set values. +    if (relation) +    { +        S32 rights = relation->getRightsGrantedTo(); +        bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights; +        bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights; +        bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights; + +        mCanSeeOnlineIcon->setVisible(can_see_online); +        mCantSeeOnlineIcon->setVisible(!can_see_online); +        mCanSeeOnMapIcon->setVisible(can_see_on_map); +        mCantSeeOnMapIcon->setVisible(!can_see_on_map); +        mCanEditObjectsIcon->setVisible(can_edit_objects); +        mCantEditObjectsIcon->setVisible(!can_edit_objects); + +        mCanSeeOnlineIcon->setEnabled(true); +        mCantSeeOnlineIcon->setEnabled(true); +        mCanSeeOnMapIcon->setEnabled(true); +        mCantSeeOnMapIcon->setEnabled(true); +        mCanEditObjectsIcon->setEnabled(true); +        mCantEditObjectsIcon->setEnabled(true); +    } +    else +    { +        mCanSeeOnlineIcon->setVisible(false); +        mCantSeeOnlineIcon->setVisible(false); +        mCanSeeOnMapIcon->setVisible(false); +        mCantSeeOnMapIcon->setVisible(false); +        mCanEditObjectsIcon->setVisible(false); +        mCantEditObjectsIcon->setVisible(false); +    } +} + +void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) +{ +    std::string name_and_date = getString("date_format"); +    LLSD args_name; +    args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); +    LLStringUtil::format(name_and_date, args_name); +    getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date); + +    std::string register_date = getString("age_format"); +    LLSD args_age; +    args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); +    LLStringUtil::format(register_date, args_age); +    getChild<LLUICtrl>("user_age")->setValue(register_date); +} + +void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) +{ +    LLRect imageRect = mSecondLifePicLayout->getRect(); +    if (!success || imagep->getFullWidth() == imagep->getFullHeight()) +    { +        mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth()); +    } +    else +    { +        // assume 3:4, for sake of firestorm +        mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4); +    } +} + +//static +void LLPanelProfileSecondLife::onImageLoaded(BOOL success, +                                             LLViewerFetchedTexture *src_vi, +                                             LLImageRaw* src, +                                             LLImageRaw* aux_src, +                                             S32 discard_level, +                                             BOOL final, +                                             void* userdata) +{ +    if (!userdata) return; + +    LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata; + +    if (!handle->isDead()) +    { +        LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); +        if (panel) +        { +            panel->onImageLoaded(success, src_vi); +        } +    } + +    if (final || !success) +    { +        delete handle; +    } +} + +// virtual, called by LLAvatarTracker +void LLPanelProfileSecondLife::changed(U32 mask) +{ +    updateOnlineStatus(); +    if (mask != LLFriendObserver::ONLINE) +    { +        fillRightsData(); +    } +} + +// virtual, called by LLVoiceClient +void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ +    if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) +    { +        return; +    } + +    mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE); +} + +void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) +{ +    if (avatar_id.notNull()) +    { +        if (getAvatarId().notNull()) +        { +            LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); +        } + +        LLPanelProfileTab::setAvatarId(avatar_id); + +        if (LLAvatarActions::isFriend(getAvatarId())) +        { +            LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); +        } +    } +} + +// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880 +void LLPanelProfileSecondLife::updateOnlineStatus() +{ +    const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); +    if (relationship != NULL) +    { +        // For friend let check if he allowed me to see his status +        bool online = relationship->isOnline(); +        bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); +        processOnlineStatus(true, perm_granted, online); +    } +    else +    { +        childSetVisible("frind_layout", false); +        childSetVisible("online_layout", false); +        childSetVisible("offline_layout", false); +    } +} + +void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online) +{ +    childSetVisible("frind_layout", is_friend); +    childSetVisible("online_layout", online && show_online); +    childSetVisible("offline_layout", !online && show_online); +} + +void LLPanelProfileSecondLife::setLoaded() +{ +    LLPanelProfileTab::setLoaded(); + +    if (getSelfProfile()) +    { +        mShowInSearchCombo->setEnabled(TRUE); +        mDescriptionEdit->setEnabled(TRUE); +    } +} + + + +class LLProfileImagePicker : public LLFilePickerThread +{ +public: +    LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle); +    ~LLProfileImagePicker(); +    void notify(const std::vector<std::string>& filenames) override; + +private: +    LLHandle<LLPanel> *mHandle; +    EProfileImageType mType; +}; + +LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle) +    : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), +    mHandle(handle), +    mType(type) +{ +} + +LLProfileImagePicker::~LLProfileImagePicker() +{ +    delete mHandle; +} + +void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) +{ +    if (mHandle->isDead()) +    { +        return; +    } +    if (filenames.empty()) +    { +        return; +    } +    std::string file_path = filenames[0]; +    if (file_path.empty()) +    { +        return; +    } + +    // generate a temp texture file for coroutine +    std::string temp_file = gDirUtilp->getTempFilename(); +    U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); +    const S32 MAX_DIM = 256; +    if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) +    { +        //todo: image not supported notification +        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; +        return; +    } + +    std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); +    if (cap_url.empty()) +    { +        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; +        return; +    } + +    switch (mType) +    { +    case PROFILE_IMAGE_SL: +        { +            LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get()); +            panel->setProfileImageUploading(true); +        } +        break; +    case PROFILE_IMAGE_FL: +        { +            LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get()); +            panel->setProfileImageUploading(true); +        } +        break; +    } + +    LLCoros::instance().launch("postAgentUserImageCoro", +        boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle)); + +    mHandle = nullptr; // transferred to post_profile_image_coro +} + +void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) +{ +    const std::string item_name = userdata.asString(); +    const LLUUID agent_id = getAvatarId(); +    // todo: consider moving this into LLAvatarActions::onCommit(name, id) +    // and making all other flaoters, like people menu do the same +    if (item_name == "im") +    { +        LLAvatarActions::startIM(agent_id); +    } +    else if (item_name == "offer_teleport") +    { +        LLAvatarActions::offerTeleport(agent_id); +    } +    else if (item_name == "request_teleport") +    { +        LLAvatarActions::teleportRequest(agent_id); +    } +    else if (item_name == "voice_call") +    { +        LLAvatarActions::startCall(agent_id); +    } +    else if (item_name == "chat_history") +    { +        LLAvatarActions::viewChatHistory(agent_id); +    } +    else if (item_name == "add_friend") +    { +        LLAvatarActions::requestFriendshipDialog(agent_id); +    } +    else if (item_name == "remove_friend") +    { +        LLAvatarActions::removeFriendDialog(agent_id); +    } +    else if (item_name == "invite_to_group") +    { +        LLAvatarActions::inviteToGroup(agent_id); +    } +    else if (item_name == "can_show_on_map") +    { +        LLAvatarActions::showOnMap(agent_id); +    } +    else if (item_name == "share") +    { +        LLAvatarActions::share(agent_id); +    } +    else if (item_name == "pay") +    { +        LLAvatarActions::pay(agent_id); +    } +    else if (item_name == "toggle_block_agent") +    { +        LLAvatarActions::toggleBlock(agent_id); +    } +    else if (item_name == "copy_user_id") +    { +        LLWString wstr = utf8str_to_wstring(getAvatarId().asString()); +        LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); +    } +    else if (item_name == "agent_permissions") +    { +        onShowAgentPermissionsDialog(); +    } +    else if (item_name == "copy_display_name" +        || item_name == "copy_username") +    { +        LLAvatarName av_name; +        if (!LLAvatarNameCache::get(getAvatarId(), &av_name)) +        { +            // shouldn't happen, option is supposed to be invisible while name is fetching +            LL_WARNS() << "Failed to get agent data" << LL_ENDL; +            return; +        } +        LLWString wstr; +        if (item_name == "copy_display_name") +        { +            wstr = utf8str_to_wstring(av_name.getDisplayName(true)); +        } +        else if (item_name == "copy_username") +        { +            wstr = utf8str_to_wstring(av_name.getUserName()); +        } +        LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); +    } +    else if (item_name == "edit_display_name") +    { +        LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); +        LLFirstUse::setDisplayName(false); +    } +    else if (item_name == "edit_partner") +    { +        std::string url = "https://[GRID]/my/account/partners.php"; +        LLSD subs; +        url = LLWeb::expandURLSubstitutions(url, subs); +        LLUrlAction::openURL(url); +    } +    else if (item_name == "upload_photo") +    { +        (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile(); + +        LLFloater* floaterp = mFloaterTexturePickerHandle.get(); +        if (floaterp) +        { +            floaterp->closeFloater(); +        } +    } +    else if (item_name == "change_photo") +    { +        onShowTexturePicker(); +    } +    else if (item_name == "remove_photo") +    { +        onCommitProfileImage(LLUUID::null); + +        LLFloater* floaterp = mFloaterTexturePickerHandle.get(); +        if (floaterp) +        { +            floaterp->closeFloater(); +        } +    } +} + +bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) +{ +    const std::string item_name = userdata.asString(); +    const LLUUID agent_id = getAvatarId(); +    if (item_name == "offer_teleport" || item_name == "request_teleport") +    { +        return LLAvatarActions::canOfferTeleport(agent_id); +    } +    else if (item_name == "voice_call") +    { +        return mVoiceStatus; +    } +    else if (item_name == "chat_history") +    { +        return LLLogChat::isTranscriptExist(agent_id); +    } +    else if (item_name == "add_friend") +    { +        return !LLAvatarActions::isFriend(agent_id); +    } +    else if (item_name == "remove_friend") +    { +        return LLAvatarActions::isFriend(agent_id); +    } +    else if (item_name == "can_show_on_map") +    { +        return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && is_agent_mappable(agent_id)) +        || gAgent.isGodlike(); +    } +    else if (item_name == "toggle_block_agent") +    { +        return LLAvatarActions::canBlock(agent_id); +    } +    else if (item_name == "agent_permissions") +    { +        return LLAvatarActions::isFriend(agent_id); +    } +    else if (item_name == "copy_display_name" +        || item_name == "copy_username") +    { +        return !mAvatarNameCacheConnection.connected(); +    } +    else if (item_name == "upload_photo" +        || item_name == "change_photo") +    { +        std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); +        return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); +    } +    else if (item_name == "remove_photo") +    { +        std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +        return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); +    } + +    return false; +} + +bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata) +{ +    const std::string item_name = userdata.asString(); +    const LLUUID agent_id = getAvatarId(); +    if (item_name == "toggle_block_agent") +    { +        return LLAvatarActions::isBlocked(agent_id); +    } +    return false; +} + +void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name)  { -	LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS); -	panel_picks->setProfilePanel(this); +    if (av_name.getDisplayName().empty()) +    { +        // something is wrong, tell user to try again later +        LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); +        return; +    } -	getTabContainer()[PANEL_PICKS] = panel_picks; +    LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update " +        << LLDate(av_name.mNextUpdate) << LL_ENDL; +    F64 now_secs = LLDate::now().secondsSinceEpoch(); -	return TRUE; +    if (now_secs < av_name.mNextUpdate) +    { +        // if the update time is more than a year in the future, it means updates have been blocked +        // show a more general message +        static const S32 YEAR = 60*60*24*365; +        if (now_secs + YEAR < av_name.mNextUpdate) +        { +            LLNotificationsUtil::add("SetDisplayNameBlocked"); +            return; +        } +    } + +    LLFloaterReg::showInstance("display_name"); +} + +void LLPanelProfileSecondLife::setDescriptionText(const std::string &text) +{ +    mSaveDescriptionChanges->setEnabled(FALSE); +    mDiscardDescriptionChanges->setEnabled(FALSE); +    mHasUnsavedDescriptionChanges = false; + +    mDescriptionText = text; +    mDescriptionEdit->setValue(mDescriptionText);  } -// virtual -void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent) +void LLPanelProfileSecondLife::onSetDescriptionDirty()  { -	// Temporarily add saved children back and reshape them. -	mChildStack.preParentReshape(); -	LLPanel::reshape(width, height, called_from_parent); -	mChildStack.postParentReshape(); +    mSaveDescriptionChanges->setEnabled(TRUE); +    mDiscardDescriptionChanges->setEnabled(TRUE); +    mHasUnsavedDescriptionChanges = true; +} + +void LLPanelProfileSecondLife::onShowInSearchCallback() +{ +    S32 value = mShowInSearchCombo->getValue().asInteger(); +    if (mAllowPublish == (bool)value) +    { +        return; +    } +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        mAllowPublish = value; +        LLSD data; +        data["allow_publish"] = mAllowPublish; +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data)); +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } +} + +void LLPanelProfileSecondLife::onSaveDescriptionChanges() +{ +    mDescriptionText = mDescriptionEdit->getValue().asString(); +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText))); +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } + +    mSaveDescriptionChanges->setEnabled(FALSE); +    mDiscardDescriptionChanges->setEnabled(FALSE); +    mHasUnsavedDescriptionChanges = false; +} + +void LLPanelProfileSecondLife::onDiscardDescriptionChanges() +{ +    setDescriptionText(mDescriptionText); +} + +void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() +{ +    LLFloater *floater = mFloaterPermissionsHandle.get(); +    if (!floater) +    { +        LLFloater* parent_floater = gFloaterView->getParentFloater(this); +        if (parent_floater) +        { +            LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId()); +            mFloaterPermissionsHandle = perms->getHandle(); +            perms->openFloater(); +            perms->setVisibleAndFrontmost(TRUE); + +            parent_floater->addDependentFloater(mFloaterPermissionsHandle); +        } +    } +    else // already open +    { +        floater->setMinimized(FALSE); +        floater->setVisibleAndFrontmost(TRUE); +    } +} + +void LLPanelProfileSecondLife::onShowAgentProfileTexture() +{ +    if (!getIsLoaded()) +    { +        return; +    } + +    LLFloater *floater = mFloaterProfileTextureHandle.get(); +    if (!floater) +    { +        LLFloater* parent_floater = gFloaterView->getParentFloater(this); +        if (parent_floater) +        { +            LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater); +            mFloaterProfileTextureHandle = texture_view->getHandle(); +            if (mImageId.notNull()) +            { +                texture_view->loadAsset(mImageId); +            } +            else +            { +                texture_view->resetAsset(); +            } +            texture_view->openFloater(); +            texture_view->setVisibleAndFrontmost(TRUE); + +            parent_floater->addDependentFloater(mFloaterProfileTextureHandle); +        } +    } +    else // already open +    { +        LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); +        texture_view->setMinimized(FALSE); +        texture_view->setVisibleAndFrontmost(TRUE); +        if (mImageId.notNull()) +        { +            texture_view->loadAsset(mImageId); +        } +        else +        { +            texture_view->resetAsset(); +        } +    } +} + +void LLPanelProfileSecondLife::onShowTexturePicker() +{ +    LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + +    // Show the dialog +    if (!floaterp) +    { +        LLFloater* parent_floater = gFloaterView->getParentFloater(this); +        if (parent_floater) +        { +            // because inventory construction is somewhat slow +            getWindow()->setCursor(UI_CURSOR_WAIT); +            LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( +                this, +                mImageId, +                LLUUID::null, +                mImageId, +                FALSE, +                FALSE, +                "SELECT PHOTO", +                PERM_NONE, +                PERM_NONE, +                PERM_NONE, +                FALSE, +                NULL); + +            mFloaterTexturePickerHandle = texture_floaterp->getHandle(); + +            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) +            { +                if (op == LLTextureCtrl::TEXTURE_SELECT) +                { +                    LLUUID image_asset_id; +                    LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get(); +                    if (floaterp) +                    { +                        if (id.notNull()) +                        { +                            image_asset_id = id; +                        } +                        else +                        { +                            image_asset_id = floaterp->getAssetID(); +                        } +                    } + +                    onCommitProfileImage(image_asset_id); +                } +            }); +            texture_floaterp->setLocalTextureEnabled(FALSE); +            texture_floaterp->setBakeTextureEnabled(FALSE); +            texture_floaterp->setCanApply(false, true); + +            parent_floater->addDependentFloater(mFloaterTexturePickerHandle); + +            texture_floaterp->openFloater(); +            texture_floaterp->setFocus(TRUE); +        } +    } +    else +    { +        floaterp->setMinimized(FALSE); +        floaterp->setVisibleAndFrontmost(TRUE); +    } +} + +void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) +{ +    if (mImageId == id) +    { +        return; +    } + +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        LLSD params; +        params["sl_image_id"] = id; +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + +        mImageId = id; +        if (mImageId == LLUUID::null) +        { +            mSecondLifePic->setValue("Generic_Person_Large"); +        } +        else +        { +            mSecondLifePic->setValue(mImageId); +        } + +        LLFloater *floater = mFloaterProfileTextureHandle.get(); +        if (floater) +        { +            LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); +            if (mImageId == LLUUID::null) +            { +                texture_view->resetAsset(); +            } +            else +            { +                texture_view->loadAsset(mImageId); +            } +        } +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } +} + +////////////////////////////////////////////////////////////////////////// +// LLPanelProfileWeb + +LLPanelProfileWeb::LLPanelProfileWeb() + : LLPanelProfileTab() + , mWebBrowser(NULL) + , mAvatarNameCacheConnection() +{ +} + +LLPanelProfileWeb::~LLPanelProfileWeb() +{ +    if (mAvatarNameCacheConnection.connected()) +    { +        mAvatarNameCacheConnection.disconnect(); +    } +} + +void LLPanelProfileWeb::onOpen(const LLSD& key) +{ +    LLPanelProfileTab::onOpen(key); + +    resetData(); + +    mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2)); +} + +BOOL LLPanelProfileWeb::postBuild() +{ +    mWebBrowser = getChild<LLMediaCtrl>("profile_html"); +    mWebBrowser->addObserver(this); +    mWebBrowser->setHomePageUrl("about:blank"); + +    return TRUE; +} + +void LLPanelProfileWeb::resetData() +{ +    mWebBrowser->navigateHome(); +} + +void LLPanelProfileWeb::updateData() +{ +    LLUUID avatar_id = getAvatarId(); +    if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty()) +    { +        setIsLoading(); + +        mWebBrowser->setVisible(TRUE); +        mPerformanceTimer.start(); +        mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML); +    } +} + +void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ +    mAvatarNameCacheConnection.disconnect(); + +    std::string username = av_name.getAccountName(); +    if (username.empty()) +    { +        username = LLCacheName::buildUsername(av_name.getDisplayName()); +    } +    else +    { +        LLStringUtil::replaceChar(username, ' ', '.'); +    } + +    mURLWebProfile = getProfileURL(username, true); +    if (mURLWebProfile.empty()) +    { +        return; +    } + +    //if the tab was opened before name was resolved, load the panel now +    updateData(); +} + +void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl) +{ +    if (!mURLHome.empty()) +    { +        LLSD::String valstr = ctrl->getValue().asString(); +        if (valstr.empty()) +        { +            mWebBrowser->setVisible(TRUE); +            mPerformanceTimer.start(); +            mWebBrowser->navigateTo( mURLHome, HTTP_CONTENT_TEXT_HTML ); +        } +        else if (valstr == "popout") +        { +            // open in viewer's browser, new window +            LLWeb::loadURLInternal(mURLHome); +        } +        else if (valstr == "external") +        { +            // open in external browser +            LLWeb::loadURLExternal(mURLHome); +        } +    } +} + +void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ +    switch(event) +    { +        case MEDIA_EVENT_STATUS_TEXT_CHANGED: +            childSetValue("status_text", LLSD( self->getStatusText() ) ); +        break; + +        case MEDIA_EVENT_NAVIGATE_BEGIN: +        { +            if (mFirstNavigate) +            { +                mFirstNavigate = false; +            } +            else +            { +                mPerformanceTimer.start(); +            } +        } +        break; + +        case MEDIA_EVENT_NAVIGATE_COMPLETE: +        { +            LLStringUtil::format_map_t args; +            args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32()); +            childSetValue("status_text", LLSD( getString("LoadTime", args)) ); +        } +        break; + +        default: +            // Having a default case makes the compiler happy. +        break; +    } +} + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelProfileFirstLife::LLPanelProfileFirstLife() + : LLPanelProfileTab() + , mHasUnsavedChanges(false) +{ +} + +LLPanelProfileFirstLife::~LLPanelProfileFirstLife() +{ +} + +BOOL LLPanelProfileFirstLife::postBuild() +{ +    mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit"); +    mPicture = getChild<LLIconCtrl>("real_world_pic"); + +    mUploadPhoto = getChild<LLButton>("fl_upload_image"); +    mChangePhoto = getChild<LLButton>("fl_change_image"); +    mRemovePhoto = getChild<LLButton>("fl_remove_image"); +    mSaveChanges = getChild<LLButton>("fl_save_changes"); +    mDiscardChanges = getChild<LLButton>("fl_discard_changes"); + +    mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr); +    mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr); +    mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr); +    mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); +    mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); +    mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); + +    return TRUE; +} + +void LLPanelProfileFirstLife::onOpen(const LLSD& key) +{ +    LLPanelProfileTab::onOpen(key); + +    if (!getSelfProfile()) +    { +        // Otherwise as the only focusable element it will be selected +        mDescriptionEdit->setTabStop(FALSE); +    } + +    resetData(); +} + +void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) +{ +    mUploadPhoto->setEnabled(!loading); +    mChangePhoto->setEnabled(!loading); +    mRemovePhoto->setEnabled(!loading && mImageId.notNull()); + +    LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator"); +    indicator->setVisible(loading); +    if (loading) +    { +        indicator->start(); +    } +    else +    { +        indicator->stop(); +    } +} + +void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id) +{ +    mPicture->setValue(image_asset_id); +    mImageId = image_asset_id; +    setProfileImageUploading(false); +} + +void LLPanelProfileFirstLife::commitUnsavedChanges() +{ +    if (mHasUnsavedChanges) +    { +        onSaveDescriptionChanges(); +    } +} + +void LLPanelProfileFirstLife::onUploadPhoto() +{ +    (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile(); + +    LLFloater* floaterp = mFloaterTexturePickerHandle.get(); +    if (floaterp) +    { +        floaterp->closeFloater(); +    } +} + +void LLPanelProfileFirstLife::onChangePhoto() +{ +    LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + +    // Show the dialog +    if (!floaterp) +    { +        LLFloater* parent_floater = gFloaterView->getParentFloater(this); +        if (parent_floater) +        { +            // because inventory construction is somewhat slow +            getWindow()->setCursor(UI_CURSOR_WAIT); +            LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( +                this, +                mImageId, +                LLUUID::null, +                mImageId, +                FALSE, +                FALSE, +                "SELECT PHOTO", +                PERM_NONE, +                PERM_NONE, +                PERM_NONE, +                FALSE, +                NULL); + +            mFloaterTexturePickerHandle = texture_floaterp->getHandle(); + +            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) +            { +                if (op == LLTextureCtrl::TEXTURE_SELECT) +                { +                    LLUUID image_asset_id; +                    LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get(); +                    if (floaterp) +                    { +                        if (id.notNull()) +                        { +                            image_asset_id = id; +                        } +                        else +                        { +                            image_asset_id = floaterp->getAssetID(); +                        } +                    } + +                    onCommitPhoto(image_asset_id); +                } +            }); +            texture_floaterp->setLocalTextureEnabled(FALSE); +            texture_floaterp->setCanApply(false, true); + +            parent_floater->addDependentFloater(mFloaterTexturePickerHandle); + +            texture_floaterp->openFloater(); +            texture_floaterp->setFocus(TRUE); +        } +    } +    else +    { +        floaterp->setMinimized(FALSE); +        floaterp->setVisibleAndFrontmost(TRUE); +    } +} + +void LLPanelProfileFirstLife::onRemovePhoto() +{ +    onCommitPhoto(LLUUID::null); + +    LLFloater* floaterp = mFloaterTexturePickerHandle.get(); +    if (floaterp) +    { +        floaterp->closeFloater(); +    } +} + +void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) +{ +    if (mImageId == id) +    { +        return; +    } + +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        LLSD params; +        params["fl_image_id"] = id; +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + +        mImageId = id; +        if (mImageId.notNull()) +        { +            mPicture->setValue(mImageId); +        } +        else +        { +            mPicture->setValue("Generic_Person_Large"); +        } + +        mRemovePhoto->setEnabled(mImageId.notNull()); +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } +} + +void LLPanelProfileFirstLife::setDescriptionText(const std::string &text) +{ +    mSaveChanges->setEnabled(FALSE); +    mDiscardChanges->setEnabled(FALSE); +    mHasUnsavedChanges = false; + +    mCurrentDescription = text; +    mDescriptionEdit->setValue(mCurrentDescription); +} + +void LLPanelProfileFirstLife::onSetDescriptionDirty() +{ +    mSaveChanges->setEnabled(TRUE); +    mDiscardChanges->setEnabled(TRUE); +    mHasUnsavedChanges = true; +} + +void LLPanelProfileFirstLife::onSaveDescriptionChanges() +{ +    mCurrentDescription = mDescriptionEdit->getValue().asString(); +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription))); +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } + +    mSaveChanges->setEnabled(FALSE); +    mDiscardChanges->setEnabled(FALSE); +    mHasUnsavedChanges = false; +} + +void LLPanelProfileFirstLife::onDiscardDescriptionChanges() +{ +    setDescriptionText(mCurrentDescription); +} + +void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) +{ +    setDescriptionText(avatar_data->fl_about_text); + +    mImageId = avatar_data->fl_image_id; + +    if (mImageId.notNull()) +    { +        mPicture->setValue(mImageId); +    } +    else +    { +        mPicture->setValue("Generic_Person_Large"); +    } + +    setLoaded(); +} + +void LLPanelProfileFirstLife::resetData() +{ +    setDescriptionText(std::string()); +    mPicture->setValue("Generic_Person_Large"); +    mImageId = LLUUID::null; + +    mUploadPhoto->setVisible(getSelfProfile()); +    mChangePhoto->setVisible(getSelfProfile()); +    mRemovePhoto->setVisible(getSelfProfile()); +    mSaveChanges->setVisible(getSelfProfile()); +    mDiscardChanges->setVisible(getSelfProfile()); +} + +void LLPanelProfileFirstLife::setLoaded() +{ +    LLPanelProfileTab::setLoaded(); + +    if (getSelfProfile()) +    { +        mDescriptionEdit->setEnabled(TRUE); +        mPicture->setEnabled(TRUE); +        mRemovePhoto->setEnabled(mImageId.notNull()); +    } +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelProfileNotes::LLPanelProfileNotes() +: LLPanelProfileTab() + , mHasUnsavedChanges(false) +{ + +} + +LLPanelProfileNotes::~LLPanelProfileNotes() +{ +} + +void LLPanelProfileNotes::updateData() +{ +    LLUUID avatar_id = getAvatarId(); +    if (!getStarted() && avatar_id.notNull()) +    { +        setIsLoading(); + +        std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +        if (!cap_url.empty()) +        { +            LLCoros::instance().launch("requestAgentUserInfoCoro", +                boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); +        } +    } +} + +void LLPanelProfileNotes::commitUnsavedChanges() +{ +    if (mHasUnsavedChanges) +    { +        onSaveNotesChanges(); +    } +} + +BOOL LLPanelProfileNotes::postBuild() +{ +    mNotesEditor = getChild<LLTextEditor>("notes_edit"); +    mSaveChanges = getChild<LLButton>("notes_save_changes"); +    mDiscardChanges = getChild<LLButton>("notes_discard_changes"); + +    mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr); +    mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr); +    mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); }); + +    return TRUE; +} + +void LLPanelProfileNotes::onOpen(const LLSD& key) +{ +    LLPanelProfileTab::onOpen(key); + +    resetData(); +} + +void LLPanelProfileNotes::setNotesText(const std::string &text) +{ +    mSaveChanges->setEnabled(FALSE); +    mDiscardChanges->setEnabled(FALSE); +    mHasUnsavedChanges = false; + +    mCurrentNotes = text; +    mNotesEditor->setValue(mCurrentNotes); +} + +void LLPanelProfileNotes::onSetNotesDirty() +{ +    mSaveChanges->setEnabled(TRUE); +    mDiscardChanges->setEnabled(TRUE); +    mHasUnsavedChanges = true; +} + +void LLPanelProfileNotes::onSaveNotesChanges() +{ +    mCurrentNotes = mNotesEditor->getValue().asString(); +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } + +    mSaveChanges->setEnabled(FALSE); +    mDiscardChanges->setEnabled(FALSE); +    mHasUnsavedChanges = false; +} + +void LLPanelProfileNotes::onDiscardNotesChanges() +{ +    setNotesText(mCurrentNotes); +} + +void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) +{ +    setNotesText(avatar_notes->notes); +    mNotesEditor->setEnabled(TRUE); +    setLoaded(); +} + +void LLPanelProfileNotes::resetData() +{ +    resetLoading(); +    setNotesText(std::string()); +} + +void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) +{ +    if (avatar_id.notNull()) +    { +        LLPanelProfileTab::setAvatarId(avatar_id); +    } +} + + +////////////////////////////////////////////////////////////////////////// +// LLPanelProfile + +LLPanelProfile::LLPanelProfile() + : LLPanelProfileTab() +{ +} + +LLPanelProfile::~LLPanelProfile() +{ +} + +BOOL LLPanelProfile::postBuild() +{ +    return TRUE; +} + +void LLPanelProfile::onTabChange() +{ +    LLPanelProfileTab* active_panel = dynamic_cast<LLPanelProfileTab*>(mTabContainer->getCurrentPanel()); +    if (active_panel) +    { +        active_panel->updateData(); +    }  }  void LLPanelProfile::onOpen(const LLSD& key)  { -	getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId()); +    LLUUID avatar_id = key["id"].asUUID(); -	// support commands to open further pieces of UI -	if (key.has("show_tab_panel")) -	{ -		std::string panel = key["show_tab_panel"].asString(); -		if (panel == "create_classified") -		{ -			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]); -			if (picks) -			{ -				picks->createNewClassified(); -			} -		} -		else if (panel == "classified_details") -		{ -			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]); -			if (picks) -			{ -				LLSD params = key; -				params.erase("show_tab_panel"); -				params.erase("open_tab_name"); -				picks->openClassifiedInfo(params); -			} -		} -		else if (panel == "edit_classified") -		{ -			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]); -			if (picks) -			{ -				LLSD params = key; -				params.erase("show_tab_panel"); -				params.erase("open_tab_name"); -				picks->openClassifiedEdit(params); -			} -		} -		else if (panel == "create_pick") -		{ -			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]); -			if (picks) -			{ -				picks->createNewPick(); -			} -		} -		else if (panel == "edit_pick") -		{ -			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]); -			if (picks) -			{ -				LLSD params = key; -				params.erase("show_tab_panel"); -				params.erase("open_tab_name"); -				picks->openPickEdit(params); -			} -		} -	} +    // Don't reload the same profile +    if (getAvatarId() == avatar_id) +    { +        return; +    } + +    LLPanelProfileTab::onOpen(avatar_id); + +    mTabContainer       = getChild<LLTabContainer>("panel_profile_tabs"); +    mPanelSecondlife    = findChild<LLPanelProfileSecondLife>(PANEL_SECONDLIFE); +    mPanelWeb           = findChild<LLPanelProfileWeb>(PANEL_WEB); +    mPanelPicks         = findChild<LLPanelProfilePicks>(PANEL_PICKS); +    mPanelClassifieds   = findChild<LLPanelProfileClassifieds>(PANEL_CLASSIFIEDS); +    mPanelFirstlife     = findChild<LLPanelProfileFirstLife>(PANEL_FIRSTLIFE); +    mPanelNotes         = findChild<LLPanelProfileNotes>(PANEL_NOTES); + +    mPanelSecondlife->onOpen(avatar_id); +    mPanelWeb->onOpen(avatar_id); +    mPanelPicks->onOpen(avatar_id); +    mPanelClassifieds->onOpen(avatar_id); +    mPanelFirstlife->onOpen(avatar_id); +    mPanelNotes->onOpen(avatar_id); + +    // Always request the base profile info +    resetLoading(); +    updateData(); + +    // Some tabs only request data when opened +    mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this));  } -void LLPanelProfile::onTabSelected(const LLSD& param) +void LLPanelProfile::updateData()  { -	std::string tab_name = param.asString(); -	if (NULL != getTabContainer()[tab_name]) -	{ -		getTabContainer()[tab_name]->onOpen(getAvatarId()); -	} +    LLUUID avatar_id = getAvatarId(); +    // Todo: getIsloading functionality needs to be expanded to +    // include 'inited' or 'data_provided' state to not rerequest +    if (!getStarted() && avatar_id.notNull()) +    { +        setIsLoading(); + +        mPanelSecondlife->setIsLoading(); +        mPanelPicks->setIsLoading(); +        mPanelFirstlife->setIsLoading(); +        mPanelNotes->setIsLoading(); + +        std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +        if (!cap_url.empty()) +        { +            LLCoros::instance().launch("requestAgentUserInfoCoro", +                boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); +        } +    }  } -void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params) +void LLPanelProfile::refreshName()  { -	// Hide currently visible panel (STORM-690). -	mChildStack.push(); +    mPanelSecondlife->refreshName(); +} -	// Add the panel or bring it to front. -	if (panel->getParent() != this) -	{ -		addChild(panel); -	} -	else -	{ -		sendChildToFront(panel); -	} +void LLPanelProfile::createPick(const LLPickData &data) +{ +    mTabContainer->selectTabPanel(mPanelPicks); +    mPanelPicks->createPick(data); +} -	panel->setVisible(TRUE); -	panel->setFocus(TRUE); // prevent losing focus by the floater -	panel->onOpen(params); +void LLPanelProfile::showPick(const LLUUID& pick_id) +{ +    if (pick_id.notNull()) +    { +        mPanelPicks->selectPick(pick_id); +    } +    mTabContainer->selectTabPanel(mPanelPicks); +} -	LLRect new_rect = getRect(); -	panel->reshape(new_rect.getWidth(), new_rect.getHeight()); -	new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight()); -	panel->setRect(new_rect); +bool LLPanelProfile::isPickTabSelected() +{ +	return (mTabContainer->getCurrentPanel() == mPanelPicks);  } -void LLPanelProfile::closePanel(LLPanel* panel) +bool LLPanelProfile::isNotesTabSelected()  { -	panel->setVisible(FALSE); +	return (mTabContainer->getCurrentPanel() == mPanelNotes); +} -	if (panel->getParent() == this)  -	{ -		removeChild(panel); +bool LLPanelProfile::hasUnsavedChanges() +{ +    return mPanelSecondlife->hasUnsavedChanges() +        || mPanelPicks->hasUnsavedChanges() +        || mPanelClassifieds->hasUnsavedChanges() +        || mPanelFirstlife->hasUnsavedChanges() +        || mPanelNotes->hasUnsavedChanges(); +} -		// Make the underlying panel visible. -		mChildStack.pop(); +bool LLPanelProfile::hasUnpublishedClassifieds() +{ +    return mPanelClassifieds->hasNewClassifieds(); +} -		// Prevent losing focus by the floater -		const child_list_t* child_list = getChildList(); -		if (child_list->size() > 0) -		{ -			child_list->front()->setFocus(TRUE); -		} -		else -		{ -			LL_WARNS() << "No underlying panel to focus." << LL_ENDL; -		} -	} +void LLPanelProfile::commitUnsavedChanges() +{ +    mPanelSecondlife->commitUnsavedChanges(); +    mPanelPicks->commitUnsavedChanges(); +    mPanelClassifieds->commitUnsavedChanges(); +    mPanelFirstlife->commitUnsavedChanges(); +    mPanelNotes->commitUnsavedChanges();  } -S32 LLPanelProfile::notifyParent(const LLSD& info) +void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit)  { -	std::string action = info["action"]; -	// lets update Picks list after Pick was saved -	if("save_new_pick" == action) -	{ -		onOpen(info); -		return 1; -	} +    if (classified_id.notNull()) +    { +        mPanelClassifieds->selectClassified(classified_id, edit); +    } +    mTabContainer->selectTabPanel(mPanelClassifieds); +} -	return LLPanel::notifyParent(info); +void LLPanelProfile::createClassified() +{ +    mPanelClassifieds->createClassified(); +    mTabContainer->selectTabPanel(mPanelClassifieds);  } + diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index d97f60ed22..d32bb943bd 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -1,25 +1,25 @@ -/**  +/**  * @file llpanelprofile.h  * @brief Profile panel  * -* $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$  */ @@ -27,76 +27,383 @@  #ifndef LL_LLPANELPROFILE_H  #define LL_LLPANELPROFILE_H +#include "llavatarpropertiesprocessor.h" +#include "llcallingcard.h" +#include "llfloater.h"  #include "llpanel.h"  #include "llpanelavatar.h" +#include "llmediactrl.h" +#include "llvoiceclient.h" + +// class LLPanelProfileClassifieds; +// class LLTabContainer; +// class LLPanelProfileSecondLife; +// class LLPanelProfileWeb; +// class LLPanelProfilePicks; +// class LLPanelProfileFirstLife; +// class LLPanelProfileNotes; + +class LLAvatarName; +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLIconCtrl;  class LLTabContainer; +class LLTextBox; +class LLTextureCtrl; +class LLMediaCtrl; +class LLGroupList; +class LLTextBase; +class LLMenuButton; +class LLLineEditor; +class LLTextEditor; +class LLPanelProfileClassifieds; +class LLPanelProfilePicks; +class LLViewerFetchedTexture; -std::string getProfileURL(const std::string& agent_name);  /** -* Base class for Profile View and My Profile. +* Panel for displaying Avatar's second life related info.  */ -class LLPanelProfile : public LLPanel +class LLPanelProfileSecondLife +	: public LLPanelProfileTab +	, public LLFriendObserver +	, public LLVoiceClientStatusObserver  { -	LOG_CLASS(LLPanelProfile); +public: +	LLPanelProfileSecondLife(); +	/*virtual*/ ~LLPanelProfileSecondLife(); + +	void onOpen(const LLSD& key) override; + +	/** +	 * LLFriendObserver trigger +	 */ +	void changed(U32 mask) override; + +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	void onChange(EStatusType status, const std::string &channelURI, bool proximal) override; + +	void setAvatarId(const LLUUID& avatar_id) override; + +	BOOL postBuild() override; + +	void resetData() override; + +	/** +	 * Sends update data request to server. +	 */ +	void updateData() override; +    void refreshName(); + +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + +    void setProfileImageUploading(bool loading); +    void setProfileImageUploaded(const LLUUID &image_asset_id); + +    bool hasUnsavedChanges() override; +    void commitUnsavedChanges() override; + +    friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + +protected: +	/** +	 * Process profile related data received from server. +	 */ +	void processProfileProperties(const LLAvatarData* avatar_data); + +	/** +	 * Processes group related data received from server. +	 */ +	void processGroupProperties(const LLAvatarGroups* avatar_groups); + +	/** +	 * Fills common for Avatar profile and My Profile fields. +	 */ +	void fillCommonData(const LLAvatarData* avatar_data); + +	/** +	 * Fills partner data. +	 */ +	void fillPartnerData(const LLAvatarData* avatar_data); +	/** +	 * Fills account status. +	 */ +	void fillAccountStatus(const LLAvatarData* avatar_data); + +    /** +     * Sets permissions specific icon +     */ +    void fillRightsData(); + +    /** +     * Fills user name, display name, age. +     */ +    void fillAgeData(const LLDate &born_on); + +    void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep); +    static void onImageLoaded(BOOL success, +                              LLViewerFetchedTexture *src_vi, +                              LLImageRaw* src, +                              LLImageRaw* aux_src, +                              S32 discard_level, +                              BOOL final, +                              void* userdata); + +	/** +	 * Displays avatar's online status if possible. +	 * +	 * Requirements from EXT-3880: +	 * For friends: +	 * - Online when online and privacy settings allow to show +	 * - Offline when offline and privacy settings allow to show +	 * - Else: nothing +	 * For other avatars: +	 *	- Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online" +	 *	- Else: Offline +	 */ +	void updateOnlineStatus(); +	void processOnlineStatus(bool is_friend, bool show_online, bool online); + +private: +    void setLoaded() override; +    void onCommitMenu(const LLSD& userdata); +    bool onEnableMenu(const LLSD& userdata); +    bool onCheckMenu(const LLSD& userdata); +	void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name); + +    void setDescriptionText(const std::string &text); +    void onSetDescriptionDirty(); +    void onShowInSearchCallback(); +    void onSaveDescriptionChanges(); +    void onDiscardDescriptionChanges(); +    void onShowAgentPermissionsDialog(); +    void onShowAgentProfileTexture(); +    void onShowTexturePicker(); +    void onCommitProfileImage(const LLUUID& id); + +private: +	typedef std::map<std::string, LLUUID> group_map_t; +	group_map_t				mGroups; +	void					openGroupProfile(); + +	LLGroupList*		mGroupList; +    LLComboBox*			mShowInSearchCombo; +    LLIconCtrl*			mSecondLifePic; +	LLPanel*			mSecondLifePicLayout; +    LLTextEditor*		mDescriptionEdit; +    LLMenuButton*		mAgentActionMenuButton; +    LLButton*			mSaveDescriptionChanges; +    LLButton*			mDiscardDescriptionChanges; +    LLIconCtrl*			mCanSeeOnlineIcon; +    LLIconCtrl*			mCantSeeOnlineIcon; +    LLIconCtrl*			mCanSeeOnMapIcon; +    LLIconCtrl*			mCantSeeOnMapIcon; +    LLIconCtrl*			mCanEditObjectsIcon; +    LLIconCtrl*			mCantEditObjectsIcon; + +    LLHandle<LLFloater>	mFloaterPermissionsHandle; +    LLHandle<LLFloater>	mFloaterProfileTextureHandle; +    LLHandle<LLFloater>	mFloaterTexturePickerHandle; + +    bool				mHasUnsavedDescriptionChanges; +	bool				mVoiceStatus; +    bool				mWaitingForImageUpload; +    bool				mAllowPublish; +    std::string			mDescriptionText; +    LLUUID				mImageId; + +	boost::signals2::connection	mAvatarNameCacheConnection; +}; + + +/** +* Panel for displaying Avatar's web profile and home page. +*/ +class LLPanelProfileWeb +	: public LLPanelProfileTab +	, public LLViewerMediaObserver +{  public: -	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); -	/*virtual*/ void onOpen(const LLSD& key); +	LLPanelProfileWeb(); +	/*virtual*/ ~LLPanelProfileWeb(); + +	void onOpen(const LLSD& key) override; + +	BOOL postBuild() override; -	virtual void openPanel(LLPanel* panel, const LLSD& params); +	void resetData() override; -	virtual void closePanel(LLPanel* panel); +	/** +	 * Loads web profile. +	 */ +	void updateData() override; -	S32 notifyParent(const LLSD& info); +	void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; + +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + +    friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);  protected: +	void onCommitLoad(LLUICtrl* ctrl); -	LLPanelProfile(); +private: +	std::string			mURLHome; +	std::string			mURLWebProfile; +	LLMediaCtrl*		mWebBrowser; -	virtual void onTabSelected(const LLSD& param); +	LLFrameTimer		mPerformanceTimer; +	bool				mFirstNavigate; -	const LLUUID& getAvatarId() { return mAvatarId; } +	boost::signals2::connection	mAvatarNameCacheConnection; +}; + +/** +* Panel for displaying Avatar's first life related info. +*/ +class LLPanelProfileFirstLife +	: public LLPanelProfileTab +{ +public: +	LLPanelProfileFirstLife(); +	/*virtual*/ ~LLPanelProfileFirstLife(); + +	void onOpen(const LLSD& key) override; + +	BOOL postBuild() override; + +    void processProperties(const LLAvatarData* avatar_data); + +	void resetData() override; + +    void setProfileImageUploading(bool loading); +    void setProfileImageUploaded(const LLUUID &image_asset_id); + +    bool hasUnsavedChanges() override { return mHasUnsavedChanges; } +    void commitUnsavedChanges() override; + +    friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + +protected: +	void setLoaded() override; + +    void onUploadPhoto(); +    void onChangePhoto(); +    void onRemovePhoto(); +    void onCommitPhoto(const LLUUID& id); +    void setDescriptionText(const std::string &text); +    void onSetDescriptionDirty(); +    void onSaveDescriptionChanges(); +    void onDiscardDescriptionChanges(); + +	LLTextEditor*	mDescriptionEdit; +    LLIconCtrl*		mPicture; +    LLButton* mUploadPhoto; +    LLButton* mChangePhoto; +    LLButton* mRemovePhoto; +    LLButton* mSaveChanges; +    LLButton* mDiscardChanges; + +    LLHandle<LLFloater>	mFloaterTexturePickerHandle; + +    std::string		mCurrentDescription; +    LLUUID			mImageId; +    bool			mHasUnsavedChanges; +}; + +/** + * Panel for displaying Avatar's notes and modifying friend's rights. + */ +class LLPanelProfileNotes +	: public LLPanelProfileTab +{ +public: +	LLPanelProfileNotes(); +	/*virtual*/ ~LLPanelProfileNotes(); -	void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } +	void setAvatarId(const LLUUID& avatar_id) override; -	typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t; +	void onOpen(const LLSD& key) override; -	profile_tabs_t& getTabContainer() { return mTabContainer; } +	BOOL postBuild() override; + +    void processProperties(LLAvatarNotes* avatar_notes); + +	void resetData() override; + +	void updateData() override; + +    bool hasUnsavedChanges() override { return mHasUnsavedChanges; } +    void commitUnsavedChanges() override; + +protected: +    void setNotesText(const std::string &text); +    void onSetNotesDirty(); +    void onSaveNotesChanges(); +    void onDiscardNotesChanges(); + +	LLTextEditor*       mNotesEditor; +    LLButton* mSaveChanges; +    LLButton* mDiscardChanges; + +    std::string		mCurrentNotes; +    bool			mHasUnsavedChanges; +}; + + +/** +* Container panel for the profile tabs +*/ +class LLPanelProfile +    : public LLPanelProfileTab +{ +public: +    LLPanelProfile(); +    /*virtual*/ ~LLPanelProfile(); + +    BOOL postBuild() override; + +    void updateData() override; +    void refreshName(); + +    void onOpen(const LLSD& key) override; + +    void createPick(const LLPickData &data); +    void showPick(const LLUUID& pick_id = LLUUID::null); +    bool isPickTabSelected(); +    bool isNotesTabSelected(); +    bool hasUnsavedChanges() override; +    bool hasUnpublishedClassifieds(); +    void commitUnsavedChanges() override; + +    void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false); +    void createClassified(); + +    LLAvatarData getAvatarData() { return mAvatarData; }; + +    friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);  private: +    void onTabChange(); + +    LLPanelProfileSecondLife*   mPanelSecondlife; +    LLPanelProfileWeb*          mPanelWeb; +    LLPanelProfilePicks*        mPanelPicks; +    LLPanelProfileClassifieds*  mPanelClassifieds; +    LLPanelProfileFirstLife*    mPanelFirstlife; +    LLPanelProfileNotes*        mPanelNotes; +    LLTabContainer*             mTabContainer; -	//-- ChildStack begins ---------------------------------------------------- -	class ChildStack -	{ -		LOG_CLASS(LLPanelProfile::ChildStack); -	public: -		ChildStack(); -		~ChildStack(); -		void setParent(LLPanel* parent); - -		bool push(); -		bool pop(); -		void preParentReshape(); -		void postParentReshape(); - -	private: -		void dump(); - -		typedef LLView::child_list_t view_list_t; -		typedef std::list<view_list_t> stack_t; - -		stack_t		mStack; -		stack_t		mSavedStack; -		LLPanel*	mParent; -	}; -	//-- ChildStack ends ------------------------------------------------------ - -	profile_tabs_t mTabContainer; -	ChildStack		mChildStack; -	LLUUID mAvatarId; +    // Todo: due to server taking minutes to update this needs a more long term storage +    // to reuse recently saved values if user opens floater again +    // Storage implementation depends onto how a cap will be implemented, if cap will be +    // enought to fully update LLAvatarPropertiesProcessor, then this storage can be +    // implemented there. +    LLAvatarData mAvatarData;  };  #endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp new file mode 100644 index 0000000000..a3913ddc49 --- /dev/null +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -0,0 +1,1513 @@ +/** + * @file llpanelprofileclassifieds.cpp + * @brief LLPanelProfileClassifieds and related class implementations + * + * $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 "llpanelprofileclassifieds.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llavatarpropertiesprocessor.h" +#include "llclassifiedflags.h" +#include "llcombobox.h" +#include "llcommandhandler.h" // for classified HTML detail page click tracking +#include "llcorehttputil.h" +#include "lldispatcher.h" +#include "llfloaterclassified.h" +#include "llfloaterreg.h" +#include "llfloatersidepanelcontainer.h" +#include "llfloaterworldmap.h" +#include "lliconctrl.h" +#include "lllineeditor.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llpanelavatar.h" +#include "llparcel.h" +#include "llregistry.h" +#include "llscrollcontainer.h" +#include "llstartup.h" +#include "llstatusbar.h" +#include "lltabcontainer.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lltrans.h" +#include "llviewergenericmessage.h" // send_generic_message +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewertexture.h" +#include "llviewertexture.h" + + +//*TODO: verify this limit +const S32 MAX_AVATAR_CLASSIFIEDS = 100; + +const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$ +const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530; + +//static +LLPanelProfileClassified::panel_list_t LLPanelProfileClassified::sAllPanels; + +static LLPanelInjector<LLPanelProfileClassifieds> t_panel_profile_classifieds("panel_profile_classifieds"); +static LLPanelInjector<LLPanelProfileClassified> t_panel_profile_classified("panel_profile_classified"); + +class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesObserver +{ +public: +    // throttle calls from untrusted browsers +    LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {} +	 +	std::set<LLUUID> mClassifiedIds; +	std::string mRequestVerb; +     +	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) +    { +        if (LLStartUp::getStartupState() < STATE_STARTED) +        { +            return true; +        } + +        if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds")) +        { +            LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +            return true; +        } + +        // handle app/classified/create urls first +        if (params.size() == 1 && params[0].asString() == "create") +        { +            LLAvatarActions::createClassified(); +            return true; +        } + +        // then handle the general app/classified/{UUID}/{CMD} urls +        if (params.size() < 2) +        { +            return false; +        } + +        // get the ID for the classified +        LLUUID classified_id; +        if (!classified_id.set(params[0], FALSE)) +        { +            return false; +        } + +        // show the classified in the side tray. +        // need to ask the server for more info first though... +        const std::string verb = params[1].asString(); +        if (verb == "about") +        { +            mRequestVerb = verb; +            mClassifiedIds.insert(classified_id); +            LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this); +            LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id); +            return true; +        } +        else if (verb == "edit") +        { +            LLAvatarActions::showClassified(gAgent.getID(), classified_id, true); +            return true; +        } + +        return false; +    } + +    void openClassified(LLAvatarClassifiedInfo* c_info) +    { +        if (mRequestVerb == "about") +        { +            if (c_info->creator_id == gAgent.getID()) +            { +                LLAvatarActions::showClassified(gAgent.getID(), c_info->classified_id, false); +            } +            else +            { +                LLSD params; +                params["id"] = c_info->creator_id; +                params["classified_id"] = c_info->classified_id; +                params["classified_creator_id"] = c_info->creator_id; +                params["classified_snapshot_id"] = c_info->snapshot_id; +                params["classified_name"] = c_info->name; +                params["classified_desc"] = c_info->description; +                params["from_search"] = true; + +                LLFloaterClassified* floaterp = LLFloaterReg::getTypedInstance<LLFloaterClassified>("classified", params); +                if (floaterp) +                { +                    floaterp->openFloater(params); +                    floaterp->setVisibleAndFrontmost(); +                } +            } +        } +    } + +    void processProperties(void* data, EAvatarProcessorType type) +    { +        if (APT_CLASSIFIED_INFO != type) +        { +            return; +        } + +        // is this the classified that we asked for? +        LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); +        if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end()) +        { +            return; +        } + +        // open the detail side tray for this classified +        openClassified(c_info); + +        // remove our observer now that we're done +        mClassifiedIds.erase(c_info->classified_id); +        LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this); +    } +}; +LLClassifiedHandler gClassifiedHandler; + +////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// LLPanelProfileClassifieds +//----------------------------------------------------------------------------- + +LLPanelProfileClassifieds::LLPanelProfileClassifieds() + : LLPanelProfilePropertiesProcessorTab() + , mClassifiedToSelectOnLoad(LLUUID::null) + , mClassifiedEditOnLoad(false) + , mSheduledClassifiedCreation(false) +{ +} + +LLPanelProfileClassifieds::~LLPanelProfileClassifieds() +{ +} + +void LLPanelProfileClassifieds::onOpen(const LLSD& key) +{ +    LLPanelProfilePropertiesProcessorTab::onOpen(key); + +    resetData(); + +    bool own_profile = getSelfProfile(); +    if (own_profile) +    { +        mNewButton->setVisible(TRUE); +        mNewButton->setEnabled(FALSE); + +        mDeleteButton->setVisible(TRUE); +        mDeleteButton->setEnabled(FALSE); +    } + +    childSetVisible("buttons_header", own_profile); + +} + +void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bool edit) +{ +    if (getIsLoaded()) +    { +        for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +        { +            LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +            if (classified_panel) +            { +                if (classified_panel->getClassifiedId() == classified_id) +                { +                    mTabContainer->selectTabPanel(classified_panel); +                    if (edit) +                    { +                        classified_panel->setEditMode(TRUE); +                    } +                    break; +                } +            } +        } +    } +    else +    { +        mClassifiedToSelectOnLoad = classified_id; +        mClassifiedEditOnLoad = edit; +    } +} + +void LLPanelProfileClassifieds::createClassified() +{ +    if (getIsLoaded()) +    { +        mNoItemsLabel->setVisible(FALSE); +        LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create(); +        classified_panel->onOpen(LLSD()); +        mTabContainer->addTabPanel( +            LLTabContainer::TabPanelParams(). +            panel(classified_panel). +            select_tab(true). +            label(classified_panel->getClassifiedName())); +        updateButtons(); +    } +    else +    { +        mSheduledClassifiedCreation = true; +    } +} + +BOOL LLPanelProfileClassifieds::postBuild() +{ +    mTabContainer = getChild<LLTabContainer>("tab_classifieds"); +    mNoItemsLabel = getChild<LLUICtrl>("classifieds_panel_text"); +    mNewButton = getChild<LLButton>("new_btn"); +    mDeleteButton = getChild<LLButton>("delete_btn"); + +    mNewButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickNewBtn, this)); +    mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickDelete, this)); + +    return TRUE; +} + +void LLPanelProfileClassifieds::onClickNewBtn() +{ +    mNoItemsLabel->setVisible(FALSE); +    LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create(); +    classified_panel->onOpen(LLSD()); +    mTabContainer->addTabPanel( +        LLTabContainer::TabPanelParams(). +        panel(classified_panel). +        select_tab(true). +        label(classified_panel->getClassifiedName())); +    updateButtons(); +} + +void LLPanelProfileClassifieds::onClickDelete() +{ +    LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getCurrentPanel()); +    if (classified_panel) +    { +        LLUUID classified_id = classified_panel->getClassifiedId(); +        LLSD args; +        args["CLASSIFIED"] = classified_panel->getClassifiedName(); +        LLSD payload; +        payload["classified_id"] = classified_id; +        payload["tab_idx"] = mTabContainer->getCurrentPanelIndex(); +        LLNotificationsUtil::add("ProfileDeleteClassified", args, payload, +            boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2)); +    } +} + +void LLPanelProfileClassifieds::callbackDeleteClassified(const LLSD& notification, const LLSD& response) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + +    if (0 == option) +    { +        LLUUID classified_id = notification["payload"]["classified_id"].asUUID(); +        S32 tab_idx = notification["payload"]["tab_idx"].asInteger(); + +        LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (classified_panel && classified_panel->getClassifiedId() == classified_id) +        { +            mTabContainer->removeTabPanel(classified_panel); +        } + +        if (classified_id.notNull()) +        { +            LLAvatarPropertiesProcessor::getInstance()->sendClassifiedDelete(classified_id); +        } + +        updateButtons(); + +        BOOL no_data = !mTabContainer->getTabCount(); +        mNoItemsLabel->setVisible(no_data); +    } +} + +void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorType type) +{ +    if ((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type)) +    { +        LLUUID avatar_id = getAvatarId(); + +        LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data); +        if (c_info && getAvatarId() == c_info->target_id) +        { +            // do not clear classified list in case we will receive two or more data packets. +            // list has been cleared in updateData(). (fix for EXT-6436) +            LLUUID selected_id = mClassifiedToSelectOnLoad; +            bool has_selection = false; + +            LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin(); +            for (; c_info->classifieds_list.end() != it; ++it) +            { +                LLAvatarClassifieds::classified_data c_data = *it; + +                LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create(); + +                LLSD params; +                params["classified_creator_id"] = avatar_id; +                params["classified_id"] = c_data.classified_id; +                params["classified_name"] = c_data.name; +                params["from_search"] = (selected_id == c_data.classified_id); //SLURL handling and stats tracking +                params["edit"] = (selected_id == c_data.classified_id) && mClassifiedEditOnLoad; +                classified_panel->onOpen(params); + +                mTabContainer->addTabPanel( +                    LLTabContainer::TabPanelParams(). +                    panel(classified_panel). +                    select_tab(selected_id == c_data.classified_id). +                    label(c_data.name)); + +                if (selected_id == c_data.classified_id) +                { +                    has_selection = true; +                } +            } + +            if (mSheduledClassifiedCreation) +            { +                LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create(); +                classified_panel->onOpen(LLSD()); +                mTabContainer->addTabPanel( +                    LLTabContainer::TabPanelParams(). +                    panel(classified_panel). +                    select_tab(!has_selection). +                    label(classified_panel->getClassifiedName())); +                has_selection = true; +            } + +            // reset 'do on load' values +            mClassifiedToSelectOnLoad = LLUUID::null; +            mClassifiedEditOnLoad = false; +            mSheduledClassifiedCreation = false; + +            // set even if not visible, user might delete own +            // calassified and this string will need to be shown +            if (getSelfProfile()) +            { +                mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText")); +            } +            else +            { +                mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText")); +            } + +            bool has_data = mTabContainer->getTabCount() > 0; +            mNoItemsLabel->setVisible(!has_data); +            if (has_data && !has_selection) +            { +                mTabContainer->selectFirstTab(); +            } + +            setLoaded(); +            updateButtons(); +        } +    } +} + +void LLPanelProfileClassifieds::resetData() +{ +    resetLoading(); +    mTabContainer->deleteAllTabs(); +} + +void LLPanelProfileClassifieds::updateButtons() +{ +    if (getSelfProfile()) +    { +        mNewButton->setEnabled(canAddNewClassified()); +        mDeleteButton->setEnabled(canDeleteClassified()); +    } +} + +void LLPanelProfileClassifieds::updateData() +{ +    // Send picks request only once +    LLUUID avatar_id = getAvatarId(); +    if (!getStarted() && avatar_id.notNull()) +    { +        setIsLoading(); +        mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText")); +        mNoItemsLabel->setVisible(TRUE); + +        LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(avatar_id); +    } +} + +bool LLPanelProfileClassifieds::hasNewClassifieds() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (classified_panel && classified_panel->isNew()) +        { +            return true; +        } +    } +    return false; +} + +bool LLPanelProfileClassifieds::hasUnsavedChanges() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (classified_panel && classified_panel->isDirty()) // includes 'new' +        { +            return true; +        } +    } +    return false; +} + +bool LLPanelProfileClassifieds::canAddNewClassified() +{ +    return (mTabContainer->getTabCount() < MAX_AVATAR_CLASSIFIEDS); +} + +bool LLPanelProfileClassifieds::canDeleteClassified() +{ +    return (mTabContainer->getTabCount() > 0); +} + +void LLPanelProfileClassifieds::commitUnsavedChanges() +{ +    if (getIsLoaded()) +    { +        for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +        { +            LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +            if (classified_panel && classified_panel->isDirty() && !classified_panel->isNew()) +            { +                classified_panel->doSave(); +            } +        } +    } +} +//----------------------------------------------------------------------------- +// LLDispatchClassifiedClickThrough +//----------------------------------------------------------------------------- + +// "classifiedclickthrough" +// strings[0] = classified_id +// strings[1] = teleport_clicks +// strings[2] = map_clicks +// strings[3] = profile_clicks +class LLDispatchClassifiedClickThrough : public LLDispatchHandler +{ +public: +    virtual bool operator()( +        const LLDispatcher* dispatcher, +        const std::string& key, +        const LLUUID& invoice, +        const sparam_t& strings) +    { +        if (strings.size() != 4) return false; +        LLUUID classified_id(strings[0]); +        S32 teleport_clicks = atoi(strings[1].c_str()); +        S32 map_clicks = atoi(strings[2].c_str()); +        S32 profile_clicks = atoi(strings[3].c_str()); + +        LLPanelProfileClassified::setClickThrough( +            classified_id, teleport_clicks, map_clicks, profile_clicks, false); + +        return true; +    } +}; +static LLDispatchClassifiedClickThrough sClassifiedClickThrough; + + +//----------------------------------------------------------------------------- +// LLPanelProfileClassified +//----------------------------------------------------------------------------- + +static const S32 CB_ITEM_MATURE = 0; +static const S32 CB_ITEM_PG    = 1; + +LLPanelProfileClassified::LLPanelProfileClassified() + : LLPanelProfilePropertiesProcessorTab() + , mInfoLoaded(false) + , mTeleportClicksOld(0) + , mMapClicksOld(0) + , mProfileClicksOld(0) + , mTeleportClicksNew(0) + , mMapClicksNew(0) + , mProfileClicksNew(0) + , mPriceForListing(0) + , mSnapshotCtrl(NULL) + , mPublishFloater(NULL) + , mIsNew(false) + , mIsNewWithErrors(false) + , mCanClose(false) + , mEditMode(false) + , mEditOnLoad(false) +{ +    sAllPanels.push_back(this); +} + +LLPanelProfileClassified::~LLPanelProfileClassified() +{ +    sAllPanels.remove(this); +    gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler +} + +//static +LLPanelProfileClassified* LLPanelProfileClassified::create() +{ +    LLPanelProfileClassified* panel = new LLPanelProfileClassified(); +    panel->buildFromFile("panel_profile_classified.xml"); +    return panel; +} + +BOOL LLPanelProfileClassified::postBuild() +{ +    mScrollContainer    = getChild<LLScrollContainer>("profile_scroll"); +    mInfoPanel          = getChild<LLView>("info_panel"); +    mInfoScroll         = getChild<LLPanel>("info_scroll_content_panel"); +    mEditPanel          = getChild<LLPanel>("edit_panel"); + +    mSnapshotCtrl       = getChild<LLTextureCtrl>("classified_snapshot"); +    mEditIcon           = getChild<LLUICtrl>("edit_icon"); + +    //info +    mClassifiedNameText = getChild<LLUICtrl>("classified_name"); +    mClassifiedDescText = getChild<LLTextEditor>("classified_desc"); +    mLocationText       = getChild<LLUICtrl>("classified_location"); +    mCategoryText       = getChild<LLUICtrl>("category"); +    mContentTypeText    = getChild<LLUICtrl>("content_type"); +    mContentTypeM       = getChild<LLIconCtrl>("content_type_moderate"); +    mContentTypeG       = getChild<LLIconCtrl>("content_type_general"); +    mPriceText          = getChild<LLUICtrl>("price_for_listing"); +    mAutoRenewText      = getChild<LLUICtrl>("auto_renew"); + +    mMapButton          = getChild<LLButton>("show_on_map_btn"); +    mTeleportButton     = getChild<LLButton>("teleport_btn"); +    mEditButton         = getChild<LLButton>("edit_btn"); + +    //edit +    mClassifiedNameEdit = getChild<LLLineEditor>("classified_name_edit"); +    mClassifiedDescEdit = getChild<LLTextEditor>("classified_desc_edit"); +    mLocationEdit       = getChild<LLUICtrl>("classified_location_edit"); +    mCategoryCombo      = getChild<LLComboBox>("category_edit"); +    mContentTypeCombo   = getChild<LLComboBox>("content_type_edit"); +    mAutoRenewEdit      = getChild<LLUICtrl>("auto_renew_edit"); + +    mSaveButton         = getChild<LLButton>("save_changes_btn"); +    mSetLocationButton  = getChild<LLButton>("set_to_curr_location_btn"); +    mCancelButton       = getChild<LLButton>("cancel_btn"); + +    mUtilityBtnCnt = getChild<LLPanel>("util_buttons_lp"); +    mPublishBtnsCnt = getChild<LLPanel>("publish_layout_panel"); +    mCancelBtnCnt = getChild<LLPanel>("cancel_btn_lp"); +    mSaveBtnCnt = getChild<LLPanel>("save_btn_lp"); + +    mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelProfileClassified::onTextureSelected, this)); +    mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseEnter, this)); +    mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseLeave, this)); +    mEditIcon->setVisible(false); + +    mMapButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onMapClick, this)); +    mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onTeleportClick, this)); +    mEditButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onEditClick, this)); +    mSaveButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSaveClick, this)); +    mSetLocationButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSetLocationClick, this)); +    mCancelButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onCancelClick, this)); + +    LLClassifiedInfo::cat_map::iterator iter; +    for (iter = LLClassifiedInfo::sCategories.begin(); +        iter != LLClassifiedInfo::sCategories.end(); +        iter++) +    { +        mCategoryCombo->add(LLTrans::getString(iter->second)); +    } + +    mClassifiedNameEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this), NULL); +    mClassifiedDescEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this)); +    mCategoryCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this)); +    mContentTypeCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this)); +    mAutoRenewEdit->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this)); + +    return TRUE; +} + +void LLPanelProfileClassified::onOpen(const LLSD& key) +{ +    mIsNew = key.isUndefined(); + +    resetData(); +    resetControls(); +    scrollToTop(); + +    // classified is not created yet +    bool is_new = isNew() || isNewWithErrors(); + +    if(is_new) +    { +        LLPanelProfilePropertiesProcessorTab::setAvatarId(gAgent.getID()); + +        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(); +        } + +        setClassifiedName(makeClassifiedName()); +        setDescription(desc); +        setSnapshotId(snapshot_id); +        setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal())); +        // server will set valid parcel id +        setParcelId(LLUUID::null); + +        mSaveButton->setLabelArg("[LABEL]", getString("publish_label")); + +        setEditMode(TRUE); +        enableSave(true); +        enableEditing(true); +        resetDirty(); +        setInfoLoaded(false); +    } +    else +    { +        LLUUID avatar_id = key["classified_creator_id"]; +        if(avatar_id.isNull()) +        { +            return; +        } +        LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); + +        setClassifiedId(key["classified_id"]); +        setClassifiedName(key["classified_name"]); +        setFromSearch(key["from_search"]); +        mEditOnLoad = key["edit"]; + +        LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL; + +        LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); + +        gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); + +        if (gAgent.getRegion()) +        { +            // While we're at it let's get the stats from the new table if that +            // capability exists. +            std::string url = gAgent.getRegion()->getCapability("SearchStatRequest"); +            if (!url.empty()) +            { +                LL_INFOS() << "Classified stat request via capability" << LL_ENDL; +                LLSD body; +                LLUUID classifiedId = getClassifiedId(); +                body["classified_id"] = classifiedId; +                LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, +                    boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, classifiedId, _1)); +            } +        } +        // Update classified click stats. +        // *TODO: Should we do this when opening not from search? +        if (!fromSearch() ) +        { +            sendClickMessage("profile"); +        } + +        setInfoLoaded(false); +    } + + +    bool is_self = getSelfProfile(); +    getChildView("auto_renew_layout_panel")->setVisible(is_self); +    getChildView("clickthrough_layout_panel")->setVisible(is_self); + +    updateButtons(); +} + +void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorType type) +{ +    if (APT_CLASSIFIED_INFO != type) +    { +        return; +    } + +    LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); +    if(c_info && getClassifiedId() == c_info->classified_id) +    { +        // see LLPanelProfileClassified::sendUpdate() for notes +        if (mIsNewWithErrors) +        { +            // We just published it +            setEditMode(FALSE); +        } +        mIsNewWithErrors = false; +        mIsNew = false; + +        setClassifiedName(c_info->name); +        setDescription(c_info->description); +        setSnapshotId(c_info->snapshot_id); +        setParcelId(c_info->parcel_id); +        setPosGlobal(c_info->pos_global); +        setSimName(c_info->sim_name); + +        setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global)); + +        mCategoryText->setValue(LLClassifiedInfo::sCategories[c_info->category]); +        // *HACK see LLPanelProfileClassified::sendUpdate() +        setCategory(c_info->category - 1); + +        bool mature = is_cf_mature(c_info->flags); +        setContentType(mature); + +        bool auto_renew = is_cf_auto_renew(c_info->flags); +        std::string auto_renew_str = auto_renew ? getString("auto_renew_on") : getString("auto_renew_off"); +        mAutoRenewText->setValue(auto_renew_str); +        mAutoRenewEdit->setValue(auto_renew); + +        static LLUIString  price_str = getString("l$_price"); +        price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing)); +        mPriceText->setValue(LLSD(price_str)); + +        static std::string date_fmt = getString("date_fmt"); +        std::string date_str = date_fmt; +        LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date)); +        getChild<LLUICtrl>("creation_date")->setValue(date_str); + +        resetDirty(); +        setInfoLoaded(true); +        enableSave(false); +        enableEditing(true); + +        // for just created classified - in case user opened edit panel before processProperties() callback +        mSaveButton->setLabelArg("[LABEL]", getString("save_label")); + +        setLoaded(); +        updateButtons(); + +        if (mEditOnLoad) +        { +            setEditMode(TRUE); +        } +    } + +} + +void LLPanelProfileClassified::setEditMode(BOOL edit_mode) +{ +    mEditMode = edit_mode; + +    mInfoPanel->setVisible(!edit_mode); +    mEditPanel->setVisible(edit_mode); + +    // snapshot control is common between info and edit, +    // enable it only when in edit mode +    mSnapshotCtrl->setEnabled(edit_mode); + +    scrollToTop(); +    updateButtons(); +    updateInfoRect(); +} + +void LLPanelProfileClassified::updateButtons() +{ +    bool edit_mode = getEditMode(); +    mUtilityBtnCnt->setVisible(!edit_mode); + +    // cancel button should either delete unpublished +    // classified or not be there at all +    mCancelBtnCnt->setVisible(edit_mode && !mIsNew); +    mPublishBtnsCnt->setVisible(edit_mode); +    mSaveBtnCnt->setVisible(edit_mode); +    mEditButton->setVisible(!edit_mode && getSelfProfile()); +} + +void LLPanelProfileClassified::updateInfoRect() +{ +    if (getEditMode()) +    { +        // info_scroll_content_panel contains both info and edit panel +        // info panel can be very large and scroll bar will carry over. +        // Resize info panel to prevent scroll carry over when in edit mode. +        mInfoScroll->reshape(mInfoScroll->getRect().getWidth(), DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT, FALSE); +    } +    else +    { +        // Adjust text height to make description scrollable. +        S32 new_height = mClassifiedDescText->getTextBoundingRect().getHeight(); +        LLRect visible_rect = mClassifiedDescText->getVisibleDocumentRect(); +        S32 delta_height = new_height - visible_rect.getHeight() + 5; + +        LLRect rect = mInfoScroll->getRect(); +        mInfoScroll->reshape(rect.getWidth(), rect.getHeight() + delta_height, FALSE); +    } +} + +void LLPanelProfileClassified::enableEditing(bool enable) +{ +    mEditButton->setEnabled(enable); +    mClassifiedNameEdit->setEnabled(enable); +    mClassifiedDescEdit->setEnabled(enable); +    mSetLocationButton->setEnabled(enable); +    mCategoryCombo->setEnabled(enable); +    mContentTypeCombo->setEnabled(enable); +    mAutoRenewEdit->setEnabled(enable); +} + +void LLPanelProfileClassified::resetControls() +{ +    updateButtons(); + +    mCategoryCombo->setCurrentByIndex(0); +    mContentTypeCombo->setCurrentByIndex(0); +    mAutoRenewEdit->setValue(false); +    mPriceForListing = MINIMUM_PRICE_FOR_LISTING; +} + +void LLPanelProfileClassified::onEditClick() +{ +    setEditMode(TRUE); +} + +void LLPanelProfileClassified::onCancelClick() +{ +    if (isNew()) +    { +        mClassifiedNameEdit->setValue(mClassifiedNameText->getValue()); +        mClassifiedDescEdit->setValue(mClassifiedDescText->getValue()); +        mLocationEdit->setValue(mLocationText->getValue()); +        mCategoryCombo->setCurrentByIndex(0); +        mContentTypeCombo->setCurrentByIndex(0); +        mAutoRenewEdit->setValue(false); +        mPriceForListing = MINIMUM_PRICE_FOR_LISTING; +    } +    else +    { +        // Reload data to undo changes to forms +        LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); +    } + +    setInfoLoaded(false); + +    setEditMode(FALSE); +} + +void LLPanelProfileClassified::onSaveClick() +{ +    mCanClose = false; + +    if(!isValidName()) +    { +        notifyInvalidName(); +        return; +    } +    if(isNew() || isNewWithErrors()) +    { +        if(gStatusBar->getBalance() < getPriceForListing()) +        { +            LLNotificationsUtil::add("ClassifiedInsufficientFunds"); +            return; +        } + +        mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>( +            "publish_classified", LLSD()); + +        if(!mPublishFloater) +        { +            mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>( +                "publish_classified", LLSD()); + +            mPublishFloater->setPublishClickedCallback(boost::bind +                (&LLPanelProfileClassified::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(); +    } +} + +/*static*/ +void LLPanelProfileClassified::handleSearchStatResponse(LLUUID classifiedId, LLSD result) +{ +    S32 teleport = result["teleport_clicks"].asInteger(); +    S32 map = result["map_clicks"].asInteger(); +    S32 profile = result["profile_clicks"].asInteger(); +    S32 search_teleport = result["search_teleport_clicks"].asInteger(); +    S32 search_map = result["search_map_clicks"].asInteger(); +    S32 search_profile = result["search_profile_clicks"].asInteger(); + +    LLPanelProfileClassified::setClickThrough(classifiedId, +        teleport + search_teleport, +        map + search_map, +        profile + search_profile, +        true); +} + +void LLPanelProfileClassified::resetData() +{ +    setClassifiedName(LLStringUtil::null); +    setDescription(LLStringUtil::null); +    setClassifiedLocation(LLStringUtil::null); +    setClassifiedId(LLUUID::null); +    setSnapshotId(LLUUID::null); +    setPosGlobal(LLVector3d::zero); +    setParcelId(LLUUID::null); +    setSimName(LLStringUtil::null); +    setFromSearch(false); + +    // reset click stats +    mTeleportClicksOld  = 0; +    mMapClicksOld       = 0; +    mProfileClicksOld   = 0; +    mTeleportClicksNew  = 0; +    mMapClicksNew       = 0; +    mProfileClicksNew   = 0; + +    mPriceForListing = MINIMUM_PRICE_FOR_LISTING; + +    mCategoryText->setValue(LLStringUtil::null); +    mContentTypeText->setValue(LLStringUtil::null); +    getChild<LLUICtrl>("click_through_text")->setValue(LLStringUtil::null); +    mEditButton->setValue(LLStringUtil::null); +    getChild<LLUICtrl>("creation_date")->setValue(LLStringUtil::null); +    mContentTypeM->setVisible(FALSE); +    mContentTypeG->setVisible(FALSE); +} + +void LLPanelProfileClassified::setClassifiedName(const std::string& name) +{ +    mClassifiedNameText->setValue(name); +    mClassifiedNameEdit->setValue(name); +} + +std::string LLPanelProfileClassified::getClassifiedName() +{ +    return mClassifiedNameEdit->getValue().asString(); +} + +void LLPanelProfileClassified::setDescription(const std::string& desc) +{ +    mClassifiedDescText->setValue(desc); +    mClassifiedDescEdit->setValue(desc); + +    updateInfoRect(); +} + +std::string LLPanelProfileClassified::getDescription() +{ +    return mClassifiedDescEdit->getValue().asString(); +} + +void LLPanelProfileClassified::setClassifiedLocation(const std::string& location) +{ +    mLocationText->setValue(location); +    mLocationEdit->setValue(location); +} + +std::string LLPanelProfileClassified::getClassifiedLocation() +{ +    return mLocationText->getValue().asString(); +} + +void LLPanelProfileClassified::setSnapshotId(const LLUUID& id) +{ +    mSnapshotCtrl->setValue(id); +} + +LLUUID LLPanelProfileClassified::getSnapshotId() +{ +    return mSnapshotCtrl->getValue().asUUID(); +} + +// static +void LLPanelProfileClassified::setClickThrough( +    const LLUUID& classified_id, +    S32 teleport, +    S32 map, +    S32 profile, +    bool from_new_table) +{ +    LL_INFOS() << "Click-through data for classified " << classified_id << " arrived: [" +            << teleport << ", " << map << ", " << profile << "] (" +            << (from_new_table ? "new" : "old") << ")" << LL_ENDL; + +    for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter) +    { +        LLPanelProfileClassified* self = *iter; +        if (self->getClassifiedId() != classified_id) +        { +            continue; +        } + +        // *HACK: Skip LLPanelProfileClassified instances: they don't display clicks data. +        // Those instances should not be in the list at all. +        if (typeid(*self) != typeid(LLPanelProfileClassified)) +        { +            continue; +        } + +        LL_INFOS() << "Updating classified info panel" << LL_ENDL; + +        // We need to check to see if the data came from the new stat_table +        // or the old classified table. We also need to cache the data from +        // the two separate sources so as to display the aggregate totals. + +        if (from_new_table) +        { +            self->mTeleportClicksNew = teleport; +            self->mMapClicksNew = map; +            self->mProfileClicksNew = profile; +        } +        else +        { +            self->mTeleportClicksOld = teleport; +            self->mMapClicksOld = map; +            self->mProfileClicksOld = profile; +        } + +        static LLUIString ct_str = self->getString("click_through_text_fmt"); + +        ct_str.setArg("[TELEPORT]", llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld)); +        ct_str.setArg("[MAP]",      llformat("%d", self->mMapClicksNew + self->mMapClicksOld)); +        ct_str.setArg("[PROFILE]",  llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)); + +        self->getChild<LLUICtrl>("click_through_text")->setValue(ct_str.getString()); +        // *HACK: remove this when there is enough room for click stats in the info panel +        self->getChildView("click_through_text")->setToolTip(ct_str.getString()); + +        LL_INFOS() << "teleport: " << llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld) +                << ", map: "    << llformat("%d", self->mMapClicksNew + self->mMapClicksOld) +                << ", profile: " << llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld) +                << LL_ENDL; +    } +} + +// static +std::string LLPanelProfileClassified::createLocationText( +    const std::string& original_name, +    const std::string& sim_name, +    const LLVector3d& pos_global) +{ +    std::string location_text; + +    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 LLPanelProfileClassified::scrollToTop() +{ +    if (mScrollContainer) +    { +        mScrollContainer->goToTop(); +    } +} + +//info +// static +// *TODO: move out of the panel +void LLPanelProfileClassified::sendClickMessage( +        const std::string& type, +        bool from_search, +        const LLUUID& classified_id, +        const LLUUID& parcel_id, +        const LLVector3d& global_pos, +        const std::string& sim_name) +{ +    if (gAgent.getRegion()) +    { +        // You're allowed to click on your own ads to reassure yourself +        // that the system is working. +        LLSD body; +        body["type"]            = type; +        body["from_search"]     = from_search; +        body["classified_id"]   = classified_id; +        body["parcel_id"]       = parcel_id; +        body["dest_pos_global"] = global_pos.getValue(); +        body["region_name"]     = sim_name; + +        std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); +        LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL; +        LL_INFOS() << "body: [" << body << "]" << LL_ENDL; +        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body, +            "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent."); +    } +} + +void LLPanelProfileClassified::sendClickMessage(const std::string& type) +{ +    sendClickMessage( +        type, +        fromSearch(), +        getClassifiedId(), +        getParcelId(), +        getPosGlobal(), +        getSimName()); +} + +void LLPanelProfileClassified::onMapClick() +{ +    sendClickMessage("map"); +    LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); +    LLFloaterReg::showInstance("world_map", "center"); +} + +void LLPanelProfileClassified::onTeleportClick() +{ +    if (!getPosGlobal().isExactlyZero()) +    { +        sendClickMessage("teleport"); +        gAgent.teleportViaLocation(getPosGlobal()); +        LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); +    } +} + +BOOL LLPanelProfileClassified::isDirty() const +{ +    if(mIsNew) +    { +        return TRUE; +    } + +    BOOL dirty = false; +    dirty |= mSnapshotCtrl->isDirty(); +    dirty |= mClassifiedNameEdit->isDirty(); +    dirty |= mClassifiedDescEdit->isDirty(); +    dirty |= mCategoryCombo->isDirty(); +    dirty |= mContentTypeCombo->isDirty(); +    dirty |= mAutoRenewEdit->isDirty(); + +    return dirty; +} + +void LLPanelProfileClassified::resetDirty() +{ +    mSnapshotCtrl->resetDirty(); +    mClassifiedNameEdit->resetDirty(); + +    // call blockUndo() to really reset dirty(and make isDirty work as intended) +    mClassifiedDescEdit->blockUndo(); +    mClassifiedDescEdit->resetDirty(); + +    mCategoryCombo->resetDirty(); +    mContentTypeCombo->resetDirty(); +    mAutoRenewEdit->resetDirty(); +} + +bool LLPanelProfileClassified::canClose() +{ +    return mCanClose; +} + +U32 LLPanelProfileClassified::getContentType() +{ +    return mContentTypeCombo->getCurrentIndex(); +} + +void LLPanelProfileClassified::setContentType(bool mature) +{ +    static std::string mature_str = getString("type_mature"); +    static std::string pg_str = getString("type_pg"); +    mContentTypeText->setValue(mature ? mature_str : pg_str); +    mContentTypeM->setVisible(mature); +    mContentTypeG->setVisible(!mature); +    mContentTypeCombo->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG); +    mContentTypeCombo->resetDirty(); +} + +bool LLPanelProfileClassified::getAutoRenew() +{ +    return mAutoRenewEdit->getValue().asBoolean(); +} + +void LLPanelProfileClassified::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 LLPanelProfileClassified::getCategory() +{ +    return mCategoryCombo->getCurrentIndex(); +} + +void LLPanelProfileClassified::setCategory(U32 category) +{ +    mCategoryCombo->setCurrentByIndex(category); +    mCategoryCombo->resetDirty(); +} + +U8 LLPanelProfileClassified::getFlags() +{ +    bool auto_renew = mAutoRenewEdit->getValue().asBoolean(); + +    bool mature = mContentTypeCombo->getCurrentIndex() == CB_ITEM_MATURE; + +    return pack_classified_flags_request(auto_renew, false, mature, false); +} + +void LLPanelProfileClassified::enableSave(bool enable) +{ +    mSaveButton->setEnabled(enable); +} + +std::string LLPanelProfileClassified::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; +} + +void LLPanelProfileClassified::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 LLPanelProfileClassified::onChange() +{ +    enableSave(isDirty()); +} + +void LLPanelProfileClassified::doSave() +{ +    //*TODO: Fix all of this + +    mCanClose = true; +    sendUpdate(); +    updateTabLabel(getClassifiedName()); +    resetDirty(); + +    if (!canClose()) +    { +        return; +    } + +    if (!isNew() && !isNewWithErrors()) +    { +        setEditMode(FALSE); +        return; +    } + +    updateButtons(); +} + +void LLPanelProfileClassified::onPublishFloaterPublishClicked() +{ +    setPriceForListing(mPublishFloater->getPrice()); + +    doSave(); +} + +std::string LLPanelProfileClassified::getLocationNotice() +{ +    static std::string location_notice = getString("location_notice"); +    return location_notice; +} + +bool LLPanelProfileClassified::isValidName() +{ +    std::string name = getClassifiedName(); +    if (name.empty()) +    { +        return false; +    } +    if (!isalnum(name[0])) +    { +        return false; +    } + +    return true; +} + +void LLPanelProfileClassified::notifyInvalidName() +{ +    std::string name = getClassifiedName(); +    if (name.empty()) +    { +        LLNotificationsUtil::add("BlankClassifiedName"); +    } +    else if (!isalnum(name[0])) +    { +        LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric"); +    } +} + +void LLPanelProfileClassified::onTexturePickerMouseEnter() +{ +    mEditIcon->setVisible(TRUE); +} + +void LLPanelProfileClassified::onTexturePickerMouseLeave() +{ +    mEditIcon->setVisible(FALSE); +} + +void LLPanelProfileClassified::onTextureSelected() +{ +    setSnapshotId(mSnapshotCtrl->getValue().asUUID()); +    onChange(); +} + +void LLPanelProfileClassified::updateTabLabel(const std::string& title) +{ +    setLabel(title); +    LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent()); +    if (parent) +    { +        parent->setCurrentTabName(title); +    } +} + + +//----------------------------------------------------------------------------- +// LLPublishClassifiedFloater +//----------------------------------------------------------------------------- + +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<LLUICtrl>("price_for_listing")->setValue(price); +} + +S32 LLPublishClassifiedFloater::getPrice() +{ +    return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger(); +} + +void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb) +{ +    getChild<LLButton>("publish_btn")->setClickedCallback(cb); +} + +void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb) +{ +    getChild<LLButton>("cancel_btn")->setClickedCallback(cb); +} diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h new file mode 100644 index 0000000000..912819e86b --- /dev/null +++ b/indra/newview/llpanelprofileclassifieds.h @@ -0,0 +1,340 @@ +/** + * @file llpanelprofileclassifieds.h + * @brief LLPanelProfileClassifieds and related class implementations + * + * $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_PANELPROFILECLASSIFIEDS_H +#define LL_PANELPROFILECLASSIFIEDS_H + +#include "llavatarpropertiesprocessor.h" +#include "llclassifiedinfo.h" +#include "llfloater.h" +#include "llpanel.h" +#include "llpanelavatar.h" +#include "llrect.h" +#include "lluuid.h" +#include "v3dmath.h" +#include "llcoros.h" +#include "lleventcoro.h" + +class LLCheckBoxCtrl; +class LLLineEditor; +class LLMediaCtrl; +class LLScrollContainer; +class LLTabContainer; +class LLTextEditor; +class LLTextureCtrl; +class LLUICtrl; + + +class LLPublishClassifiedFloater : public LLFloater +{ +public: +    LLPublishClassifiedFloater(const LLSD& key); +    virtual ~LLPublishClassifiedFloater(); + +    BOOL postBuild() override; + +    void setPrice(S32 price); +    S32 getPrice(); + +    void setPublishClickedCallback(const commit_signal_t::slot_type& cb); +    void setCancelClickedCallback(const commit_signal_t::slot_type& cb); +}; + + +/** +* Panel for displaying Avatar's picks. +*/ +class LLPanelProfileClassifieds +    : public LLPanelProfilePropertiesProcessorTab +{ +public: +    LLPanelProfileClassifieds(); +    /*virtual*/ ~LLPanelProfileClassifieds(); + +    BOOL postBuild() override; + +    void onOpen(const LLSD& key) override; + +    void selectClassified(const LLUUID& classified_id, bool edit); + +    void createClassified(); + +    void processProperties(void* data, EAvatarProcessorType type) override; + +    void resetData() override; + +    void updateButtons(); + +    void updateData() override; + +    bool hasNewClassifieds(); +    bool hasUnsavedChanges() override; +    // commits changes to existing classifieds, but does not publish new classified! +    void commitUnsavedChanges() override; + +private: +    void onClickNewBtn(); +    void onClickDelete(); +    void callbackDeleteClassified(const LLSD& notification, const LLSD& response); + +    bool canAddNewClassified(); +    bool canDeleteClassified(); + +    LLTabContainer* mTabContainer; +    LLUICtrl*       mNoItemsLabel; +    LLButton*       mNewButton; +    LLButton*       mDeleteButton; + +    LLUUID          mClassifiedToSelectOnLoad; +    bool            mClassifiedEditOnLoad; +    bool            mSheduledClassifiedCreation; +}; + + +class LLPanelProfileClassified +    : public LLPanelProfilePropertiesProcessorTab +{ +public: + +    static LLPanelProfileClassified* create(); + +    LLPanelProfileClassified(); + +    /*virtual*/ ~LLPanelProfileClassified(); + +    BOOL postBuild() override; + +    void onOpen(const LLSD& key) override; + +    void processProperties(void* data, EAvatarProcessorType type) override; + +    void setSnapshotId(const LLUUID& id); + +    LLUUID getSnapshotId(); + +    void setClassifiedId(const LLUUID& id) { mClassifiedId = id; } + +    LLUUID& getClassifiedId() { return mClassifiedId; } + +    void setClassifiedName(const std::string& name); + +    std::string getClassifiedName(); + +    void setDescription(const std::string& desc); + +    std::string getDescription(); + +    void setClassifiedLocation(const std::string& location); + +    std::string getClassifiedLocation(); + +    void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } + +    LLVector3d& getPosGlobal() { return mPosGlobal; } + +    void setParcelId(const LLUUID& id) { mParcelId = id; } + +    LLUUID getParcelId() { return mParcelId; } + +    void setSimName(const std::string& sim_name) { mSimName = sim_name; } + +    std::string getSimName() { return mSimName; } + +    void setFromSearch(bool val) { mFromSearch = val; } + +    bool fromSearch() { return mFromSearch; } + +    bool getInfoLoaded() { return mInfoLoaded; } + +    void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; } + +    BOOL isDirty() const override; + +    void resetDirty() override; + +    bool isNew() { return mIsNew; } + +    bool isNewWithErrors() { return mIsNewWithErrors; } + +    bool canClose(); + +    U32 getCategory(); + +    void setCategory(U32 category); + +    U32 getContentType(); + +    void setContentType(bool mature); + +    bool getAutoRenew(); + +    S32 getPriceForListing() { return mPriceForListing; } + +    void setEditMode(BOOL edit_mode); +    bool getEditMode() {return mEditMode;} + +    static void setClickThrough( +        const LLUUID& classified_id, +        S32 teleport, +        S32 map, +        S32 profile, +        bool from_new_table); + +    static void sendClickMessage( +            const std::string& type, +            bool from_search, +            const LLUUID& classified_id, +            const LLUUID& parcel_id, +            const LLVector3d& global_pos, +            const std::string& sim_name); + +    void doSave(); + +protected: + +    void resetData() override; + +    void resetControls(); + +    void updateButtons(); +    void updateInfoRect(); + +    static std::string createLocationText( +        const std::string& original_name, +        const std::string& sim_name, +        const LLVector3d& pos_global); + +    void sendClickMessage(const std::string& type); + +    void scrollToTop(); + +    void onEditClick(); +    void onCancelClick(); +    void onSaveClick(); +    void onMapClick(); +    void onTeleportClick(); + +    void sendUpdate(); + +    void enableSave(bool enable); + +    void enableEditing(bool enable); + +    std::string makeClassifiedName(); + +    void setPriceForListing(S32 price) { mPriceForListing = price; } + +    U8 getFlags(); + +    std::string getLocationNotice(); + +    bool isValidName(); + +    void notifyInvalidName(); + +    void onSetLocationClick(); +    void onChange(); + +    void onPublishFloaterPublishClicked(); + +    void onTexturePickerMouseEnter(); +    void onTexturePickerMouseLeave(); + +    void onTextureSelected(); + +    void updateTabLabel(const std::string& title); + +private: + +    LLTextureCtrl*      mSnapshotCtrl; +    LLUICtrl*           mEditIcon; +    LLUICtrl*           mClassifiedNameText; +    LLTextEditor*       mClassifiedDescText; +    LLLineEditor*       mClassifiedNameEdit; +    LLTextEditor*       mClassifiedDescEdit; +    LLUICtrl*           mLocationText; +    LLUICtrl*           mLocationEdit; +    LLUICtrl*           mCategoryText; +    LLComboBox*         mCategoryCombo; +    LLUICtrl*           mContentTypeText; +    LLIconCtrl*         mContentTypeM; +    LLIconCtrl*         mContentTypeG; +    LLComboBox*         mContentTypeCombo; +    LLUICtrl*           mPriceText; +    LLUICtrl*           mAutoRenewText; +    LLUICtrl*           mAutoRenewEdit; + +    LLButton*           mMapButton; +    LLButton*           mTeleportButton; +    LLButton*           mEditButton; +    LLButton*           mSaveButton; +    LLButton*           mSetLocationButton; +    LLButton*           mCancelButton; + +    LLPanel*            mUtilityBtnCnt; +    LLPanel*            mPublishBtnsCnt; +    LLPanel*            mSaveBtnCnt; +    LLPanel*            mCancelBtnCnt; + +    LLScrollContainer*  mScrollContainer; +    LLView*             mInfoPanel; +    LLPanel*            mInfoScroll; +    LLPanel*            mEditPanel; + + +    LLUUID mClassifiedId; +    LLVector3d mPosGlobal; +    LLUUID mParcelId; +    std::string mSimName; +    bool mFromSearch; +    bool mInfoLoaded; +    bool mEditMode; + +    // Needed for stat tracking +    S32 mTeleportClicksOld; +    S32 mMapClicksOld; +    S32 mProfileClicksOld; +    S32 mTeleportClicksNew; +    S32 mMapClicksNew; +    S32 mProfileClicksNew; + +    S32 mPriceForListing; + +    static void handleSearchStatResponse(LLUUID classifiedId, LLSD result); + +    typedef std::list<LLPanelProfileClassified*> panel_list_t; +    static panel_list_t sAllPanels; + + +    bool mIsNew; +    bool mIsNewWithErrors; +    bool mCanClose; +    bool mEditOnLoad; + +    LLPublishClassifiedFloater* mPublishFloater; +}; + +#endif // LL_PANELPROFILECLASSIFIEDS_H diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp new file mode 100644 index 0000000000..774119f169 --- /dev/null +++ b/indra/newview/llpanelprofilepicks.cpp @@ -0,0 +1,883 @@ +/** + * @file llpanelprofilepicks.cpp + * @brief LLPanelProfilePicks and related class implementations + * + * $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 "llpanelprofilepicks.h" + +#include "llagent.h" +#include "llagentpicksinfo.h" +#include "llavataractions.h" +#include "llavatarpropertiesprocessor.h" +#include "llcommandhandler.h" +#include "lldispatcher.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h" +#include "lllineeditor.h" +#include "llnotificationsutil.h" +#include "llpanelavatar.h" +#include "llpanelprofile.h" +#include "llparcel.h" +#include "llstartup.h" +#include "lltabcontainer.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lltexturectrl.h" +#include "lltrans.h" +#include "llviewergenericmessage.h" // send_generic_message +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks"); +static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick"); + + +class LLPickHandler : public LLCommandHandler +{ +public: + +    // requires trusted browser to trigger +    LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { } + +    bool handle(const LLSD& params, const LLSD& query_map, +        LLMediaCtrl* web) +    { +        if (LLStartUp::getStartupState() < STATE_STARTED) +        { +            return true; +        } + +        if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks")) +        { +            LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +            return true; +        } + +        // handle app/pick/create urls first +        if (params.size() == 1 && params[0].asString() == "create") +        { +            LLAvatarActions::createPick(); +            return true; +        } + +        // then handle the general app/pick/{UUID}/{CMD} urls +        if (params.size() < 2) +        { +            return false; +        } + +        // get the ID for the pick_id +        LLUUID pick_id; +        if (!pick_id.set(params[0], FALSE)) +        { +            return false; +        } + +        // edit the pick in the side tray. +        // need to ask the server for more info first though... +        const std::string verb = params[1].asString(); +        if (verb == "edit") +        { +            LLAvatarActions::showPick(gAgent.getID(), pick_id); +            return true; +        } +        else +        { +            LL_WARNS() << "unknown verb " << verb << LL_ENDL; +            return false; +        } +    } +}; +LLPickHandler gPickHandler; + + +//----------------------------------------------------------------------------- +// LLPanelProfilePicks +//----------------------------------------------------------------------------- + +LLPanelProfilePicks::LLPanelProfilePicks() + : LLPanelProfilePropertiesProcessorTab() + , mPickToSelectOnLoad(LLUUID::null) +{ +} + +LLPanelProfilePicks::~LLPanelProfilePicks() +{ +} + +void LLPanelProfilePicks::onOpen(const LLSD& key) +{ +    LLPanelProfilePropertiesProcessorTab::onOpen(key); + +    resetData(); + +    bool own_profile = getSelfProfile(); +    if (own_profile) +    { +        mNewButton->setVisible(TRUE); +        mNewButton->setEnabled(FALSE); + +        mDeleteButton->setVisible(TRUE); +        mDeleteButton->setEnabled(FALSE); +    } + +    childSetVisible("buttons_header", own_profile); +} + +void LLPanelProfilePicks::createPick(const LLPickData &data) +{ +    if (getIsLoaded()) +    { +        if (canAddNewPick()) +        { +            mNoItemsLabel->setVisible(FALSE); +            LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); +            pick_panel->setAvatarId(getAvatarId()); +            pick_panel->processProperties(&data); +            mTabContainer->addTabPanel( +                LLTabContainer::TabPanelParams(). +                panel(pick_panel). +                select_tab(true). +                label(pick_panel->getPickName())); +            updateButtons(); +        } +        else +        { +            // This means that something doesn't properly check limits +            // before creating a pick +            LL_WARNS() << "failed to add pick" << LL_ENDL; +        } +    } +    else +    { +        mSheduledPickCreation.push_back(data); +    } +} + +void LLPanelProfilePicks::selectPick(const LLUUID& pick_id) +{ +    if (getIsLoaded()) +    { +        for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +        { +            LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +            if (pick_panel) +            { +                if (pick_panel->getPickId() == pick_id) +                { +                    mTabContainer->selectTabPanel(pick_panel); +                    break; +                } +            } +        } +    } +    else +    { +        mPickToSelectOnLoad = pick_id; +    } +} + +BOOL LLPanelProfilePicks::postBuild() +{ +    mTabContainer = getChild<LLTabContainer>("tab_picks"); +    mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text"); +    mNewButton = getChild<LLButton>("new_btn"); +    mDeleteButton = getChild<LLButton>("delete_btn"); + +    mNewButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickNewBtn, this)); +    mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickDelete, this)); + +    return TRUE; +} + +void LLPanelProfilePicks::onClickNewBtn() +{ +    mNoItemsLabel->setVisible(FALSE); +    LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); +    pick_panel->setAvatarId(getAvatarId()); +    mTabContainer->addTabPanel( +        LLTabContainer::TabPanelParams(). +        panel(pick_panel). +        select_tab(true). +        label(pick_panel->getPickName())); +    updateButtons(); +} + +void LLPanelProfilePicks::onClickDelete() +{ +    LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel()); +    if (pick_panel) +    { +        LLUUID pick_id = pick_panel->getPickId(); +        LLSD args; +        args["PICK"] = pick_panel->getPickName(); +        LLSD payload; +        payload["pick_id"] = pick_id; +        payload["tab_idx"] = mTabContainer->getCurrentPanelIndex(); +        LLNotificationsUtil::add("ProfileDeletePick", args, payload, +            boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2)); +    } +} + +void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + +    if (0 == option) +    { +        LLUUID pick_id = notification["payload"]["pick_id"].asUUID(); +        S32 tab_idx = notification["payload"]["tab_idx"].asInteger(); + +        LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (pick_panel && pick_panel->getPickId() == pick_id) +        { +            mTabContainer->removeTabPanel(pick_panel); +        } + +        if (pick_id.notNull()) +        { +            LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id); +        } + +        updateButtons(); +    } +} + +void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type) +{ +    if (APT_PICKS == type) +    { +        LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); +        if (avatar_picks && getAvatarId() == avatar_picks->target_id) +        { +            processProperties(avatar_picks); +        } +    } +} + +void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks) +{ +    LLUUID selected_id = mPickToSelectOnLoad; +    bool has_selection = false; +    if (mPickToSelectOnLoad.isNull()) +    { +        if (mTabContainer->getTabCount() > 0) +        { +            LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel()); +            if (active_pick_panel) +            { +                selected_id = active_pick_panel->getPickId(); +            } +        } +    } + +    mTabContainer->deleteAllTabs(); + +    LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); +    for (; avatar_picks->picks_list.end() != it; ++it) +    { +        LLUUID pick_id = it->first; +        std::string pick_name = it->second; + +        LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); + +        pick_panel->setPickId(pick_id); +        pick_panel->setPickName(pick_name); +        pick_panel->setAvatarId(getAvatarId()); + +        mTabContainer->addTabPanel( +            LLTabContainer::TabPanelParams(). +            panel(pick_panel). +            select_tab(selected_id == pick_id). +            label(pick_name)); + +        if (selected_id == pick_id) +        { +            has_selection = true; +        } +    } + +    while (!mSheduledPickCreation.empty() && canAddNewPick()) +    { +        const LLPickData data = +            mSheduledPickCreation.back(); + +        LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); +        pick_panel->setAvatarId(getAvatarId()); +        pick_panel->processProperties(&data); +        mTabContainer->addTabPanel( +            LLTabContainer::TabPanelParams(). +            panel(pick_panel). +            select_tab(!has_selection). +            label(pick_panel->getPickName())); + +        mSheduledPickCreation.pop_back(); +        has_selection = true; +    } + +    // reset 'do on load' values +    mPickToSelectOnLoad = LLUUID::null; +    mSheduledPickCreation.clear(); + +    if (getSelfProfile()) +    { +        mNoItemsLabel->setValue(LLTrans::getString("NoPicksText")); +    } +    else +    { +        mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText")); +    } + +    bool has_data = mTabContainer->getTabCount() > 0; +    mNoItemsLabel->setVisible(!has_data); +    if (has_data && !has_selection) +    { +        mTabContainer->selectFirstTab(); +    } + +    setLoaded(); +    updateButtons(); +} + +void LLPanelProfilePicks::resetData() +{ +    resetLoading(); +    mTabContainer->deleteAllTabs(); +} + +void LLPanelProfilePicks::updateButtons() +{ +    if (getSelfProfile()) +    { +        mNewButton->setEnabled(canAddNewPick()); +        mDeleteButton->setEnabled(canDeletePick()); +    } +} + +void LLPanelProfilePicks::apply() +{ +    if (getIsLoaded()) +    { +        for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +        { +            LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +            if (pick_panel) +            { +                pick_panel->apply(); +            } +        } +    } +} + +void LLPanelProfilePicks::updateData() +{ +    // Send picks request only once +    LLUUID avatar_id = getAvatarId(); +    if (!getStarted() && avatar_id.notNull()) +    { +        setIsLoading(); + +        LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id); +    } +    if (!getIsLoaded()) +    { +        mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText")); +        mNoItemsLabel->setVisible(TRUE); +    } +} + +bool LLPanelProfilePicks::hasUnsavedChanges() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty())) +        { +            return true; +        } +    } +    return false; +} + +void LLPanelProfilePicks::commitUnsavedChanges() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (pick_panel) +        { +            pick_panel->apply(); +        } +    } +} + +bool LLPanelProfilePicks::canAddNewPick() +{ +    return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() && +        mTabContainer->getTabCount() < LLAgentPicksInfo::getInstance()->getMaxNumberOfPicks()); +} + +bool LLPanelProfilePicks::canDeletePick() +{ +    return (mTabContainer->getTabCount() > 0); +} + + +//----------------------------------------------------------------------------- +// LLPanelProfilePick +//----------------------------------------------------------------------------- + +LLPanelProfilePick::LLPanelProfilePick() + : LLPanelProfilePropertiesProcessorTab() + , LLRemoteParcelInfoObserver() + , mSnapshotCtrl(NULL) + , mPickId(LLUUID::null) + , mParcelId(LLUUID::null) + , mRequestedId(LLUUID::null) + , mLocationChanged(false) + , mNewPick(false) + , mIsEditing(false) +{ +} + +//static +LLPanelProfilePick* LLPanelProfilePick::create() +{ +    LLPanelProfilePick* panel = new LLPanelProfilePick(); +    panel->buildFromFile("panel_profile_pick.xml"); +    return panel; +} + +LLPanelProfilePick::~LLPanelProfilePick() +{ +    if (mParcelId.notNull()) +    { +        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); +    } +} + +void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) +{ +    if (avatar_id.isNull()) +    { +        return; +    } +    LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); + +    // creating new Pick +    if (getPickId().isNull() && getSelfProfile()) +    { +        mNewPick = true; + +        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); +        setPickName(pick_name.empty() ? region_name : pick_name); +        setPickDesc(pick_desc); +        setSnapshotId(snapshot_id); +        setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal())); + +        enableSaveButton(TRUE); +    } +    else +    { +        LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId()); + +        enableSaveButton(FALSE); +    } + +    resetDirty(); + +    if (getSelfProfile()) +    { +        mPickName->setEnabled(TRUE); +        mPickDescription->setEnabled(TRUE); +        mSetCurrentLocationButton->setVisible(TRUE); +    } +    else +    { +        mSnapshotCtrl->setEnabled(FALSE); +    } +} + +BOOL LLPanelProfilePick::postBuild() +{ +    mPickName = getChild<LLLineEditor>("pick_name"); +    mPickDescription = getChild<LLTextEditor>("pick_desc"); +    mSaveButton = getChild<LLButton>("save_changes_btn"); +    mCreateButton = getChild<LLButton>("create_changes_btn"); +    mCancelButton = getChild<LLButton>("cancel_changes_btn"); +    mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn"); + +    mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot"); +    mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this)); + +    childSetAction("teleport_btn", boost::bind(&LLPanelProfilePick::onClickTeleport, this)); +    childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this)); + +    mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); +    mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); +    mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this)); +    mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this)); + +    mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL); +    mPickName->setEnabled(FALSE); + +    mPickDescription->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1)); +    mPickDescription->setFocusReceivedCallback(boost::bind(&LLPanelProfilePick::onDescriptionFocusReceived, this)); + +    getChild<LLUICtrl>("pick_location")->setEnabled(FALSE); + +    return TRUE; +} + +void LLPanelProfilePick::onDescriptionFocusReceived() +{ +    if (!mIsEditing && getSelfProfile()) +    { +        mIsEditing = true; +        mPickDescription->setParseHTML(false); +    } +} + +void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type) +{ +    if (APT_PICK_INFO != type) +    { +        return; +    } + +    LLPickData* pick_info = static_cast<LLPickData*>(data); +    if (!pick_info +        || pick_info->creator_id != getAvatarId() +        || pick_info->pick_id != getPickId()) +    { +        return; +    } + +    processProperties(pick_info); +} + +void LLPanelProfilePick::processProperties(const LLPickData* pick_info) +{ +    mIsEditing = false; +    mPickDescription->setParseHTML(true); +    mParcelId = pick_info->parcel_id; +    setSnapshotId(pick_info->snapshot_id); +    if (!getSelfProfile()) +    { +        mSnapshotCtrl->setEnabled(FALSE); +    } +    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 + +    setLoaded(); +} + +void LLPanelProfilePick::apply() +{ +    if ((mNewPick || getIsLoaded()) && isDirty()) +    { +        sendUpdate(); +    } +} + +void LLPanelProfilePick::setSnapshotId(const LLUUID& id) +{ +    mSnapshotCtrl->setImageAssetID(id); +    mSnapshotCtrl->setValid(TRUE); +} + +void LLPanelProfilePick::setPickName(const std::string& name) +{ +    mPickName->setValue(name); +} + +const std::string LLPanelProfilePick::getPickName() +{ +    return mPickName->getValue().asString(); +} + +void LLPanelProfilePick::setPickDesc(const std::string& desc) +{ +    mPickDescription->setValue(desc); +} + +void LLPanelProfilePick::setPickLocation(const std::string& location) +{ +    getChild<LLUICtrl>("pick_location")->setValue(location); +} + +void LLPanelProfilePick::onClickMap() +{ +    LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); +    LLFloaterReg::showInstance("world_map", "center"); +} + +void LLPanelProfilePick::onClickTeleport() +{ +    if (!getPosGlobal().isExactlyZero()) +    { +        gAgent.teleportViaLocation(getPosGlobal()); +        LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); +    } +} + +void LLPanelProfilePick::enableSaveButton(BOOL enable) +{ +    childSetVisible("save_changes_lp", enable); + +    childSetVisible("save_btn_lp", enable && !mNewPick); +    childSetVisible("create_btn_lp", enable && mNewPick); +    childSetVisible("cancel_btn_lp", enable && !mNewPick); +} + +void LLPanelProfilePick::onSnapshotChanged() +{ +    enableSaveButton(TRUE); +} + +void LLPanelProfilePick::onPickChanged(LLUICtrl* ctrl) +{ +    if (ctrl && ctrl == mPickName) +    { +        updateTabLabel(mPickName->getText()); +    } + +    enableSaveButton(isDirty()); +} + +void LLPanelProfilePick::resetDirty() +{ +    LLPanel::resetDirty(); + +    mPickName->resetDirty(); +    mPickDescription->resetDirty(); +    mSnapshotCtrl->resetDirty(); +    mLocationChanged = false; +} + +BOOL LLPanelProfilePick::isDirty() const +{ +    if (mNewPick +        || LLPanel::isDirty() +        || mLocationChanged +        || mSnapshotCtrl->isDirty() +        || mPickName->isDirty() +        || mPickDescription->isDirty()) +    { +        return TRUE; +    } +    return FALSE; +} + +void LLPanelProfilePick::onClickSetLocation() +{ +    // Save location for later use. +    setPosGlobal(gAgent.getPositionGlobal()); + +    std::string parcel_name, region_name; + +    LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +    if (parcel) +    { +        mParcelId = parcel->getID(); +        parcel_name = parcel->getName(); +    } + +    LLViewerRegion* region = gAgent.getRegion(); +    if (region) +    { +        region_name = region->getName(); +    } + +    setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); + +    mLocationChanged = true; +    enableSaveButton(TRUE); +} + +void LLPanelProfilePick::onClickSave() +{ +    sendUpdate(); + +    mLocationChanged = false; +} + +void LLPanelProfilePick::onClickCancel() +{ +    LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId()); +    mLocationChanged = false; +    enableSaveButton(FALSE); +} + +std::string LLPanelProfilePick::getLocationNotice() +{ +    static const std::string notice = getString("location_notice"); +    return notice; +} + +void LLPanelProfilePick::sendParcelInfoRequest() +{ +    if (mParcelId != mRequestedId) +    { +        if (mRequestedId.notNull()) +        { +            LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); +        } +        LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); +        LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); + +        mRequestedId = mParcelId; +    } +} + +void LLPanelProfilePick::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 LLPanelProfilePick::sendUpdate() +{ +    LLPickData pick_data; + +    // If we don't have a pick id yet, we'll need to generate one, +    // otherwise we'll keep overwriting pick_id 00000 in the database. +    if (getPickId().isNull()) +    { +        getPickId().generate(); +    } + +    pick_data.agent_id = gAgentID; +    pick_data.session_id = gAgent.getSessionID(); +    pick_data.pick_id = getPickId(); +    pick_data.creator_id = gAgentID;; + +    //legacy var  need to be deleted +    pick_data.top_pick = FALSE; +    pick_data.parcel_id = mParcelId; +    pick_data.name = getPickName(); +    pick_data.desc = mPickDescription->getValue().asString(); +    pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); +    pick_data.pos_global = getPosGlobal(); +    pick_data.sort_order = 0; +    pick_data.enabled = TRUE; + +    LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data); + +    if(mNewPick) +    { +        // Assume a successful create pick operation, make new number of picks +        // available immediately. Actual number of picks will be requested in +        // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond. +        LLAgentPicksInfo::getInstance()->incrementNumberOfPicks(); +    } +} + +// static +std::string LLPanelProfilePick::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global) +{ +    std::string location_text(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 LLPanelProfilePick::updateTabLabel(const std::string& title) +{ +    setLabel(title); +    LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent()); +    if (parent) +    { +        parent->setCurrentTabName(title); +    } +} + diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h new file mode 100644 index 0000000000..f84463cc9b --- /dev/null +++ b/indra/newview/llpanelprofilepicks.h @@ -0,0 +1,248 @@ +/** + * @file llpanelprofilepicks.h + * @brief LLPanelProfilePicks and related class definitions + * + * $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_LLPANELPICKS_H +#define LL_LLPANELPICKS_H + +#include "llpanel.h" +#include "lluuid.h" +#include "llavatarpropertiesprocessor.h" +#include "llpanelavatar.h" +#include "llremoteparcelrequest.h" + +class LLTabContainer; +class LLTextureCtrl; +class LLMediaCtrl; +class LLLineEditor; +class LLTextEditor; + + +/** +* Panel for displaying Avatar's picks. +*/ +class LLPanelProfilePicks +    : public LLPanelProfilePropertiesProcessorTab +{ +public: +    LLPanelProfilePicks(); +    /*virtual*/ ~LLPanelProfilePicks(); + +    BOOL postBuild() override; + +    void onOpen(const LLSD& key) override; + +    void createPick(const LLPickData &data); +    void selectPick(const LLUUID& pick_id); + +    void processProperties(void* data, EAvatarProcessorType type) override; +    void processProperties(const LLAvatarPicks* avatar_picks); + +    void resetData() override; + +    void updateButtons(); + +    /** +     * Saves changes. +     */ +    virtual void apply(); + +    /** +     * Sends update data request to server. +     */ +    void updateData() override; + +    bool hasUnsavedChanges() override; +    void commitUnsavedChanges() override; + +    friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + +private: +    void onClickNewBtn(); +    void onClickDelete(); +    void callbackDeletePick(const LLSD& notification, const LLSD& response); + +    bool canAddNewPick(); +    bool canDeletePick(); + +    LLTabContainer* mTabContainer; +    LLUICtrl*       mNoItemsLabel; +    LLButton*       mNewButton; +    LLButton*       mDeleteButton; + +    LLUUID          mPickToSelectOnLoad; +    std::list<LLPickData> mSheduledPickCreation; +}; + + +class LLPanelProfilePick +    : public LLPanelProfilePropertiesProcessorTab +    , public LLRemoteParcelInfoObserver +{ +public: + +    // Creates new panel +    static LLPanelProfilePick* create(); + +    LLPanelProfilePick(); + +    /*virtual*/ ~LLPanelProfilePick(); + +    BOOL postBuild() override; + +    void setAvatarId(const LLUUID& avatar_id) override; + +    void setPickId(const LLUUID& id) { mPickId = id; } +    virtual LLUUID& getPickId() { return mPickId; } + +    virtual void setPickName(const std::string& name); +    const std::string getPickName(); + +    void processProperties(void* data, EAvatarProcessorType type) override; +    void processProperties(const LLPickData* pick_data); + +    /** +     * Returns true if any of Pick properties was changed by user. +     */ +    BOOL isDirty() const override; + +    /** +     * Saves changes. +     */ +    virtual void apply(); + +    void updateTabLabel(const std::string& title); + +    //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing +    void processParcelInfo(const LLParcelData& parcel_data) override; +    void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } +    void setErrorStatus(S32 status, const std::string& reason) override {}; + +protected: + +    /** +     * Sends remote parcel info request to resolve parcel name from its ID. +     */ +    void sendParcelInfoRequest(); + +    /** +    * "Location text" is actually the owner name, the original +    * name that owner gave the parcel, and the location. +    */ +    static std::string createLocationText( +        const std::string& owner_name, +        const std::string& original_name, +        const std::string& sim_name, +        const LLVector3d& pos_global); + +    /** +     * Sets snapshot id. +     * +     * Will mark snapshot control as valid if id is not null. +     * Will mark snapshot control as invalid if id is null. If null id is a valid value, +     * you have to manually mark snapshot is valid. +     */ +    virtual void setSnapshotId(const LLUUID& id); +    virtual void setPickDesc(const std::string& desc); +    virtual void setPickLocation(const std::string& location); + +    virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } +    virtual LLVector3d& getPosGlobal() { return mPosGlobal; } + +    /** +     * Callback for "Map" button, opens Map +     */ +    void onClickMap(); + +    /** +     * Callback for "Teleport" button, teleports user to Pick location. +     */ +    void onClickTeleport(); + +    /** +     * Enables/disables "Save" button +     */ +    void enableSaveButton(BOOL enable); + +    /** +     * Called when snapshot image changes. +     */ +    void onSnapshotChanged(); + +    /** +     * Callback for Pick snapshot, name and description changed event. +     */ +    void onPickChanged(LLUICtrl* ctrl); + +    /** +     * Resets panel and all cantrols to unedited state +     */ +    void resetDirty() override; + +    /** +     * Callback for "Set Location" button click +     */ +    void onClickSetLocation(); + +    /** +     * Callback for "Save" and "Create" button click +     */ +    void onClickSave(); + +    /** +     * Callback for "Save" button click +     */ +    void onClickCancel(); + +    std::string getLocationNotice(); + +    /** +     * Sends Pick properties to server. +     */ +    void sendUpdate(); + +protected: + +    LLTextureCtrl*      mSnapshotCtrl; +    LLLineEditor*       mPickName; +    LLTextEditor*       mPickDescription; +    LLButton*           mSetCurrentLocationButton; +    LLButton*           mSaveButton; +    LLButton*           mCreateButton; +    LLButton*           mCancelButton; + +    LLVector3d mPosGlobal; +    LLUUID mParcelId; +    LLUUID mPickId; +    LLUUID mRequestedId; + +    bool mLocationChanged; +    bool mNewPick; +    bool                mIsEditing; + +    void onDescriptionFocusReceived(); +}; + +#endif // LL_LLPANELPICKS_H diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 5b02609a53..39f4c7485b 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -595,13 +595,6 @@ void LLPanelVolume::refresh()  		mRootObject = NULL;  	} -	BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; - -	getChildView("Light FOV")->setVisible( visible); -	getChildView("Light Focus")->setVisible( visible); -	getChildView("Light Ambiance")->setVisible( visible); -	getChildView("light texture control")->setVisible( visible); -  	bool enable_mesh = false;  	LLSD sim_features; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 94d20828ec..9b60d1ae2f 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -38,154 +38,11 @@  #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally  #endif -// See EXT-4301. -/** - * class LLAvalineUpdater - observe the list of voice participants in session and check - *  presence of Avaline Callers among them. - * - * LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation: - *	- whether Avaline caller presence among participants; - *	- whether watched Avaline caller still exists in voice channel. - * Both validations have callbacks which will notify subscriber if any of event occur. - * - * @see findAvalineCaller() - * @see checkIfAvalineCallersExist() - */ -class LLAvalineUpdater : public LLVoiceClientParticipantObserver -{ -public: -	typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t; - -	LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb) -		: mAvalineFoundCallback(found_cb) -		, mAvalineRemovedCallback(removed_cb) -	{ -		LLVoiceClient::getInstance()->addObserver(this); -	} -	~LLAvalineUpdater() -	{ -		if (LLVoiceClient::instanceExists()) -		{ -			LLVoiceClient::getInstance()->removeObserver(this); -		} -	} - -	/** -	 * Adds UUID of Avaline caller to watch. -	 * -	 * @see checkIfAvalineCallersExist(). -	 */ -	void watchAvalineCaller(const LLUUID& avaline_caller_id) -	{ -		mAvalineCallers.insert(avaline_caller_id); -	} - -	void onParticipantsChanged() -	{ -		uuid_set_t participant_uuids; -		LLVoiceClient::getInstance()->getParticipantList(participant_uuids); - - -		// check whether Avaline caller exists among voice participants -		// and notify Participant List -		findAvalineCaller(participant_uuids); - -		// check whether watched Avaline callers still present among voice participant -		// and remove if absents. -		checkIfAvalineCallersExist(participant_uuids); -	} - -private: -	typedef std::set<LLUUID> uuid_set_t; - -	/** -	 * Finds Avaline callers among voice participants and calls mAvalineFoundCallback. -	 * -	 * When Avatar is in group call with Avaline caller and then ends call Avaline caller stays -	 * in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again -	 * Avaline caller is added to voice channel AFTER Avatar is connected to group call. -	 * But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information -	 * if a speaker is Avaline caller. -	 * -	 * In this case this speaker is created as avatar and will be recreated when it appears in -	 * Avatar's Voice session. -	 * -	 * @see LLParticipantList::onAvalineCallerFound() -	 */ -	void findAvalineCaller(const uuid_set_t& participant_uuids) -	{ -		uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end(); - -		for(; it != it_end; ++it) -		{ -			const LLUUID& participant_id = *it; -			if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id)) -			{ -				LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL; - -				if (mAvalineFoundCallback) -				{ -					mAvalineFoundCallback(participant_id); -				} -			} -		} -	} - -	/** -	 * Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback. -	 * -	 * The problem is when Avaline caller ends a call it is removed from Voice Client session but -	 * still exists in LLSpeakerMgr. Server does not send such information. -	 * This method implements a HUCK to notify subscribers that watched Avaline callers by class -	 * are not anymore in the call. -	 * -	 * @see LLParticipantList::onAvalineCallerRemoved() -	 */ -	void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids) -	{ -		uuid_set_t::iterator it = mAvalineCallers.begin(); -		uuid_set_t::const_iterator participants_it_end = participant_uuids.end(); - -		while (it != mAvalineCallers.end()) -		{ -			const LLUUID participant_id = *it; -			LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL; -			bool not_found = participant_uuids.find(participant_id) == participants_it_end; -			if (not_found) -			{ -				LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL; - -				// notify Participant List -				if (mAvalineRemovedCallback) -				{ -					mAvalineRemovedCallback(participant_id); -				} - -				// remove from the watch list -				mAvalineCallers.erase(it++); -			} -			else -			{ -				++it; -			} -		} -	} - -	process_avaline_callback_t mAvalineFoundCallback; -	process_avaline_callback_t mAvalineRemovedCallback; - -	uuid_set_t mAvalineCallers; -}; -  LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :  	LLConversationItemSession(data_source->getSessionID(), root_view_model),  	mSpeakerMgr(data_source),  	mValidateSpeakerCallback(NULL)  { - -	mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1), -										   boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1)); -  	mSpeakerAddListener = new SpeakerAddListener(*this);  	mSpeakerRemoveListener = new SpeakerRemoveListener(*this);  	mSpeakerClearListener = new SpeakerClearListener(*this); @@ -243,32 +100,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewMode  LLParticipantList::~LLParticipantList()  { -	delete mAvalineUpdater; -} - -/* -  Seems this method is not necessary after onAvalineCallerRemoved was implemented; - -  It does nothing because list item is always created with correct class type for Avaline caller. -  For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client -  session. -  This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call. - -  Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself. -  Asked in EXT-4301. -*/ -void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id) -{ -	removeParticipant(participant_id); -	// re-add avaline caller with a correct class instance. -	addAvatarIDExceptAgent(participant_id); -} - -void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id) -{ -	LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL; - -	mSpeakerMgr->removeAvalineSpeaker(participant_id);  }  void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb) @@ -386,7 +217,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)  		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);  		// Create a participant view model instance  		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel); -		mAvalineUpdater->watchAvalineCaller(avatar_id);  	}  	// *TODO : Need to update the online/offline status of the participant diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 3a3ae76604..14c0a63692 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -32,7 +32,6 @@  class LLSpeakerMgr;  class LLUICtrl; -class LLAvalineUpdater;  class LLParticipantList : public LLConversationItemSession  { @@ -133,8 +132,6 @@ protected:  	};  private: -	void onAvalineCallerFound(const LLUUID& participant_id); -	void onAvalineCallerRemoved(const LLUUID& participant_id);  	/**  	 * Adjusts passed participant to work properly. @@ -156,7 +153,6 @@ private:  	LLPointer<SpeakerMuteListener>				mSpeakerMuteListener;  	validate_speaker_callback_t mValidateSpeakerCallback; -	LLAvalineUpdater* mAvalineUpdater;  };  #endif // LL_PARTICIPANTLIST_H diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 9bc77393dc..9bf771db8a 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -163,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications()  	LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;  } -void LLPersistentNotificationStorage::initialize() +void LLPersistentNotificationStorage::reset()  { -	std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml"; -	setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name)); -	setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); +    std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml"; +    setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name)); +    setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); +} +void LLPersistentNotificationStorage::initialize() +{ +    reset();  	LLNotifications::instance().getChannel("Persistent")->  		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));  } diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index 1fb4487286..335d85aaf6 100644 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -52,6 +52,7 @@ public:  	void saveNotifications();  	void loadNotifications(); +    void reset();  protected: diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 230def5362..3fd4f51559 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -866,7 +866,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)      buffer[nread] = '\0';      fclose(file); -    mEditor->setText(LLStringExplicit(buffer)); +    std::string text = std::string(buffer); +    LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); + +    mEditor->setText(text);      delete[] buffer;      return true; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index a32dc8beda..d677a996c1 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -601,7 +601,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)  	buffer[nread] = '\0';  	fclose(file); -	mEditor->setText(LLStringExplicit(buffer)); +    std::string text = std::string(buffer); +    LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); + +    mEditor->setText(text);  	delete[] buffer;  	return true; diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index cd7b93aba7..10177c8023 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -367,7 +367,10 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)  	// add space for dimensions and aspect ratio  	S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD; - +	if (getChild<LLLayoutPanel>("buttons_panel")->getVisible()) +	{ +		info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight(); +	}  	LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);  	client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);  	client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ; @@ -412,6 +415,16 @@ void LLPreviewTexture::openToSave()  	mPreviewToSave = TRUE;  } +void LLPreviewTexture::hideCtrlButtons() +{ +	getChildView("desc txt")->setVisible(false); +	getChildView("desc")->setVisible(false); +	getChild<LLLayoutStack>("preview_stack")->collapsePanel(getChild<LLLayoutPanel>("buttons_panel"), true); +	getChild<LLLayoutPanel>("buttons_panel")->setVisible(false); +	getChild<LLComboBox>("combo_aspect_ratio")->setCurrentByIndex(0); //unconstrained +	reshape(getRect().getWidth(), getRect().getHeight()); +} +  // static  void LLPreviewTexture::onFileLoadedForSave(BOOL success,   					   LLViewerFetchedTexture *src_vi, diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index 9b6a843875..16db51332e 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -67,6 +67,8 @@ public:  	static void			onSaveAsBtn(void* data); +	void				hideCtrlButtons(); +  	/*virtual*/ void setObjectID(const LLUUID& object_id);  protected:  	void				init(); diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp index 83b0c4f1bf..0faf6bf889 100644 --- a/indra/newview/llrecentpeople.cpp +++ b/indra/newview/llrecentpeople.cpp @@ -42,14 +42,6 @@ bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata)  	if (is_not_group_id)  	{ -		// For each avaline call the id of caller is different even if -		// the phone number is the same. -		// To avoid duplication of avaline list items in the recent list -		// of panel People, deleting id's with similar phone number. -		const LLUUID& caller_id = getIDByPhoneNumber(userdata); -		if (caller_id.notNull()) -			mPeople.erase(caller_id); -  		//[] instead of insert to replace existing id->llsd["date"] with new date value  		mPeople[id] = userdata;  		mChangedSignal(); @@ -90,35 +82,6 @@ const LLSD& LLRecentPeople::getData(const LLUUID& id) const  	return no_data;  } -bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const -{ -	recent_people_t::const_iterator it = mPeople.find(id); - -	if (it != mPeople.end()) -	{ -		const LLSD& user = it->second;		 -		return user["avaline_call"].asBoolean(); -	} - -	return false; -} - -const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata) -{ -	if (!userdata["avaline_call"].asBoolean()) -		return LLUUID::null; - -	for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it) -	{ -		const LLSD& user_info = it->second; -		 -		if (user_info["call_number"].asString() == userdata["call_number"].asString()) -			return it->first; -	} -	 -	return LLUUID::null; -} -  // virtual  bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  { diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index 18b669ff4f..1b322f2c0a 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -62,9 +62,7 @@ public:  	 * @param id avatar to add.  	 *  	 * @param userdata additional information about last interaction party. -	 *				   For example when last interaction party is not an avatar -	 *				   but an avaline caller, additional info (such as phone -	 *				   number, session id and etc.) should be added. +	 *				   For example session id can be added.  	 *  	 * @return false if the avatar is in the list already, true otherwise  	 */ @@ -97,13 +95,6 @@ public:  	const LLSD& getData(const LLUUID& id) const;  	/** -	 * Checks whether specific participant is an avaline caller -	 * -	 * @param id identifier of specific participant -	 */ -	bool isAvalineCaller(const LLUUID& id) const; - -	/**  	 * Set callback to be called when the list changed.  	 *   	 * Multiple callbacks can be set. @@ -122,8 +113,6 @@ public:  private: -	const LLUUID& getIDByPhoneNumber(const LLSD& userdata); -  	typedef std::map<LLUUID, LLSD> recent_people_t;  	recent_people_t		mPeople;  	signal_t			mChangedSignal; diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index 055ccd5818..f4ace52faa 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,      if (!status)      { -        observer->setErrorStatus(status.getStatus(), status.getMessage()); +        std::string message = status.getMessage(); +        if (message.empty()) +        { +            message = status.toString(); +        } +        observer->setErrorStatus(status.getStatus(), message);      }      else       { diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h index e033cae3ab..31f11eb8ef 100644 --- a/indra/newview/llsearchableui.h +++ b/indra/newview/llsearchableui.h @@ -41,9 +41,9 @@ namespace ll  		struct PanelData;  		struct TabContainerData; -		typedef boost::shared_ptr< SearchableItem > SearchableItemPtr; -		typedef boost::shared_ptr< PanelData > PanelDataPtr; -		typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr; +		typedef std::shared_ptr< SearchableItem > SearchableItemPtr; +		typedef std::shared_ptr< PanelData > PanelDataPtr; +		typedef std::shared_ptr< TabContainerData > TabContainerDataPtr;  		typedef std::vector< TabContainerData > tTabContainerDataList;  		typedef std::vector< SearchableItemPtr > tSearchableItemList; @@ -55,7 +55,7 @@ namespace ll  			LLView const *mView;  			ll::ui::SearchableControl const *mCtrl; -			std::vector< boost::shared_ptr< SearchableItem >  > mChildren; +			std::vector< std::shared_ptr< SearchableItem >  > mChildren;  			virtual ~SearchableItem(); @@ -68,8 +68,8 @@ namespace ll  			LLPanel const *mPanel;  			std::string mLabel; -			std::vector< boost::shared_ptr< SearchableItem > > mChildren; -			std::vector< boost::shared_ptr< PanelData > > mChildPanel; +			std::vector< std::shared_ptr< SearchableItem > > mChildren; +			std::vector< std::shared_ptr< PanelData > > mChildPanel;  			virtual ~PanelData(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 82a165cb35..86f7d2bf25 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -310,14 +310,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)  {      struct f : public LLSelectedNodeFunctor      { +        f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {} +        bool mAvatarOverridesPersist; +        LLSelectMgr* mManager;          virtual bool apply(LLSelectNode* node)          { +            if (mAvatarOverridesPersist) +            { +                LLViewerObject* object = node->getObject(); +                if (object && !object->getParent()) +                { +                    LLVOAvatar* avatar = object->asAvatar(); +                    if (avatar) +                    { +                        mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object)); +                    } +                } +            }              node->mLastPositionLocal.setVec(0, 0, 0);              node->mLastRotation = LLQuaternion();              node->mLastScale.setVec(0, 0, 0);              return true;          } -    } func; +    } func(mAllowSelectAvatar, this);      selected_handle->applyToNodes(&func);  } @@ -351,6 +366,93 @@ void LLSelectMgr::overrideObjectUpdates()  	getSelection()->applyToNodes(&func);  } +void LLSelectMgr::resetAvatarOverrides() +{ +    mAvatarOverridesMap.clear(); +} + +void LLSelectMgr::overrideAvatarUpdates() +{ +    if (mAvatarOverridesMap.size() == 0) +    { +        return; +    } + +    if (!mAllowSelectAvatar || !gFloaterTools) +    { +        resetAvatarOverrides(); +        return; +    } + +    if (!gFloaterTools->getVisible() && getSelection()->isEmpty()) +    { +        // when user switches selection, floater is invisible and selection is empty +        LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset(); +        if (toolset->isShowFloaterTools() +            && toolset->isToolSelected(0)) // Pie tool +        { +            resetAvatarOverrides(); +            return; +        } +    } + +    // remove selected avatars from this list, +    // but set object overrides to make sure avatar won't snap back  +    struct f : public LLSelectedNodeFunctor +    { +        f(LLSelectMgr* p) : mManager(p) {} +        LLSelectMgr* mManager; +        virtual bool apply(LLSelectNode* selectNode) +        { +            LLViewerObject* object = selectNode->getObject(); +            if (object && !object->getParent()) +            { +                LLVOAvatar* avatar = object->asAvatar(); +                if (avatar) +                { +                    uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID()); +                    if (iter != mManager->mAvatarOverridesMap.end()) +                    { +                        if (selectNode->mLastPositionLocal.isExactlyZero()) +                        { +                            selectNode->mLastPositionLocal = iter->second.mLastPositionLocal; +                        } +                        if (selectNode->mLastRotation == LLQuaternion()) +                        { +                            selectNode->mLastRotation = iter->second.mLastRotation; +                        } +                        mManager->mAvatarOverridesMap.erase(iter); +                    } +                } +            } +            return true; +        } +    } func(this); +    getSelection()->applyToNodes(&func); + +    // Override avatar positions +    uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin(); +    while (it != mAvatarOverridesMap.end()) +    { +        if (it->second.mObject->isDead()) +        { +            it = mAvatarOverridesMap.erase(it); +        } +        else +        { +            if (!it->second.mLastPositionLocal.isExactlyZero()) +            { +                it->second.mObject->setPosition(it->second.mLastPositionLocal); +            } +            if (it->second.mLastRotation != LLQuaternion()) +            { +                it->second.mObject->setRotation(it->second.mLastRotation); +            } +            it++; +        } +    } +} +  //-----------------------------------------------------------------------------  // Select just the object, not any other group members.  //----------------------------------------------------------------------------- @@ -886,7 +988,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to  		// Can't select yourself  		if (objectp->mID == gAgentID -			&& !LLSelectMgr::getInstance()->mAllowSelectAvatar) +			&& !mAllowSelectAvatar)  		{  			continue;  		} @@ -6281,6 +6383,24 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)  LLSelectNode::~LLSelectNode()  { +    LLSelectMgr *manager = LLSelectMgr::getInstance(); +    if (manager->mAllowSelectAvatar +        && (!mLastPositionLocal.isExactlyZero() +            || mLastRotation != LLQuaternion())) +    { +        LLViewerObject* object = getObject(); //isDead() check +        if (object && !object->getParent()) +        { +            LLVOAvatar* avatar = object->asAvatar(); +            if (avatar) +            { +                // Avatar was moved and needs to stay that way +                manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object)); +            } +        } +    } + +  	delete mPermissions;  	mPermissions = NULL;  } @@ -6788,6 +6908,10 @@ void LLSelectMgr::updateSelectionCenter()  	const F32 MOVE_SELECTION_THRESHOLD = 1.f;		//  Movement threshold in meters for updating selection  													//  center (tractor beam) +    // override any avatar updates received +    // Works only if avatar was repositioned +    // and edit floater is visible +    overrideAvatarUpdates();  	//override any object updates received  	//for selected objects  	overrideObjectUpdates(); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index ce0316e610..199141fc32 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -467,6 +467,30 @@ public:  	void resetObjectOverrides(LLObjectSelectionHandle selected_handle);  	void overrideObjectUpdates(); +    void resetAvatarOverrides(); +    void overrideAvatarUpdates(); + +    struct AvatarPositionOverride +    { +        AvatarPositionOverride(); +        AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) : +            mLastPositionLocal(vec), +            mLastRotation(quat), +            mObject(obj) +        { +        } +        LLVector3 mLastPositionLocal; +        LLQuaternion mLastRotation; +        LLPointer<LLViewerObject> mObject; +    }; + +    // Avatar overrides should persist even after selection +    // was removed as long as edit floater is up +    typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t; +    uuid_av_override_map_t mAvatarOverridesMap; +public: + +  	// Returns the previous value of mForceSelection  	BOOL setForceSelection(BOOL force); diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index abb936c3e5..ea671a130e 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -534,7 +534,7 @@ void LLSpeakerMgr::updateSpeakerList()  			}  			else if (mSpeakers.size() == 0)  			{ -				// For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list +				// For all other session type (ad-hoc, P2P), we use the initial participants targets list  				for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)  				{  					// Add buddies if they are on line, add any other avatar. diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index d1dbf72fe9..ed795b5155 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -245,14 +245,6 @@ public:  	bool isSpeakerToBeRemoved(const LLUUID& speaker_id);  	/** -	 * Removes avaline speaker. -	 * -	 * This is a HACK due to server does not send information that Avaline caller ends call. -	 * It can be removed when server is updated. See EXT-4301 for details -	 */ -	bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); } - -	/**  	 * Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant.  	 *  	 * Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937 diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 5beb12057c..dc48eaa823 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -97,6 +97,7 @@  #include "llfloateravatarpicker.h"  #include "llcallbacklist.h"  #include "llcallingcard.h" +#include "llclassifiedinfo.h"  #include "llconsole.h"  #include "llcontainerview.h"  #include "llconversationlog.h" @@ -124,8 +125,6 @@  #include "llpanellogin.h"  #include "llmutelist.h"  #include "llavatarpropertiesprocessor.h" -#include "llpanelclassified.h" -#include "llpanelpick.h"  #include "llpanelgrouplandmoney.h"  #include "llpanelgroupnotices.h"  #include "llparcel.h" @@ -194,6 +193,7 @@  #include "llavatariconctrl.h"  #include "llvoicechannel.h"  #include "llpathfindingmanager.h" +#include "llremoteparcelrequest.h"  #include "lllogin.h"  #include "llevents.h" @@ -255,6 +255,7 @@ static bool mLoginStatePastUI = false;  static bool mBenefitsSuccessfullyInit = false;  const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds +const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances  std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));  std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); @@ -927,6 +928,12 @@ bool idle_startup()  			LLPersistentNotificationStorage::initParamSingleton();  			LLDoNotDisturbNotificationStorage::initParamSingleton();  		} +        else +        { +            // reinitialize paths in case user switched grids or accounts +            LLPersistentNotificationStorage::getInstance()->reset(); +            LLDoNotDisturbNotificationStorage::getInstance()->reset(); +        }  		// Set PerAccountSettingsFile to the default value.  		std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")); @@ -1388,10 +1395,21 @@ bool idle_startup()  		{  			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );  		} +        else if (regionp->capabilitiesError()) +        { +            // Try to connect despite capabilities' error state +            LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); +        }  		else  		{  			U32 num_retries = regionp->getNumSeedCapRetries(); -			if (num_retries > 0) +            if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN) +            { +                // Region will keep trying to get capabilities, +                // but for now continue as if caps were granted +                LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); +            } +			else if (num_retries > 0)  			{  				LLStringUtil::format_map_t args;  				args["[NUMBER]"] = llformat("%d", num_retries + 1); @@ -2389,6 +2407,11 @@ void login_callback(S32 option, void *userdata)  void show_release_notes_if_required()  {      static bool release_notes_shown = false; +    // We happen to know that instantiating LLVersionInfo implicitly +    // instantiates the LLEventMailDrop named "relnotes", which we (might) use +    // below. If viewer release notes stop working, might be because that +    // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been +    // instantiated.      if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion)          && LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds          && gSavedSettings.getBOOL("UpdaterShowReleaseNotes") @@ -2656,7 +2679,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)  	msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply);  	msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply); -//	msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);  	msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);  	msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);  	msg->setHandlerFunc("ScriptDialog", process_script_dialog); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 51ee5b6157..0ce82a1297 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -48,6 +48,7 @@  #include "llui.h"  #include "llviewerinventory.h"  #include "llpermissions.h" +#include "llpreviewtexture.h"  #include "llsaleinfo.h"  #include "llassetstorage.h"  #include "lltextbox.h" @@ -1215,6 +1216,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	mNeedsRawImageData( FALSE ),  	mValid( TRUE ),  	mShowLoadingPlaceholder( TRUE ), +	mOpenTexPreview(false),  	mImageAssetID(p.image_id),  	mDefaultImageAssetID(p.default_image_id),  	mDefaultImageName(p.default_image_name), @@ -1471,12 +1473,31 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)  	if (!handled && mBorder->parentPointInView(x, y))  	{ -		showPicker(FALSE); -		//grab textures first... -		LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE)); -		//...then start full inventory fetch. -		LLInventoryModelBackgroundFetch::instance().start(); -		handled = TRUE; +		if (!mOpenTexPreview) +		{ +			showPicker(FALSE); +			//grab textures first... +			LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE)); +			//...then start full inventory fetch. +			LLInventoryModelBackgroundFetch::instance().start(); +			handled = TRUE; +		} +		else +		{ +			if (getImageAssetID().notNull()) +			{ +				LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue()); +				if (preview_texture && !preview_texture->isDependent()) +				{ +					LLFloater* root_floater = gFloaterView->getParentFloater(this); +					if (root_floater) +					{ +						root_floater->addDependentFloater(preview_texture); +						preview_texture->hideCtrlButtons(); +					} +				} +			} +		}  	}  	return handled; diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 3769f43737..fbb38c4464 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -169,6 +169,8 @@ public:  	void			setBlankImageAssetID( const LLUUID& id )	{ mBlankImageAssetID = id; }  	const LLUUID&	getBlankImageAssetID() const { return mBlankImageAssetID; } +	void			setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; } +  	void			setCaption(const std::string& caption);  	void			setCanApplyImmediately(BOOL b); @@ -248,6 +250,8 @@ private:  	BOOL					 	mShowLoadingPlaceholder;  	std::string				 	mLoadingPlaceholderString;  	S32						 	mLabelWidth; +	bool						mOpenTexPreview; +	BOOL						mBakeTextureEnabled;  };  ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index bc8171b2fc..be54cb2f96 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -739,7 +739,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  				glh::matrix4f proj = get_current_projection();  				glh::matrix4f mod = get_current_modelview();  				glViewport(0,0,512,512); -				LLVOAvatar::updateFreezeCounter() ;  				LLVOAvatar::updateImpostors(); diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp new file mode 100644 index 0000000000..cec08c4f15 --- /dev/null +++ b/indra/newview/llviewerdisplayname.cpp @@ -0,0 +1,226 @@ +/**  + * @file llviewerdisplayname.cpp + * @brief Wrapper for display name functionality + * + * $LicenseInfo:firstyear=2010&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 "llviewerdisplayname.h" + +// viewer includes +#include "llagent.h" +#include "llfloaterprofile.h" +#include "llfloaterreg.h" +#include "llviewerregion.h" +#include "llvoavatar.h" + +// library includes +#include "llavatarnamecache.h" +#include "llhttpnode.h" +#include "llnotificationsutil.h" +#include "llui.h"					// getLanguage() + +namespace LLViewerDisplayName +{ +	// Fired when viewer receives server response to display name change +	set_name_signal_t sSetDisplayNameSignal; + +	// Fired when there is a change in the agent's name +	name_changed_signal_t sNameChangedSignal; + +	void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)  +	{  +		sNameChangedSignal.connect(cb);  +	} + +	void doNothing() { } +} + +void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot) +{ +	// TODO: simple validation here + +	LLViewerRegion* region = gAgent.getRegion(); +	llassert(region); +	std::string cap_url = region->getCapability("SetDisplayName"); +	if (cap_url.empty()) +	{ +		// this server does not support display names, report error +		slot(false, "unsupported", LLSD()); +		return; +	} + +	// People API requires both the old and new value to change a variable. +	// Our display name will be in cache before the viewer's UI is available +	// to request a change, so we can use direct lookup without callback. +	LLAvatarName av_name; +	if (!LLAvatarNameCache::get( gAgent.getID(), &av_name)) +	{ +		slot(false, "name unavailable", LLSD()); +		return; +	} + +	// People API expects array of [ "old value", "new value" ] +	LLSD change_array = LLSD::emptyArray(); +	change_array.append(av_name.getDisplayName()); +	change_array.append(display_name); +	 +	LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL; + +	// Record our caller for when the server sends back a reply +	sSetDisplayNameSignal.connect(slot); +	 +	// POST the requested change.  The sim will not send a response back to +	// this request directly, rather it will send a separate message after it +	// communicates with the back-end. +	LLSD body; +	body["display_name"] = change_array; +    LLCoros::instance().launch("LLViewerDisplayName::SetDisplayNameCoro", +            boost::bind(&LLViewerDisplayName::setDisplayNameCoro, cap_url, body)); +} + +void LLViewerDisplayName::setDisplayNameCoro(const std::string& cap_url, const LLSD& body) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("SetDisplayNameCoro", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + +    // People API can return localized error messages.  Indicate our +    // language preference via header. +    httpHeaders->append(HTTP_OUT_HEADER_ACCEPT_LANGUAGE, LLUI::getLanguage()); + +    LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpHeaders); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    if (!status) +    { +        LL_WARNS() << "Unable to set display name. Status: " << status.toString() << LL_ENDL; +        LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD()); +        LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); +    } +} + +class LLSetDisplayNameReply : public LLHTTPNode +{ +	LOG_CLASS(LLSetDisplayNameReply); +public: +	/*virtual*/ void post( +		LLHTTPNode::ResponsePtr response, +		const LLSD& context, +		const LLSD& input) const +	{ +		LLSD body = input["body"]; + +		S32 status = body["status"].asInteger(); +		bool success = (status == HTTP_OK); +		std::string reason = body["reason"].asString(); +		LLSD content = body["content"]; + +		LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL; + +		// If viewer's concept of display name is out-of-date, the set request +		// will fail with 409 Conflict.  If that happens, fetch up-to-date +		// name information. +		if (status == HTTP_CONFLICT) +		{ +			LLUUID agent_id = gAgent.getID(); +			// Flush stale data +			LLAvatarNameCache::getInstance()->erase( agent_id ); +			// Queue request for new data: nothing to do on callback though... +			// Note: no need to disconnect the callback as it never gets out of scope +            LLAvatarNameCache::getInstance()->get(agent_id, boost::bind(&LLViewerDisplayName::doNothing)); +			// Kill name tag, as it is wrong +			LLVOAvatar::invalidateNameTag( agent_id ); +		} + +		// inform caller of result +		LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content); +		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); +	} +}; + + +class LLDisplayNameUpdate : public LLHTTPNode +{ +	/*virtual*/ void post( +		LLHTTPNode::ResponsePtr response, +		const LLSD& context, +		const LLSD& input) const +	{ +		LLSD body = input["body"]; +		LLUUID agent_id = body["agent_id"]; +		std::string old_display_name = body["old_display_name"]; +		// By convention this record is called "agent" in the People API +		LLSD name_data = body["agent"]; + +		// Inject the new name data into cache +		LLAvatarName av_name; +		av_name.fromLLSD( name_data ); + +		LL_INFOS() << "name-update now " << LLDate::now() +			<< " next_update " << LLDate(av_name.mNextUpdate) +			<< LL_ENDL; + +		// Name expiration time may be provided in headers, or we may use a +		// default value +		// *TODO: get actual headers out of ResponsePtr +		//LLSD headers = response->mHeaders; +		LLSD headers; +		av_name.mExpires =  +            LLAvatarNameCache::getInstance()->nameExpirationFromHeaders(headers); + +        LLAvatarNameCache::getInstance()->insert(agent_id, av_name); + +		// force name tag to update +		LLVOAvatar::invalidateNameTag(agent_id); + +		LLSD args; +		args["OLD_NAME"] = old_display_name; +		args["SLID"] = av_name.getUserName(); +		args["NEW_NAME"] = av_name.getDisplayName(); +		LLNotificationsUtil::add("DisplayNameUpdate", args); +		if (agent_id == gAgent.getID()) +		{ +			LLViewerDisplayName::sNameChangedSignal(); +		} + +        LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id))); +        if (profile_floater) +        { +            profile_floater->refreshName(); +        } +	} +}; + +LLHTTPRegistration<LLSetDisplayNameReply> +    gHTTPRegistrationMessageSetDisplayNameReply( +		"/message/SetDisplayNameReply"); + +LLHTTPRegistration<LLDisplayNameUpdate> +    gHTTPRegistrationMessageDisplayNameUpdate( +		"/message/DisplayNameUpdate"); diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h new file mode 100644 index 0000000000..337aaa68b6 --- /dev/null +++ b/indra/newview/llviewerdisplayname.h @@ -0,0 +1,55 @@ +/**  + * @file llviewerdisplayname.h + * @brief Wrapper for display name functionality + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LLVIEWERDISPLAYNAME_H +#define LLVIEWERDISPLAYNAME_H + +#include <boost/signals2.hpp> + +class LLSD; +class LLUUID; + +namespace LLViewerDisplayName +{ +	typedef boost::signals2::signal< +		void (bool success, const std::string& reason, const LLSD& content)> +			set_name_signal_t; +	typedef set_name_signal_t::slot_type set_name_slot_t; +	 +	typedef boost::signals2::signal<void (void)> name_changed_signal_t; +	typedef name_changed_signal_t::slot_type name_changed_slot_t; + +	// Sends an update to the server to change a display name +	// and call back when done.  May not succeed due to service +	// unavailable or name not available. +	void set(const std::string& display_name, const set_name_slot_t& slot); + +    void setDisplayNameCoro(const std::string& cap_url, const LLSD& body); + +	void addNameChangedCallback(const name_changed_signal_t::slot_type& cb); +} + +#endif // LLVIEWERDISPLAYNAME_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index f23e4ab9b3..da9f83905a 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -57,11 +57,13 @@  #include "llfloatercamera.h"  #include "llfloatercamerapresets.h"  #include "llfloaterchatvoicevolume.h" +#include "llfloaterclassified.h"  #include "llfloaterconversationlog.h"  #include "llfloaterconversationpreview.h"  #include "llfloatercreatelandmark.h"  #include "llfloaterdeleteprefpreset.h"  #include "llfloaterdestinations.h" +#include "llfloaterdisplayname.h"  #include "llfloatereditextdaycycle.h"  #include "llfloaterenvironmentadjust.h"  #include "llfloaterexperienceprofile.h" @@ -113,6 +115,7 @@  #include "llfloaterpreferencesgraphicsadvanced.h"  #include "llfloaterpreferenceviewadvanced.h"  #include "llfloaterpreviewtrash.h" +#include "llfloaterprofile.h"  #include "llfloaterproperties.h"  #include "llfloaterregiondebugconsole.h"  #include "llfloaterregioninfo.h" @@ -143,7 +146,6 @@  #include "llfloateruipreview.h"  #include "llfloatervoiceeffect.h"  #include "llfloaterwebcontent.h" -#include "llfloaterwebprofile.h"  #include "llfloatervoicevolume.h"  #include "llfloaterwhitelistentry.h"  #include "llfloaterwindowsize.h" @@ -157,7 +159,7 @@  #include "llmoveview.h"  #include "llfloaterimnearbychat.h"  #include "llpanelblockedlist.h" -#include "llpanelclassified.h" +#include "llpanelprofileclassifieds.h"  #include "llpreviewanim.h"  #include "llpreviewgesture.h"  #include "llpreviewnotecard.h" @@ -230,6 +232,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);  	LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);  	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater); +    LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);  	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);  	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);  	LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>); @@ -277,6 +280,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLInspectRemoteObjectUtil::registerFloater();  	LLFloaterVoiceVolumeUtil::registerFloater();  	LLNotificationsUI::registerFloater(); +	LLFloaterDisplayNameUtil::registerFloater();  	LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);  	LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>); @@ -323,7 +327,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);  	LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);  	LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>); -	LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);  	LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);  	LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");  	LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>); @@ -370,8 +373,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);      LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);      LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); -	LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); -	LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); +    LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);  	LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);  	LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 812f804ea9..636909e6f2 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -48,7 +48,7 @@  #include "llmutelist.h"  #include "llnotifications.h"  #include "llnotificationsutil.h" -#include "llpanelprofile.h" +#include "llavataractions.h"  #include "llparcel.h"  #include "llpluginclassmedia.h"  #include "llurldispatcher.h" @@ -3194,7 +3194,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const  	}  	// If this media's class is not supposed to be shown, unload -	if (!shouldShowBasedOnClass()) +	if (!shouldShowBasedOnClass() || isObscured())  	{  		return true;  	} @@ -3881,6 +3881,26 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const  //////////////////////////////////////////////////////////////////////////////////////////  // +bool LLViewerMediaImpl::isObscured() const +{ +    if (getUsedInUI() || isParcelMedia()) return false; + +    LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +    if (!agent_parcel) +    { +        return false; +    } +     +    if (agent_parcel->getObscureMOAP() && !isInAgentParcel()) +    { +        return true; +    } + +    return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +//  bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const  {  	bool result = false; diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 806692929a..b95cfd4c68 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -423,6 +423,7 @@ public:  private:  	bool isAutoPlayable() const;  	bool shouldShowBasedOnClass() const; +	bool isObscured() const;  	static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);  	static bool isObjectInAgentParcel(LLVOVolume *obj); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2a8a6e9848..3c64edf2db 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -33,10 +33,11 @@  #include "llviewermenu.h"   // linden library includes -#include "llavatarnamecache.h"	// IDEVO +#include "llavatarnamecache.h"  // IDEVO (I Are Not Men!) +#include "llcombobox.h" +#include "llcoros.h"  #include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h" -#include "llcombobox.h"  #include "llinventorypanel.h"  #include "llnotifications.h"  #include "llnotificationsutil.h" @@ -93,6 +94,7 @@  #include "llmarketplacefunctions.h"  #include "llmenuoptionpathfindingrebakenavmesh.h"  #include "llmoveview.h" +#include "llnavigationbar.h"  #include "llparcel.h"  #include "llrootview.h"  #include "llsceneview.h" @@ -2407,6 +2409,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t  		return true;  	}  }; +  class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -2416,6 +2419,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t  	}  }; +class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        LLCoros::instance().launch( +            "AdvancedForceErrorBadMemoryAccessCoro", +            [](){ +                // Wait for one mainloop() iteration, letting the enclosing +                // handleEvent() method return. +                llcoro::suspend(); +                force_error_bad_memory_access(NULL); +            }); +        return true; +    } +}; +  class LLAdvancedForceErrorInfiniteLoop : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -2434,6 +2453,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t  	}  }; +class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        LLCoros::instance().launch( +            "AdvancedForceErrorSoftwareExceptionCoro", +            [](){ +                // Wait for one mainloop() iteration, letting the enclosing +                // handleEvent() method return. +                llcoro::suspend(); +                force_error_software_exception(NULL); +            }); +        return true; +    } +}; +  class LLAdvancedForceErrorDriverCrash : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -3637,6 +3672,11 @@ bool my_profile_visible()  	return floaterp && floaterp->isInVisibleChain();  } +bool picks_tab_visible() +{ +    return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID); +} +  bool enable_freeze_eject(const LLSD& avatar_id)  {  	// Use avatar_id if available, otherwise default to right-click avatar @@ -5362,12 +5402,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t  	{  		bool returnValue = false; -		if (LLPathfindingManager::getInstance() != NULL) -		{ -			LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); -			returnValue = (rebakeInstance->canRebakeRegion() && -				(rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); -		} +        if (LLNavigationBar::instanceExists()) +        { +            returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable(); +        }  		return returnValue;  	}  }; @@ -6330,6 +6368,29 @@ class LLAvatarToggleMyProfile : public view_listener_t  	}  }; +class LLAvatarTogglePicks : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID()); +        if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome())) +        { +            instance->setMinimized(FALSE); +            instance->setFocus(TRUE); +            LLAvatarActions::showPicks(gAgent.getID()); +        } +        else if (picks_tab_visible()) +        { +            instance->closeFloater(); +        } +        else +        { +            LLAvatarActions::showPicks(gAgent.getID()); +        } +        return true; +    } +}; +  class LLAvatarToggleSearch : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -6800,6 +6861,15 @@ class LLShowAgentProfile : public view_listener_t  	}  }; +class LLShowAgentProfilePicks : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        LLAvatarActions::showPicks(gAgent.getID()); +        return true; +    } +}; +  class LLToggleAgentProfile : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -9447,8 +9517,10 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");  	view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");  	view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); +	view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");  	view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");  	view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException"); +	view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");  	view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");      view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");      view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); @@ -9523,12 +9595,14 @@ void initialize_menus()  	enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));  	view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");  	view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile"); +	view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");  	view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");  	view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");  	view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");  	view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");  	view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");  	enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible)); +    enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));  	commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL"))); @@ -9605,6 +9679,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");  	view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");  	view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile"); +    view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");  	view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");  	view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");      view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index be80d0bc0a..5f82f1c44f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3334,13 +3334,6 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  	// trigger a control event.  	U32 control_flags = gAgent.getControlFlags(); -    // Rotation into both directions should cancel out -    U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG; -    if ((control_flags & mask) == mask) -    { -        control_flags &= ~mask; -    } -  	MASK	key_mask = gKeyboard->currentMask(TRUE);  	if (key_mask & MASK_ALT || key_mask & MASK_CONTROL) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index a95636ff23..aad6c14b4d 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -356,6 +356,13 @@ LLViewerObject::~LLViewerObject()  		mPartSourcep = NULL;  	} +    if (mText) +    { +        // something recovered LLHUDText when object was already dead +        mText->markDead(); +        mText = NULL; +    } +  	// Delete memory associated with extra parameters.  	std::map<U16, ExtraParameter*>::iterator iter;  	for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) @@ -2457,11 +2464,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  		needs_refresh = needs_refresh || child->mUserSelected;  	} +    static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE);  	if (needs_refresh)  	{  		LLSelectMgr::getInstance()->updateSelectionCenter();  		dialog_refresh_all(); -	}  +	} +    else if (allow_select_avatar && asAvatar()) +    { +        // Override any avatar position updates received +        // Works only if avatar was repositioned using build +        // tools and build floater is visible +        LLSelectMgr::getInstance()->overrideAvatarUpdates(); +    }  	// Mark update time as approx. now, with the ping delay. diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 55e2386d10..e930b58111 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -571,7 +571,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		if(update_cache)  		{ -			objectp = regionp->updateCacheEntry(local_id, objectp, update_type); +            //update object cache if the object receives a full-update or terse update +			objectp = regionp->updateCacheEntry(local_id, objectp);  		}  		// This looks like it will break if the local_id of the object doesn't change diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index e69b0347f8..f58eac2ed9 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1553,6 +1553,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use      BOOL    region_allow_environment_override = true;      S32     parcel_environment_version = 0;      BOOL	agent_parcel_update = false; // updating previous(existing) agent parcel +    U32     extended_flags = 0; //obscure MOAP      S32		other_clean_time = 0; @@ -1642,6 +1643,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use          msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);      } +    if (msg->getNumberOfBlocks(_PREHASH_ParcelExtendedFlags)) +    { +        msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags); +     } +      if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock))      {          msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version); @@ -1698,6 +1704,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use          parcel->setParcelEnvironmentVersion(cur_parcel_environment_version);          parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override); +        parcel->setObscureMOAP((bool)extended_flags); +  		parcel->unpackMessage(msg);  		if (parcel == parcel_mgr.mAgentParcel) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b282a2b90c..fb55c5e816 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -95,8 +95,6 @@  // The server only keeps our pending agent info for 60 seconds.  // We want to allow for seed cap retry, but its not useful after that 60 seconds. -// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up. -const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;  // Even though we gave up on login, keep trying for caps after we are logged in:  const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;  const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000; @@ -178,7 +176,6 @@ public:          mCompositionp(NULL),          mEventPoll(NULL),          mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), -        mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),          mSeedCapAttempts(0),          mHttpResponderID(0),          mLastCameraUpdate(0), @@ -231,7 +228,6 @@ public:  	LLEventPoll* mEventPoll;  	S32 mSeedCapMaxAttempts; -	S32 mSeedCapMaxAttemptsBeforeLogin;  	S32 mSeedCapAttempts;  	S32 mHttpResponderID; @@ -266,14 +262,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)              return;          } -        LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton! -        if (!world_inst) +        if (!LLWorld::instanceExists())          {              LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL;              return;          } -        regionp = world_inst->getRegionFromHandle(regionHandle); +        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);          if (!regionp) //region was removed          {              LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL; @@ -287,19 +282,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)          if (url.empty())          {              LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL; +            regionp->setCapabilitiesError();              return; // this error condition is not recoverable.          }          // record that we just entered a new region          newRegionEntry(*regionp); -        // After a few attempts, continue login.  But keep trying to get the caps: -        if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin && -            STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) -        { -            LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); -        } -          if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts)          {              // *TODO: Give a user pop-up about this error? @@ -321,7 +310,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)          regionp = NULL;          impl = NULL; -        world_inst = NULL;          result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);          if (STATE_WORLD_INIT > LLStartUp::getStartupState()) @@ -332,17 +320,36 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)          if (LLApp::isExiting() || gDisconnected)          { +            LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL;              return;          } -        world_inst = LLWorld::getInstance(); -        if (!world_inst) +        if (!result.isMap() || result.has("error")) +        { +            LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL; +            // setup for retry. +            continue; +        } + +        LLSD httpResults = result["http_result"]; +        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); +        if (!status) +        { +            LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL; +            // setup for retry. +            continue; +        } + +        // remove the http_result from the llsd +        result.erase("http_result"); + +        if (!LLWorld::instanceExists())          {              LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;              return;          } -        regionp = world_inst->getRegionFromHandle(regionHandle); +        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);          if (!regionp) //region was removed          {              LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL; @@ -351,7 +358,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)          impl = regionp->getRegionImplNC(); -        ++impl->mSeedCapAttempts; +        ++(impl->mSeedCapAttempts);          if (id != impl->mHttpResponderID) // region is no longer referring to this request          { @@ -360,25 +367,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)              continue;          } -        if (!result.isMap() || result.has("error")) -        { -            LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL; -            // setup for retry. -            continue; -        } - -        LLSD httpResults = result["http_result"]; -        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); -        if (!status) -        { -            LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL; -            // setup for retry. -            continue; -        } - -        // remove the http_result from the llsd -        result.erase("http_result"); -          LLSD::map_const_iterator iter;          for (iter = result.beginMap(); iter != result.endMap(); ++iter)          { @@ -396,11 +384,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)  														 << " region name " << regionp->getName() << LL_ENDL;          regionp->setCapabilitiesReceived(true); -        if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) -        { -            LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); -        } -          break;      }       while (true); @@ -444,6 +427,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)          if (url.empty())          {              LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL; +            if (regionp->getCapability("Seed").empty()) +            { +                // initial attempt failed to get this cap as well +                regionp->setCapabilitiesError(); +            }              break; // this error condition is not recoverable.          } @@ -645,7 +633,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mCacheLoaded(FALSE),  	mCacheDirty(FALSE),  	mReleaseNotesRequested(FALSE), -	mCapabilitiesReceived(false), +	mCapabilitiesState(CAPABILITIES_STATE_INIT),  	mSimulatorFeaturesReceived(false),  	mBitsReceived(0.f),  	mPacketsReceived(0.f), @@ -1820,13 +1808,8 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)  //update object cache if the object receives a full-update or terse update  //update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL -LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type) +LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp)  { -	if(objectp && update_type != (U32)OUT_TERSE_IMPROVED) -	{ -		return objectp; //no need to access cache -	} -  	LLVOCacheEntry* entry = getCacheEntry(local_id);  	if (!entry)  	{ @@ -1838,11 +1821,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o  		objectp = addNewObject(entry);  	} -	//remove from cache if terse update -	if(update_type == (U32)OUT_TERSE_IMPROVED) -	{ -		killCacheEntry(entry, true); -	} +    //remove from cache. +    killCacheEntry(entry, true);  	return objectp;  } @@ -2302,6 +2282,11 @@ void LLViewerRegion::requestSimulatorFeatures()          std::string coroname =              LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",                                         boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle())); + +        // requestSimulatorFeatures can be called from other coros, +        // launch() acts like a suspend() +        // Make sure we are still good to do +        LLCoros::checkStop();          LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;      } @@ -3002,6 +2987,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("AcceptFriendship");  	capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!  	capabilityNames.append("AgentPreferences"); +    capabilityNames.append("AgentProfile");  	capabilityNames.append("AgentState");  	capabilityNames.append("AttachmentResources");  	capabilityNames.append("AvatarPickerSearch"); @@ -3096,6 +3082,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("UpdateScriptTask");      capabilityNames.append("UpdateSettingsAgentInventory");      capabilityNames.append("UpdateSettingsTaskInventory"); +    capabilityNames.append("UploadAgentProfileImage");  	capabilityNames.append("UploadBakedTexture");      capabilityNames.append("UserInfo");  	capabilityNames.append("ViewerAsset");  @@ -3121,6 +3108,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)          std::string coroname =              LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",              boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle())); + +        // setSeedCapability can be called from other coros, +        // launch() acts like a suspend() +        // Make sure we are still good to do +        LLCoros::checkStop(); +  		return;      } @@ -3134,6 +3127,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)          LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",          boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle())); +    // setSeedCapability can be called from other coros, +    // launch() acts like a suspend() +    // Make sure we are still good to do +    LLCoros::checkStop(); +      LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;  } @@ -3255,12 +3253,17 @@ bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const  bool LLViewerRegion::capabilitiesReceived() const  { -	return mCapabilitiesReceived; +	return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED; +} + +bool LLViewerRegion::capabilitiesError() const +{ +    return mCapabilitiesState == CAPABILITIES_STATE_ERROR;  }  void LLViewerRegion::setCapabilitiesReceived(bool received)  { -	mCapabilitiesReceived = received; +	mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;  	// Tell interested parties that we've received capabilities,  	// so that they can safely use getCapability(). @@ -3275,6 +3278,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)  	}  } +void LLViewerRegion::setCapabilitiesError() +{ +    mCapabilitiesState = CAPABILITIES_STATE_ERROR; +} +  boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)  {  	return mCapabilitiesReceivedSignal.connect(cb); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index fcbf56c81f..d0fa9fea01 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -268,7 +268,9 @@ public:  	// has region received its final (not seed) capability list?  	bool capabilitiesReceived() const; +    bool capabilitiesError() const;  	void setCapabilitiesReceived(bool received); +	void setCapabilitiesError();  	boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);  	static bool isSpecialCapabilityName(const std::string &name); @@ -352,7 +354,7 @@ public:  	void requestCacheMisses();  	void addCacheMissFull(const U32 local_id);  	//update object cache if the object receives a full-update or terse update -	LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type); +	LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);  	void findOrphans(U32 parent_id);  	void clearCachedVisibleObjects();  	void dumpCache(); @@ -527,12 +529,20 @@ private:  	BOOL									mCacheLoaded;  	BOOL                                    mCacheDirty;  	BOOL	mAlive;					// can become false if circuit disconnects -	BOOL	mCapabilitiesReceived;  	BOOL	mSimulatorFeaturesReceived;  	BOOL    mReleaseNotesRequested;  	BOOL    mDead;  //if true, this region is in the process of deleting.  	BOOL    mPaused; //pause processing the objects in the region +    typedef enum +    { +        CAPABILITIES_STATE_INIT = 0, +        CAPABILITIES_STATE_ERROR, +        CAPABILITIES_STATE_RECEIVED +    } eCababilitiesState; + +    eCababilitiesState	mCapabilitiesState; +  	typedef std::map<U32, std::vector<U32> > orphan_list_t;  	orphan_list_t mOrphanMap; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index ffe3baa351..a420de98f5 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -506,6 +506,7 @@ void send_viewer_stats(bool include_preferences)  	system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();  	system["os"] = LLOSInfo::instance().getOSStringSimple();  	system["cpu"] = gSysCPU.getCPUString(); +    system["cpu_sse"] = gSysCPU.getSSEVersions();  	system["address_size"] = ADDRESS_SIZE;  	system["os_bitness"] = LLOSInfo::instance().getOSBitness();  	unsigned char MACAddress[MAC_ADDRESS_BYTES]; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index ed948e506a..2270d86384 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1262,7 +1262,8 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  										 const std::string& out_filename, -										 const U8 codec) +										 const U8 codec, +										 const S32 max_image_dimentions)  {	      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	// Load the image @@ -1291,7 +1292,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  		return FALSE;  	}  	// Convert to j2c (JPEG2000) and save the file locally -	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);	 +	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);  	if (compressedImage.isNull())  	{  		image->setLastError("Couldn't convert the image to jpeg2000."); @@ -1316,10 +1317,10 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  }  // note: modifies the argument raw_image!!!! -LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image) +LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions)  { -    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +	LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; +	raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);  	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();  	if (gSavedSettings.getBOOL("LosslessJ2CUpload") && diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index fead2e52b2..6fb0d3552e 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -92,8 +92,11 @@ class LLViewerTextureList  	friend class LLLocalBitmap;  public: -	static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); -	static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image); +    static BOOL createUploadFile(const std::string& filename, +                                 const std::string& out_filename, +                                 const U8 codec, +                                 const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +	static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);  	static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );  	static void receiveImageHeader(LLMessageSystem *msg, void **user_data);  	static void receiveImagePacket(LLMessageSystem *msg, void **user_data); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 119859a4ac..5ce46b143a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -772,6 +772,12 @@ public:  				ypos += y_inc;  				addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); +                ypos += y_inc; + +                addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f))); +                ypos += y_inc; + +                addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));  				ypos += y_inc;  			} @@ -1567,9 +1573,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)  	showCursor();  	getWindow()->setMouseClipping(FALSE); -	// If losing focus while keys are down, reset them. +	// If losing focus while keys are down, handle them as +    // an 'up' to correctly release states, then reset states  	if (gKeyboard)  	{ +        gKeyboard->resetKeyDownAndHandle();  		gKeyboard->resetKeys();  	} diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 038cc12c41..b66a6958fe 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @File llvoavatar.cpp   * @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject   * @@ -183,8 +183,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32;  // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB  const S32 SWITCH_TO_BAKED_DISCARD = 5; -const F32 FOOT_COLLIDE_FUDGE = 0.04f; -  const F32 HOVER_EFFECT_MAX_SPEED = 3.f;  const F32 HOVER_EFFECT_STRENGTH = 0.f;  const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f; @@ -585,7 +583,6 @@ private:  //-----------------------------------------------------------------------------  // Static Data  //----------------------------------------------------------------------------- -S32 LLVOAvatar::sFreezeCounter = 0;  U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors  bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)  F32 LLVOAvatar::sRenderDistance = 256.f; @@ -610,7 +607,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0;  BOOL LLVOAvatar::sDebugInvisible = FALSE;  BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;  BOOL LLVOAvatar::sShowAnimationDebug = FALSE; -BOOL LLVOAvatar::sShowFootPlane = FALSE;  BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;  F32 LLVOAvatar::sLODFactor = 1.f;  F32 LLVOAvatar::sPhysicsLODFactor = 1.f; @@ -779,6 +775,13 @@ std::string LLVOAvatar::avString() const  void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)  { +    if (gDisconnected) +    { +        // If we disconected, these values are likely to be invalid and +        // avString() might crash due to a dead sAvatarDictionary +        return; +    } +  	LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()  					   << "sec ]"  					   << avString()  @@ -4107,8 +4110,7 @@ void LLVOAvatar::computeUpdatePeriod()          && (!isSelf() || visually_muted)          && !isUIAvatar()          && (sLimitNonImpostors || visually_muted) -        && !mNeedsAnimUpdate  -        && !sFreezeCounter) +        && !mNeedsAnimUpdate)  	{  		const LLVector4a* ext = mDrawable->getSpatialExtents();  		LLVector4a size; @@ -5081,42 +5083,6 @@ U32 LLVOAvatar::renderSkinned()  		return num_indices;  	} -	// render collision normal -	// *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due -	// to DEV-14477.  the code is left here to aid in tracking down the cause -	// of the crash in the future. -brad -	if (sShowFootPlane && mDrawable.notNull()) -	{ -		LLVector3 slaved_pos = mDrawable->getPositionAgent(); -		LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]); -		F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW]; -		LLVector3 collide_point = slaved_pos; -		collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE); - -		gGL.begin(LLRender::LINES); -		{ -			F32 SQUARE_SIZE = 0.2f; -			gGL.color4f(1.f, 0.f, 0.f, 1.f); -			 -			gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); -			gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - -			gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); -			gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); -			 -			gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); -			gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); -			 -			gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); -			gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); -			 -			gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); -			gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); - -		} -		gGL.end(); -		gGL.flush(); -	}  	//--------------------------------------------------------------------  	// render all geometry attached to the skeleton  	//-------------------------------------------------------------------- @@ -7243,6 +7209,14 @@ LLViewerJoint*	LLVOAvatar::getViewerJoint(S32 idx)  }  //----------------------------------------------------------------------------- +// hideHair() +//----------------------------------------------------------------------------- +void LLVOAvatar::hideHair() +{ +    mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE); +} + +//-----------------------------------------------------------------------------  // hideSkirt()  //-----------------------------------------------------------------------------  void LLVOAvatar::hideSkirt() @@ -10247,23 +10221,6 @@ LLHost LLVOAvatar::getObjectHost() const  	}  } -//static -void LLVOAvatar::updateFreezeCounter(S32 counter) -{ -	if(counter) -	{ -		sFreezeCounter = counter; -	} -	else if(sFreezeCounter > 0) -	{ -		sFreezeCounter--; -	} -	else -	{ -		sFreezeCounter = 0; -	} -} -  BOOL LLVOAvatar::updateLOD()  {      if (mDrawable.isNull()) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 8a47895cf7..e9c3d48a78 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -327,7 +327,6 @@ public:  	static bool		sLimitNonImpostors; // use impostors for far away avatars  	static F32		sRenderDistance; // distance at which avatars will render.  	static BOOL		sShowAnimationDebug; // show animation debug info -	static BOOL		sShowFootPlane;	// show foot collision plane reported by server  	static BOOL		sShowCollisionVolumes;	// show skeletal collision volumes  	static BOOL		sVisibleInFirstPerson;  	static S32		sNumLODChangesThisFrame; @@ -619,14 +618,6 @@ private:  	BOOL		mCulled;  	//-------------------------------------------------------------------- -	// Freeze counter -	//-------------------------------------------------------------------- -public: -	static void updateFreezeCounter(S32 counter = 0); -private: -	static S32  sFreezeCounter; - -	//--------------------------------------------------------------------  	// Constants  	//--------------------------------------------------------------------  public: @@ -809,6 +800,7 @@ public:  	void 			parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);  	void 			processAvatarAppearance(LLMessageSystem* mesgsys);      void            applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params); +    void 			hideHair();  	void 			hideSkirt();  	void			startAppearanceAnimation(); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index f971554c9d..b0eb8d962c 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -770,8 +770,6 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string  		mReceivedCall(FALSE)  {  	// make sure URI reflects encoded version of other user's agent id -	// *NOTE: in case of Avaline call generated SIP URL will be incorrect. -	// But it will be overridden in LLVoiceChannelP2P::setSessionHandle() called when agent accepts call  	setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));  } @@ -911,8 +909,6 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s  	else  	{  		LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL; -		// In the case of an incoming AvaLine call, the generated URI will be different from the -		// original one. This is because the P2P URI is based on avatar UUID but Avaline is not.  		// See LLVoiceClient::sessionAddedEvent()  		setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));  	} @@ -947,22 +943,5 @@ void LLVoiceChannelP2P::setState(EState state)  void LLVoiceChannelP2P::addToTheRecentPeopleList()  { -	bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType(); -	 -	if (avaline_call) -	{ -		LLSD call_data; -		std::string call_number = LLVoiceChannel::getSessionName(); -		 -		call_data["avaline_call"]	= true; -		call_data["session_id"]		= mSessionID; -		call_data["call_number"]	= call_number; -		call_data["date"]			= LLDate::now(); -		 -		LLRecentPeople::instance().add(mOtherUserID, call_data); -	} -	else -	{ -		LLRecentPeople::instance().add(mOtherUserID); -	} +	LLRecentPeople::instance().add(mOtherUserID);  } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index e2bd1a39c7..d8b8b8749f 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -200,6 +200,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()  		LLVoiceVersionInfo result;  		result.serverVersion = std::string();  		result.serverType = std::string(); +		result.mBuildVersion = std::string();  		return result;  	}  } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index cf527a4464..246883b611 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -95,6 +95,7 @@ struct LLVoiceVersionInfo  {  	std::string serverType;  	std::string serverVersion; +	std::string mBuildVersion;  };  ////////////////////////////////// diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 19036a3f77..735bb4ad94 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -690,6 +690,10 @@ void LLVivoxVoiceClient::voiceControlCoro()          // surviving longer than LLVivoxVoiceClient          voiceControlStateMachine(state);      } +    catch (const LLCoros::Stop&) +    { +        LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL; +    }      catch (const LLContinueError&)      {          LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient"); @@ -4572,6 +4576,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st  	}  } +void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id) +{ +	// We don't generally need to process this. However, one occurence is when we first connect, and so it is the +	// earliest opportunity to learn what we're connected to. +	if (statusCode) +	{ +		LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode << +			"statusString: " << statusString << LL_ENDL; +		return; +	} +	if (build_id.empty()) +	{ +		return; +	} +	mVoiceVersion.mBuildVersion = build_id; +} +  void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)  {  	LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL; @@ -4758,7 +4779,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions()          if ((*it).expired())          {              LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL; -            mSession.erase(it++); +            it = mSession.erase(it);          }          else              ++it; @@ -6815,7 +6836,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id)  		if (list_iter->second == id)  		{  			LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL; -			mVoiceFontList.erase(list_iter++); +            list_iter = mVoiceFontList.erase(list_iter);  			mVoiceFontListDirty = true;  		}  		else @@ -7554,6 +7575,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)  			connectorHandle = string;  		else if (!stricmp("VersionID", tag))  			versionID = string; +		else if (!stricmp("Version", tag)) +			mBuildID = string;  		else if (!stricmp("AccountHandle", tag))  			accountHandle = string;  		else if (!stricmp("State", tag)) @@ -7856,7 +7879,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag)  			// We don't need to process this, but we also shouldn't warn on it, since that confuses people.  		}  		else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent")) -		{	// Yet another ignored event +		{ +			LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID);  		}  		else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent"))  		{ diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index cf30a4e86a..ebc3a62c35 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -465,6 +465,7 @@ protected:  	void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType);  	void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);  	void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy); +	void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id);  	void auxAudioPropertiesEvent(F32 energy);  	void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);  	void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType); @@ -969,6 +970,7 @@ protected:  	std::string		actionString;  	std::string		connectorHandle;  	std::string		versionID; +	std::string		mBuildID;  	std::string		accountHandle;  	std::string		sessionHandle;  	std::string		sessionGroupHandle; diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index ff899fe895..3cc82621c4 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -36,7 +36,7 @@  #include "llstring.h"  // newview -#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions +#include "llavataractions.h" // for getProfileURL()  #include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals  #include "llcorehttputil.h" diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 32c8ce66a0..5c56a1d34f 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -40,6 +40,7 @@  #include "httpoptions.h"  #include "httpheaders.h"  #include "bufferarray.h" +#include "llversioninfo.h"  #include "llviewercontrol.h"  // Have to include these last to avoid queue redefinition! @@ -378,6 +379,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const  	httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML); +    std::string user_agent = llformat("%s %d.%d.%d (%d)", +        LLVersionInfo::instance().getChannel().c_str(), +        LLVersionInfo::instance().getMajor(), +        LLVersionInfo::instance().getMinor(), +        LLVersionInfo::instance().getPatch(), +        LLVersionInfo::instance().getBuild()); + +    httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); +  	///* Setting the DNS cache timeout to -1 disables it completely.  	//This might help with bug #503 */  	//httpOpts->setDNSCacheTimeout(-1); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index e8d3c12d39..c53b2167b3 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -886,6 +886,22 @@        name="PanelNotificationListItem"        value="0.3 0.3 0.3 .3" /> +	<!-- profiles --> +    <color +        name="StatusUserOnline" +        reference="White" /> +    <color +        name="StatusUserOffline" +        reference="LtGray_35" /> +    <!-- Groups visible in own profiles --> +    <color +        name="GroupVisibleInProfile" +        reference="TextBgFocusColor" /> +    <color +        name="GroupHiddenInProfile" +        reference="Gray" /> +     +    <!-- Generic color names (legacy) -->    <color      name="white" diff --git a/indra/newview/skins/default/textures/icons/CopyBright.png b/indra/newview/skins/default/textures/icons/CopyBright.png Binary files differnew file mode 100644 index 0000000000..8d21c47295 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/CopyBright.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png Binary files differnew file mode 100644 index 0000000000..aeba6b70f7 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png Binary files differnew file mode 100644 index 0000000000..d668fd8dfa --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png Binary files differnew file mode 100644 index 0000000000..8f8caa10d8 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png Binary files differnew file mode 100644 index 0000000000..42a209dda5 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png Binary files differnew file mode 100644 index 0000000000..644edf0ef6 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png Binary files differnew file mode 100644 index 0000000000..629c05ecb8 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png Binary files differnew file mode 100644 index 0000000000..ecf66c0ee1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png Binary files differnew file mode 100644 index 0000000000..26123938fa --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg Binary files differdeleted file mode 100644 index 3bb7f7183c..0000000000 --- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg +++ /dev/null diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png Binary files differnew file mode 100644 index 0000000000..3a2ed399b2 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png Binary files differnew file mode 100644 index 0000000000..789f59a491 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png Binary files differnew file mode 100644 index 0000000000..4fb56c389c --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png Binary files differnew file mode 100644 index 0000000000..ae04a256a4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1869bf08d2..ae8c451a90 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -67,8 +67,6 @@ with the same filename but different name    <texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" />    <texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" /> -  <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" /> -    <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />    <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> @@ -192,6 +190,7 @@ with the same filename but different name    <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />    <texture name="Copy" file_name="icons/Copy.png" preload="false" /> +  <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" />    <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" /> @@ -513,6 +512,19 @@ with the same filename but different name    <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />    <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" /> +  <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/> +  <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/> +  <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/> +  <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/> +  <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/> +  <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/> +  <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/> +  <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/> +  <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/> +  <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/> +  <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/> +  <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/> +      <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />    <texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />    <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" /> diff --git a/indra/newview/skins/default/xui/da/panel_me.xml b/indra/newview/skins/default/xui/da/panel_me.xml deleted file mode 100644 index f98ced5f91..0000000000 --- a/indra/newview/skins/default/xui/da/panel_me.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Min profil" name="panel_me"> -	<tab_container name="tabs"> -		<panel label="MIN PROFIL" name="panel_profile"/> -		<panel label="MINE FAVORITTER" name="panel_picks"/> -	</tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml index 45946fd222..c8a3ad328e 100644 --- a/indra/newview/skins/default/xui/da/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml @@ -7,8 +7,8 @@  		ukendt  	</text>  	<text name="detail_texture_text"> -		Terræn teksturer (kræver 512x512, 24 bit .tga filer) -	</text> +    Terræn teksturer (kræver 1024x1024, 24 bit .tga filer) +  </text>  	<text name="height_text_lbl">  		1 (Lav)  	</text> diff --git a/indra/newview/skins/default/xui/da/panel_side_tray.xml b/indra/newview/skins/default/xui/da/panel_side_tray.xml deleted file mode 100644 index 66c3e69904..0000000000 --- a/indra/newview/skins/default/xui/da/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always -	partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> -	<sidetray_tab description="Åbn/luk sidebar" name="sidebar_openclose" tab_title="Åbn/luk sidebar"/> -	<sidetray_tab description="Hjem." name="sidebar_home" tab_title="Hjem"> -		<panel label="hjem" name="panel_home"/> -	</sidetray_tab> -	<sidetray_tab description="Redigér din profile og favoritter." name="sidebar_me" tab_title="Min profil"> -		<panel_container name="panel_container"> -			<panel label="Mig" name="panel_me"/> -		</panel_container> -	</sidetray_tab> -	<sidetray_tab description="Find venner, kontakter og personer tæt på." name="sidebar_people" tab_title="Personer"> -		<panel_container name="panel_container"> -			<panel label="Gruppe profil" name="panel_group_info_sidetray"/> -			<panel label="Blokerede beboere og objekter" name="panel_block_list_sidetray"/> -		</panel_container> -	</sidetray_tab> -	<sidetray_tab description="Find steder du vil hen og steder du har været før." label="Steder" name="sidebar_places" tab_title="Steder"> -		<panel label="Steder" name="panel_places"/> -	</sidetray_tab> -	<sidetray_tab description="Browse din beholdning." name="sidebar_inventory" tab_title="Min beholdning"> -		<panel label="Redigér beholdning" name="sidepanel_inventory"/> -	</sidetray_tab> -	<sidetray_tab description="Ændre dit nuværende udseende" name="sidebar_appearance" tab_title="Mit udseende"> -		<panel label="Redigér udseende" name="sidepanel_appearance"/> -	</sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 5f1bf73f26..e4f99d14e9 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -443,9 +443,6 @@ Prøv venligst om lidt igen.  	<string name="GroupNameNone">  		(ingen)  	</string> -	<string name="AvalineCaller"> -		Avaline opkalder [ORDER] -	</string>  	<string name="AssetErrorNone">  		Ingen fejl  	</string> diff --git a/indra/newview/skins/default/xui/de/floater_preview_texture.xml b/indra/newview/skins/default/xui/de/floater_preview_texture.xml index eacd11c3e6..b386d0288c 100644 --- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		In Inventar kopieren  	</floater.string> -	<text name="desc txt"> -		Beschreibung: -	</text> -	<text name="dimensions"> -		[WIDTH]px x [HEIGHT]px -	</text> -	<text name="aspect_ratio"> -		Vorschau Seitenverhältnis -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen"> -		<combo_item name="Unconstrained"> -			keines -		</combo_item> -		<combo_item name="1:1" tool_tip="Gruppeninsignien oder Beschreibung"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="[SECOND_LIFE]-Profil"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="Anzeigen und Suchergebnisse, Landmarken"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="Über Land"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Profilauswahl"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="Verwerfen" name="Discard"/> -	<button label="Speichern unter" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Beschreibung: +			</text> +			<text name="dimensions"> +				[WIDTH]px x [HEIGHT]px +			</text> +			<text name="aspect_ratio"> +				Vorschau Seitenverhältnis +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="Verwerfen" name="Discard"/> +			<button label="Speichern unter" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/de/floater_profile.xml b/indra/newview/skins/default/xui/de/floater_profile.xml new file mode 100644 index 0000000000..eb03463930 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Profil"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="Interessen" name="panel_profile_interests"/> +			<panel label="Auswahlen" name="panel_profile_picks"/> +			<panel label="Anzeige" name="panel_profile_classifieds"/> +			<panel label="Echtes Leben" name="panel_profile_firstlife"/> +			<panel label="Hinweise" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="Profiländerungen speichern und schließen"/> +		<button label="Abbrechen" label_selected="Abbrechen" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml index f0152ad8cd..636f320a95 100644 --- a/indra/newview/skins/default/xui/de/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		E-Mail senden  	</string> +	<string name="facebook_progress_str"> +		Auf Facebook posten +	</string>  	<string name="profile_progress_str">  		Posten  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Speichern auf Computer  	</string> +	<string name="facebook_succeeded_str"> +		Bild hochgeladen +	</string>  	<string name="profile_succeeded_str">  		Bild hochgeladen  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		Auf Computer gespeichert!  	</string> +	<string name="facebook_failed_str"> +		Fehler beim Hochladen des Bilds in Ihre Facebook-Chronik. +	</string>  	<string name="profile_failed_str">  		Fehler beim Hochladen des Bilds in Ihr Profil.  	</string> diff --git a/indra/newview/skins/default/xui/de/menu_name_field.xml b/indra/newview/skins/default/xui/de/menu_name_field.xml new file mode 100644 index 0000000000..1d293c9361 --- /dev/null +++ b/indra/newview/skins/default/xui/de/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Anzeigenamen kopieren" name="copy_display"/> +	<menu_item_call label="Agent-Namen kopieren" name="copy_name"/> +	<menu_item_call label="Agent-ID kopieren" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 359a835630..a72784f70b 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -2698,6 +2698,9 @@ Wählen Sie eine kleinere Landfläche.  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml index bd270697ea..8adacb4a5f 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="Abbrechen" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml index f6a8fda23e..1a0bbc7d30 100644 --- a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml +++ b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_friends"> -	<string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die gleichzeitig Einwohner von Second Life sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/> -	<string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, gehen Sie zur Registerkarte „Status“."/> +	<string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die ebenfalls Second Life-Einwohner sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/> +	<string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, wechseln Sie zur Registerkarte "Status"."/>  	<accordion name="friends_accordion">  		<accordion_tab name="tab_second_life_friends" title="SL-Freunde"/>  		<accordion_tab name="tab_suggested_friends" title="Diese Personen als SL-Freunde hinzufügen"/> diff --git a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml index bc48931129..fac9fe9984 100644 --- a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml @@ -2,10 +2,10 @@  <panel name="panel_facebook_photo">  	<combo_box name="resolution_combobox" tool_tip="Bildauflösung">  		<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/> -		<combo_box.item label="640x480" name="640x480"/> -		<combo_box.item label="800x600" name="800x600"/> -		<combo_box.item label="1024x768" name="1024x768"/> -		<combo_box.item label="1200x630" name="1200x630"/> +		<combo_box.item label="640 x 480" name="640x480"/> +		<combo_box.item label="800 x 600" name="800x600"/> +		<combo_box.item label="1024 x 768" name="1024x768"/> +		<combo_box.item label="1200 x 630" name="1200x630"/>  	</combo_box>  	<combo_box name="filters_combobox" tool_tip="Bildfilter">  		<combo_box.item label="Kein Filter" name="NoFilter"/> diff --git a/indra/newview/skins/default/xui/de/panel_facebook_status.xml b/indra/newview/skins/default/xui/de/panel_facebook_status.xml index 23c9d3b75f..1fefef548e 100644 --- a/indra/newview/skins/default/xui/de/panel_facebook_status.xml +++ b/indra/newview/skins/default/xui/de/panel_facebook_status.xml @@ -13,7 +13,7 @@  		</text>  	</panel>  	<text name="status_caption_label"> -		Was machst du gerade? +		Was machen Sie gerade?  	</text>  	<button label="Posten" name="post_status_btn"/>  	<button label="Abbrechen" name="cancel_status_btn"/> diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml index 9fec5a242d..e50124c37e 100644 --- a/indra/newview/skins/default/xui/de/panel_group_general.xml +++ b/indra/newview/skins/default/xui/de/panel_group_general.xml @@ -46,7 +46,7 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.  		<check_box label="Jeder kann beitreten" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>  		<check_box label="Kosten für Beitritt" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen"/>  		<spinner label="L$" name="spin_enrollment_fee" tool_tip="Wenn Beitrittsgebühr aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/> -		<combo_box name="group_mature_check" tool_tip="Inhaltseinstufungen kennzeichnen die in einer Gruppe zulässigen Inhalte und Verhaltensweisen"> +		<combo_box name="group_mature_check" tool_tip="Legt fest, ob Ihre Gruppe als moderat eingestufte Informationen enthält">  			<combo_item name="select_mature">  				- Inhaltseinstufung auswählen -  			</combo_item> diff --git a/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml new file mode 100644 index 0000000000..fc911a64df --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Unbekannt"/> +	<button name="info_btn" tool_tip="Mehr Infos"/> +	<button name="profile_btn" tool_tip="Profil anzeigen"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml deleted file mode 100644 index f49446fbbf..0000000000 --- a/indra/newview/skins/default/xui/de/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Mein Profil" name="panel_me"> -	<panel label="MEINE AUSWAHLEN" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml index 81de679429..e4a4c1033e 100644 --- a/indra/newview/skins/default/xui/de/panel_people.xml +++ b/indra/newview/skins/default/xui/de/panel_people.xml @@ -40,6 +40,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="Online"/>  				<accordion_tab name="tab_all" title="Alle"/> +				<accordion_tab name="tab_suggested_friends" title="Potenzielle Freunde"/>  			</accordion>  		</panel>  		<panel label="GRUPPEN" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/de/panel_profile_classified.xml b/indra/newview/skins/default/xui/de/panel_profile_classified.xml new file mode 100644 index 0000000000..5c11a01977 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Moderat +	</panel.string> +	<panel.string name="type_pg"> +		Generelle Inhalte +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] Teleportieren, [MAP] Karten, [PROFILE] Profil +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Aktiviert +	</panel.string> +	<panel.string name="auto_renew_off"> +		Deaktiviert +	</panel.string> +	<panel.string name="location_notice"> +		(wird nach dem Speichern aktualisiert) +	</panel.string> +	<string name="publish_label"> +		Veröffentlichen +	</string> +	<string name="save_label"> +		Speichern +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Klicken, um ein Bild auszuwählen"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Standort:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="Inhaltsart:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Kategorie:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Erstellungsdatum:"/> +					<text_editor name="creation_date" tool_tip="Erstellungsdatum" value="[date]"/> +					<text name="price_for_listing_label" value="Preis für Auflistung:"/> +					<text_editor name="price_for_listing" tool_tip="Preis für Auflistung."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Klicks:"/> +					<text_editor name="click_through_text" tool_tip="Click-Through-Daten" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Autom. erneuern:"/> +					<text name="auto_renew" value="Aktiviert"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Beschreibung:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Titel: +				</text> +				<text name="description_label"> +					Beschreibung: +				</text> +				<text name="location_label"> +					Standort: +				</text> +				<text name="classified_location_edit"> +					Laden... +				</text> +				<button label="Aktuellen Standort verwenden" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Kategorie:"/> +				<text name="content_type_label" value="Inhaltsart:"/> +				<icons_combo_box label="Generelle Inhalte" name="content_type_edit"> +					<icons_combo_box.item label="Moderate Inhalte" name="mature_ci" value="Adult"/> +					<icons_combo_box.item label="Generelle Inhalte" name="pg_ci" value="PG"/> +				</icons_combo_box> +				<check_box label="Jede Woche automatisch erneuern" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="Preis für Auflistung:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="Preis für Auflistung." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Teleportieren" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Karte" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Bearbeiten" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="Abbrechen" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml new file mode 100644 index 0000000000..83549cb138 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Anzeige" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="Keine Anzeigen"/> +	<button label="Neu..." name="new_btn"/> +	<button label="Löschen..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		Laden... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/de/floater_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml index 2521920e83..0f65090209 100644 --- a/indra/newview/skins/default/xui/de/floater_picks.xml +++ b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml @@ -1,2 +1,2 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Auswahlen"/> +<panel label="Profil" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/de/panel_profile_interests.xml b/indra/newview/skins/default/xui/de/panel_profile_interests.xml new file mode 100644 index 0000000000..0f36f76aa0 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Interessen" name="panel_profile_interests"> +	<text name="I Want To:"> +		Ich möchte: +	</text> +	<check_box label="Erstellen" name="chk0"/> +	<check_box label="Erkunden" name="chk1"/> +	<check_box label="Treffen" name="chk2"/> +	<check_box label="Angestellt werden" name="chk6"/> +	<check_box label="Gruppe" name="chk3"/> +	<check_box label="Kaufen" name="chk4"/> +	<check_box label="Verkaufen" name="chk5"/> +	<check_box label="Anstellen" name="chk7"/> +	<line_editor name="want_to_edit"> +		(wird geladen...) +	</line_editor> +	<text name="Skills:"> +		Fähigkeiten: +	</text> +	<check_box label="Texturen" name="schk0"/> +	<check_box label="Architektur" name="schk1"/> +	<check_box label="Modellierung" name="schk3"/> +	<check_box label="Eventplanung" name="schk2"/> +	<check_box label="Scripting" name="schk4"/> +	<check_box label="Benutzerdefinierte Charaktere" name="schk5"/> +	<line_editor name="skills_edit"> +		(wird geladen...) +	</line_editor> +	<text name="Languages:"> +		Sprachen: +	</text> +	<line_editor name="languages_edit"> +		(wird geladen...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_notes.xml b/indra/newview/skins/default/xui/de/panel_profile_notes.xml new file mode 100644 index 0000000000..05c46ff858 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Anmerkungen & Privatsphäre" name="panel_notes"> +	<text name="status_message" value="Private Anmerkungen zu diesem Avatar:"/> +	<text name="status_message2" value="Dieser Avatar darf:"/> +	<check_box label="Sehen, wenn ich online bin" name="status_check"/> +	<check_box label="Mich auf der Weltkarte sehen" name="map_check"/> +	<check_box label="Meine Objekte bearbeiten, löschen oder nehmen" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_pick.xml b/indra/newview/skins/default/xui/de/panel_profile_pick.xml new file mode 100644 index 0000000000..1f44ba8b1b --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(wird nach dem Speichern aktualisiert) +	</panel.string> +	<line_editor name="pick_location"> +		Laden... +	</line_editor> +	<button label="Teleportieren" name="teleport_btn"/> +	<button label="Auf Karte anzeigen" name="show_on_map_btn"/> +	<button label="Standort festlegen" name="set_to_curr_location_btn" tool_tip="Aktuellen Standort verwenden"/> +	<button label="Auswahl speichern" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_picks.xml new file mode 100644 index 0000000000..96403715e4 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Auswahlen" name="panel_picks"> +	<string name="no_picks" value="Keine Auswahl"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Erzählen Sie von Ihren Lieblingsorten in Second Life. +	</text> +	<button label="Neu..." name="new_btn"/> +	<button label="Löschen..." name="delete_btn"/> +	<text name="picks_panel_text"> +		Laden... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml new file mode 100644 index 0000000000..baaa58e1d7 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profil" name="panel_profile"> +	<string name="status_online"> +		Zurzeit online +	</string> +	<string name="status_offline"> +		Zurzeit offline +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=de +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=de +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Keine"/> +	<string name="no_group_text" value="Keine"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Entwickler"/> +	<string name="FSSupp" value="Support"/> +	<string name="FSQualityAssurance" value="Fehlersuche"/> +	<string name="FSGW" value="Gateway"/> +	<text name="name_label" value="Name:"/> +	<button label="Name:" name="set_name" tool_tip="Anzeigenamen festlegen"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(wird geladen...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Status unbekannt"/> +			<text name="label" value="Second Life-Geburtsdatum:"/> +			<text name="label2" value="Konto:"/> +			<text name="partner_label" value="Partner:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Gruppen:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="In Gruppe einladen"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="Info:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Objekt geben:"/> +			<text name="Give inventory" tool_tip="Legen Sie hier Inventarobjekte ab, um Sie dieser Person zu geben."> +				Inventarobjekt hier ablegen. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Auf Karte anzeigen" label_selected="Auf Karte anzeigen" name="show_on_map_btn" tool_tip="Einwohner auf Karte lokalisieren"/> +			<button label="Bezahlen" label_selected="Bezahlen" name="pay" tool_tip="Geld an den Einwohner zahlen"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Teleportation anbieten" label_selected="Teleportation anbieten" name="teleport" tool_tip="Dem Einwohner eine Teleportation anbieten"/> +			<button label="Instant Message" label_selected="Instant Message" name="im" tool_tip="Instant Message-Sitzung öffnen"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Freund hinzufügen" label_selected="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/> +			<button label="Blockieren" name="block" tool_tip="Diesen Einwohner blockieren"/> +			<button label="Blockierung aufheben" name="unblock" tool_tip="Diesen Einwohner nicht mehr blockieren"/> +		</layout_panel> +	</layout_stack> +	<check_box label="In Suche anzeigen" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_web.xml b/indra/newview/skins/default/xui/de/panel_profile_web.xml new file mode 100644 index 0000000000..a03918f4b5 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Ladezeit: [TIME] Sekunden"/> +	<line_editor name="url_edit"> +		(wird geladen..) +	</line_editor> +	<flyout_button label="Laden" name="load" tool_tip="Lädt diese Profilseite im integrierten Webbrowser."> +		<flyout_button.item label="Im Viewer-Browser öffnen" name="open_item"/> +		<flyout_button.item label="In externem Browser öffnen" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Webprofil ausklappen"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml index 7801be30e4..42ba5b5269 100644 --- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml @@ -10,8 +10,8 @@  	<spinner label="Obere Terraingrenze" name="terrain_raise_spin"/>  	<spinner label="Untere Terraingrenze" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512) -	</text> +    Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024) +  </text>  	<text name="height_text_lbl">  		1 (niedrig)  	</text> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 97ace4fc18..0120f7e5bd 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -356,6 +356,24 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.  	<string name="TestingDisconnect">  		Verbindungsabbruch wird getestet  	</string> +	<string name="SocialFacebookConnecting"> +		Mit Facebook verbinden... +	</string> +	<string name="SocialFacebookPosting"> +		Posten... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Facebook-Verbindung trennen... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Problem beim Verbinden mit Facebook +	</string> +	<string name="SocialFacebookErrorPosting"> +		Problem beim Posten auf Facebook +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Problem beim Trennen der Facebook-Verbindung +	</string>  	<string name="SocialFlickrConnecting">  		Verbinden mit Flickr...  	</string> @@ -673,9 +691,6 @@ nächsten Eigentümer angehängt werden.  	<string name="GroupNameNone">  		(keiner)  	</string> -	<string name="AvalineCaller"> -		Avaline-Anfrufer [ORDER] -	</string>  	<string name="AssetErrorNone">  		Kein Fehler  	</string> @@ -2578,9 +2593,21 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo  	<string name="NoPicksClassifiedsText">  		Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus"-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen.  	</string> +	<string name="NoPicksText"> +		Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche "Neu", um eine Auswahl zu erstellen. +	</string> +	<string name="NoClassifiedsText"> +		Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche "Neu", um eine Anzeige zu erstellen. +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		Der Einwohner hat keine Auswahl oder Anzeigen  	</string> +	<string name="NoAvatarPicksText"> +		Der Einwohner hat keine Auswahl +	</string> +	<string name="NoAvatarClassifiedsText"> +		Der Einwohner hat keine Anzeigen +	</string>  	<string name="PicksClassifiedsLoadingText">  		Wird geladen...  	</string> @@ -4558,6 +4585,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_  	<string name="share_alert">  		Objekte aus dem Inventar hier her ziehen  	</string> +	<string name="facebook_post_success"> +		Sie haben auf Facebook gepostet. +	</string>  	<string name="flickr_post_success">  		Sie haben auf Flickr gepostet.  	</string> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index dee5e29a3c..4678d65b85 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1893,7 +1893,29 @@ Only large parcels can be listed in search.               left="110"               name="parcel_enable_voice_channel_local"               width="300" /> -        </panel> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="16" +             layout="topleft" +             left="10" +             mouse_opaque="false" +             name="media" +             top_pad="10" +             width="100"> +                Media: +            </text> +            <check_box +             height="16" +             label="Obscure MOAP" +             layout="topleft" +             left="110" +             left_pad="0" +             name="obscure_moap" +             tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa." +             width="300" /> +            </panel>          <panel           border="true"           follows="all" diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_classified.xml index 984894b016..5b14c827d0 100644 --- a/indra/newview/skins/default/xui/en/floater_picks.xml +++ b/indra/newview/skins/default/xui/en/floater_classified.xml @@ -2,20 +2,19 @@  <floater   positioning="cascading"   can_close="true" - can_resize="true" + can_resize="false"   height="572"   help_topic="sidebar_me"   min_width="333"   min_height="440" - name="floater_picks" + name="floater_classified"   save_rect="true" - save_visibility="true" - reuse_instance="true" - title="Picks" + save_visibility="false" + title="Classified"   width="333" >     <panel -    class="panel_me" +    class="panel_classified_info"      name="main_panel" -    filename="panel_me.xml" +    filename="panel_classified_info.xml"      follows="all"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml index 9a9fd32a77..3c8f415860 100644 --- a/indra/newview/skins/default/xui/en/floater_display_name.xml +++ b/indra/newview/skins/default/xui/en/floater_display_name.xml @@ -23,7 +23,7 @@       use_ellipses="true"       width="380"       wrap="true"> -      The name you give your avatar is called your Display Name. You can change it once a week. +      Your display name is what other people see above your head. It is different from your login name. You can change it once a week.      </text>  	<text       type="string" @@ -85,19 +85,10 @@       width="120" />      <button       height="23" -     label="Reset" -     layout="topleft" -     font="SansSerif" -     left_pad="5" -     name="reset_btn" -     tool_tip="Make Display Name the same as Username" -     width="120" /> -    <button -     height="23"       label="Cancel"       font="SansSerif"       layout="topleft" -     left_pad="5" +     left_pad="125"       name="cancel_btn"       width="120" />  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml index e1e7e1c8c8..048cf7df62 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml @@ -17,94 +17,122 @@       name="Copy">          Copy To Inventory      </floater.string> -    <text -     type="string" -     length="1" -     follows="left|top" -     font="SansSerif" -     height="19" -     layout="topleft" -     left="10" -     name="desc txt" -     top="21" -     width="90"> -        Description: -    </text> -    <line_editor -     border_style="line" -     border_thickness="1" -     follows="left|top|right" -     font="SansSerif" -     height="19" -     layout="topleft" -     left_pad="0" -     max_length_bytes="127" -     name="desc" -     width="190" /> -    <text -     type="string" -     halign="right" -     length="1" -     follows="right|bottom" -     height="16" -     layout="topleft" -     left="110" -     name="dimensions" -     top="255" -     width="200"> -        [WIDTH]px x [HEIGHT]px -    </text> -    <text -     type="string" -     halign="right" -     length="1" -     follows="right|bottom" -     height="16" -     layout="topleft" -     left_delta="-110" -     name="aspect_ratio" -     top_pad="5" -     width="200"> -        Preview aspect ratio -    </text> -    <combo_box -     allow_text_entry="true"  -     top_delta="-3"  -     follows="right|bottom"  -     height="23" -     left_pad="10" -     max_chars="20" -     mouse_opaque="true" -     enabled="true" -     width="108" -     name="combo_aspect_ratio" -     tool_tip="Preview at a fixed aspect ratio"> -	</combo_box> -    <button -     follows="right|bottom" -     height="22" -     label="OK" -     layout="topleft" -     left="6" -     name="Keep" -     top_pad="5" -     width="110" /> -    <button -     follows="right|bottom" -     height="22" -     label="Discard" -     layout="topleft" -     left_pad="5" -     name="Discard" -     top_delta="0" -     width="110" /> -    <button -     follows="right|bottom" -     height="22" -     label="Save As" -     layout="topleft" -     left_pad="5" -     name="save_tex_btn" -     top_delta="0" -     width="110" /> +    <layout_stack +     animate="false" +     name="preview_stack" +     top_pad="15" +     left="0" +     follows="all" +     orientation="vertical" +     height="350" +     width="370" +     layout="topleft"> +      <layout_panel +        name="texture_panel" +        height="305" +        top_pad="0" +        left="0" +        follows="left|top" +        layout="topleft"> +          <text +           type="string" +           length="1" +           follows="left|top" +           font="SansSerif" +           height="19" +           layout="topleft" +           left="10" +           name="desc txt" +           top="6" +           width="90"> +              Description: +          </text> +          <line_editor +           border_style="line" +           border_thickness="1" +           follows="left|top|right" +           font="SansSerif" +           height="19" +           layout="topleft" +           left_pad="0" +           max_length_bytes="127" +           name="desc" +           width="190" /> +          <text +           type="string" +           halign="right" +           length="1" +           follows="right|bottom" +           height="16" +           layout="topleft" +           left="110" +           name="dimensions" +           bottom="-40" +           width="200"> +              [WIDTH]px x [HEIGHT]px +          </text> +          <text +           type="string" +           halign="right" +           length="1" +           follows="right|bottom" +           height="16" +           layout="topleft" +           left_delta="-110" +           name="aspect_ratio" +           top_pad="5" +           width="200"> +              Preview aspect ratio +          </text> +          <combo_box +           allow_text_entry="true"  +           top_delta="-3"  +           follows="right|bottom"  +           height="23" +           left_pad="10" +           max_chars="20" +           mouse_opaque="true" +           enabled="true" +           width="108" +           name="combo_aspect_ratio" +           tool_tip="Preview at a fixed aspect ratio"> +	      </combo_box> +      </layout_panel> +      <layout_panel +        name="buttons_panel" +        height="45" +        bottom="-40" +        left="0" +        follows="right|bottom" +        auto_resize="false" +        layout="topleft"> +        <button +         follows="right|bottom" +         height="22" +         label="OK" +         layout="topleft" +         left="6" +         name="Keep" +         top_pad="0" +         width="110" /> +        <button +         follows="right|bottom" +         height="22" +         label="Discard" +         layout="topleft" +         left_pad="5" +         name="Discard" +         top_delta="0" +         width="110" /> +        <button +         follows="right|bottom" +         height="22" +         label="Save As" +         layout="topleft" +         left_pad="5" +         name="save_tex_btn" +         top_delta="0" +         width="110" /> +      </layout_panel> +    </layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml new file mode 100644 index 0000000000..32ab811a6e --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + name="avatarinfo" + height="510" + width="510" + layout="topleft" + can_close="true" + can_resize="true" + help_topic="panel_my_profile_tab" + min_height="510" + min_width="510" + positioning="centered" + save_rect="true" + title="Profile" +> +    <panel +     name="panel_profile_view" +     top="0" +     left="0" +     height="500" +     width="505" +     follows="all" +     class="panel_profile" +    > +        <tab_container +         name="panel_profile_tabs" +         top_pad="5" +         left="0" +         height="500" +         width="505" +         follows="all" +         layout="topleft" +         halign="center" +         tab_min_width="81" +         tab_height="30" +         tab_position="top" +        > +            <panel +             name="panel_profile_secondlife" +             label="BIO" +             layout="topleft" +             class="panel_profile_secondlife" +             filename="panel_profile_secondlife.xml" +             help_topic="profile_secondlife_tab" +            /> +            <panel +             name="panel_profile_web" +             label="FEED" +             layout="topleft" +             class="panel_profile_web" +             filename="panel_profile_web.xml" +             help_topic="profile_web_tab" +            /> +            <panel +             name="panel_profile_picks" +             label="PICKS" +             layout="topleft" +             class="panel_profile_picks" +             filename="panel_profile_picks.xml" +             help_topic="profile_picks_tab" +            /> +            <panel +             name="panel_profile_classifieds" +             label="CLASSIFIEDS" +             layout="topleft" +             class="panel_profile_classifieds" +             filename="panel_profile_classifieds.xml" +             help_topic="profile_classified_tab" +            /> +            <panel +             name="panel_profile_firstlife" +             label="REAL LIFE" +             layout="topleft" +             class="panel_profile_firstlife" +             filename="panel_profile_firstlife.xml" +             help_topic="profile_firstlife_tab" +            /> +            <panel +             name="panel_profile_notes" +             label="MY NOTES" +             layout="topleft" +             class="panel_profile_notes" +             filename="panel_profile_notes.xml" +             help_topic="profile_notes_tab" +            /> +        </tab_container> +    </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_profile_permissions.xml b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml new file mode 100644 index 0000000000..9f3b4d9a00 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + show_title="false" + can_minimize="false" + can_close="false" + header_height="10" + bg_opaque_image="Window_NoTitle_Foreground" + bg_alpha_image="Window_NoTitle_Background" + height="115" + layout="topleft" + name="profile_permissions" + width="300"> +  <string +   name="description_string" +   value="Allow [AGENT_NAME] to:" /> +  <text +   name="perm_description" +   value="Allow agent to:" +   top="1" +   left="12" +   right="-6" +   height="16" +   follows="top|left" +   layout="topleft" +   font.style="BOLD" +    /> +  <check_box +   name="online_check" +   label="See when I am online" +   top_pad="5" +   left="16" +   height="16" +   width="293" +   follows="top|left" +   layout="topleft" +    /> +  <check_box +   name="map_check" +   label="Find me on the world map" +   top_pad="5" +   left="16" +   height="16" +   width="293" +   follows="top|left" +   layout="topleft" +    /> +  <check_box +   name="objects_check" +   label="Edit, delete or take my objects from my land" +   top_pad="5" +   left="16" +   height="16" +   width="293" +   follows="top|left" +   layout="topleft" +    /> +  <button +   name="perms_btn_ok" +   label="OK" +   top_pad="5" +   left="42" +   height="20" +   width="100" +   follows="top|left" +   layout="topleft"/> +  <button +   name="perms_btn_cancel" +   label="Cancel" +   top_delta="0" +   left_pad="12" +   height="20" +   width="100" +   follows="top|left" +   layout="topleft"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml new file mode 100644 index 0000000000..3b351a3325 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + show_title="false" + can_minimize="false" + can_close="false" + header_height="10" + height="223" + width="200" + layout="topleft" + min_height="128" + min_width="128" + name="profile_texture"> +    <layout_stack +     name="preview_stack" +     top="0" +     left="0" +     right="-1" +     bottom="-1" +     follows="all" +     orientation="vertical" +     layout="topleft" +     animate="false"> +      <layout_panel +        name="texture_panel" +        height="196" +        follows="left|top" +        auto_resize="true" +        layout="topleft"> +        <icon +         name="profile_pic" +         image_name="Generic_Person_Large" +         layout="topleft" +         follows="all" +         top="5" +         left="5" +         bottom="-1" +         right="-5"/> +      </layout_panel> +      <layout_panel +        name="buttons_panel" +        height="26" +        auto_resize="false" +        layout="topleft"> +        <layout_stack +         name="buttons_stack" +         top="0" +         left="0" +         right="-1" +         bottom="-1" +         follows="all" +         orientation="horizontal" +         layout="topleft" +         animate="false"> +          <layout_panel +           follows="all" +           layout="topleft" +           name="resizer_left" +           auto_resize="true" +           width="1"> +          </layout_panel> +          <layout_panel +           follows="all" +           layout="topleft" +           name="close_panel" +           auto_resize="false" +           width="112"> +            <button +             follows="top|left" +             height="22" +             label="Close" +             layout="topleft" +             left="1" +             top="0" +             width="110" +             name="close_btn"/> +          </layout_panel> +          <layout_panel +           follows="all" +           layout="topleft" +           name="resizer_right" +           auto_resize="true" +           width="1"> +          </layout_panel> +        </layout_stack> +      </layout_panel> +    </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index d07e3cb31b..343e72f057 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -11,6 +11,11 @@       name="Screenshot">          Screenshot      </floater.string> +    <floater.string +     name="chat_report_format"> +Time: [MSG_TIME] +Text: [MSG_DESCRIPTION] +    </floater.string>      <texture_picker       allow_no_texture="true"       default_image_name="None" @@ -19,7 +24,7 @@       layout="topleft"       left="60"       name="screenshot" -     top="15" +     top="20"       width="220" />      <text       type="string" diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index ef4f19cd4c..fceb9b2184 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -85,6 +85,8 @@       use_ellipses="true" />       <text       follows="left|top|right" +     trusted_content="false" +     always_show_icons="true"       height="35"       left="8"       name="user_details" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml index 05ab4d35a0..9f394a4c74 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml @@ -96,6 +96,13 @@       name="Pay">         <on_click function="AvatarIcon.Action" parameter="pay" />      </menu_item_call> +    <menu_item_call +     label="Report Abuse" +     layout="topleft" +     name="Report Abuse"> +       <on_click function="AvatarIcon.Action" parameter="report_abuse" /> +       <on_enable function="AvatarIcon.Enable" parameter="report_abuse" /> +    </menu_item_call>      <menu_item_check       label="Block Voice"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 500b6fffc2..20f3ad080b 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -290,4 +290,11 @@      <menu_item_call.on_visible       function="EnableMuteParticle" />    </menu_item_call> +  <menu_item_separator/> +  <menu_item_call label="View Profile" +       layout="topleft" +       name="show_avatar_profile"> +    <menu_item_call.on_click +     function="Avatar.ToggleMyProfile" /> +  </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml index ed362b36e5..59e6106a28 100644 --- a/indra/newview/skins/default/xui/en/menu_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -132,6 +132,13 @@          <on_click function="Avatar.DoToSelected" parameter="pay" />          <on_enable function="Avatar.EnableItem" parameter="can_pay" />      </menu_item_call> +    <menu_item_call +     label="Report Abuse" +     layout="topleft" +     name="report_abuse"> +       <on_click function="Avatar.DoToSelected" parameter="report_abuse" /> +       <on_enable function="Avatar.EnableItem" parameter="report_abuse" /> +    </menu_item_call>      <menu_item_check       label="Block Voice"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml index 5cae643e44..359c093eff 100644 --- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml @@ -9,7 +9,7 @@       layout="topleft"       name="activate">          <on_click -         function="Gesture.Action.ToogleActiveState" /> +         function="Gesture.Action.ToggleActiveState" />      </menu_item_call>      <menu_item_call       label="Rename" diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml index 43287c6ec3..b38fae4404 100644 --- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml @@ -79,6 +79,13 @@      </menu_item_call>      <menu_item_separator       layout="topleft"/> +    <menu_item_call +     label="Report Abuse" +     layout="topleft" +     name="Report Abuse"> +       <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" /> +       <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" /> +    </menu_item_call>      <menu_item_check       label="Block Voice"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml new file mode 100644 index 0000000000..4db4d0922b --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Avatar Profile Menu"> +  <menu_item_call +   label="IM" +   layout="topleft" +   name="im"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="im"/> +  </menu_item_call> +  <menu_item_call +  label="Offer Teleport" +  name="offer_teleport"> +    <menu_item_call.on_click +     function="Profile.Commit" +    parameter="offer_teleport"/> +    <menu_item_call.on_enable +    function="Profile.EnableItem" +    parameter="offer_teleport"/> +  </menu_item_call> +  <menu_item_call +  label="Request Teleport" +  name="request_teleport"> +    <menu_item_call.on_click +     function="Profile.Commit" +    parameter="request_teleport"/> +    <menu_item_call.on_enable +    function="Profile.EnableItem" +    parameter="request_teleport"/> +  </menu_item_call> +  <menu_item_call +   label="Voice call" +   layout="topleft" +   name="voice_call"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="voice_call"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="voice_call"/> +  </menu_item_call> +  <menu_item_separator /> +  <menu_item_call +   label="View chat history..." +   layout="topleft" +   name="chat_history"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="chat_history"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="chat_history"/> +  </menu_item_call> +  <menu_item_separator name="separator_chat_history"/> +  <menu_item_call +   label="Add Friend" +   layout="topleft" +   name="add_friend"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="add_friend"/> +    <menu_item_call.on_visible +     function="Profile.EnableItem" +     parameter="add_friend"/> +  </menu_item_call> +  <menu_item_call +   label="Remove Friend" +   layout="topleft" +   name="remove_friend"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="remove_friend"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="remove_friend"/> +  </menu_item_call> +  <menu_item_call +   label="Invite to group..." +   layout="topleft" +   name="invite_to_group"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="invite_to_group"/> +  </menu_item_call> +  <menu_item_separator name="separator_invite_to_group"/> +  <menu_item_call +   label="Permissions" +   layout="topleft" +   name="agent_permissions"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="agent_permissions"/> +    <menu_item_call.on_visible +     function="Profile.EnableItem" +     parameter="agent_permissions"/> +  </menu_item_call> +  <menu_item_call +   label="Map" +   layout="topleft" +   name="map"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="can_show_on_map"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="can_show_on_map"/> +  </menu_item_call> +  <menu_item_call +   label="Share" +   layout="topleft" +   name="share"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="share"/> +  </menu_item_call> +  <menu_item_call +   label="Pay" +   layout="topleft" +   name="pay"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="pay"/> +  </menu_item_call> +  <menu_item_check +   label="Block/Unblock" +   layout="topleft" +   name="block_unblock"> +    <menu_item_check.on_click +     function="Profile.Commit" +     parameter="toggle_block_agent"/> +    <menu_item_check.on_check +     function="Profile.CheckItem" +     parameter="toggle_block_agent"/> +    <menu_item_check.on_enable +     function="Profile.EnableItem" +     parameter="toggle_block_agent"/> +  </menu_item_check> +  <menu_item_separator name="separator_copy_options"/> +  <menu_item_call +   label="Copy Display Name" +   layout="topleft" +   name="copy_display_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_display_name"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_display_name"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Name" +   layout="topleft" +   name="copy_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_username"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_username"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Id" +   layout="topleft" +   name="copy_id"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_user_id"/> +  </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml new file mode 100644 index 0000000000..d0bd4000f8 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Avatar Profile Menu Self"> +  <menu_item_call +   label="Edit Display Name" +   layout="topleft" +   name="edit_display_name"> +    <on_click +     function="Profile.Commit" +     parameter="edit_display_name"/> +  </menu_item_call> +  <menu_item_call +   label="Edit Partner" +   layout="topleft" +   name="edit_partner"> +    <on_click +     function="Profile.Commit" +     parameter="edit_partner"/> +  </menu_item_call> +  <menu_item_call +   label="Upload Photo" +   layout="topleft" +   name="upload_photo"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="upload_photo"/> +    <menu_item_call.on_enable +    function="Profile.EnableItem" +     parameter="upload_photo"/> +  </menu_item_call> +  <menu_item_call +   label="Change Photo" +   layout="topleft" +   name="change_photo"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="change_photo"/> +    <menu_item_call.on_enable +    function="Profile.EnableItem" +     parameter="change_photo"/> +  </menu_item_call> +  <menu_item_call +   label="Remove Photo" +   layout="topleft" +   name="remove_photo"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="remove_photo"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="remove_photo"/> +  </menu_item_call> +  <menu_item_separator name="separator_copy_options"/> +  <menu_item_call +   label="Copy Display Name" +   layout="topleft" +   name="copy_display_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_display_name"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_display_name"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Name" +   layout="topleft" +   name="copy_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_username"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_username"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Id" +   layout="topleft" +   name="copy_id"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_user_id"/> +  </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index e8b6116026..5ca8be2123 100644 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -29,7 +29,14 @@       name="remove_friend">          <menu_item_call.on_click           function="Url.RemoveFriend" /> -        </menu_item_call> +    </menu_item_call> +    <menu_item_call +     label="Report Abuse" +     layout="topleft" +     name="report_abuse"> +        <menu_item_call.on_click +         function="Url.ReportAbuse" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" />      <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 4b485820bd..af733f6ebc 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -47,8 +47,7 @@         label="Picks..."         name="Picks">          <menu_item_call.on_click -         function="Floater.ToggleOrBringToFront" -         parameter="picks" /> +         function="ShowAgentProfilePicks" />        </menu_item_call>        <menu_item_call          label="Experiences..." @@ -423,7 +422,9 @@          </menu_item_call>                 <menu_item_call           label="Stop animations" -         name="Stop Animating My Avatar"> +         name="Stop Animating My Avatar" +         allow_key_repeat="true" +         shortcut="alt|shift|A">            <menu_item_call.on_click             function="Tools.StopAllAnimations" />          </menu_item_call> @@ -2656,6 +2657,12 @@ function="World.EnvPreset"                   function="Advanced.ForceErrorBadMemoryAccess" />              </menu_item_call>              <menu_item_call +             label="Force Bad Memory Access in Coroutine" +             name="Force Bad Memory Access in Coroutine"> +                <menu_item_call.on_click +                 function="Advanced.ForceErrorBadMemoryAccessCoro" /> +            </menu_item_call> +            <menu_item_call               label="Force Infinite Loop"               name="Force Infinite Loop">                  <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 2bc742286e..03f9c9ce97 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1496,7 +1496,19 @@ Insufficient funds to create classified.    <notification     icon="alertmodal.tga" -   name="DeleteAvatarPick" +   name="ProfileDeleteClassified" +   type="alertmodal"> +Delete classified <nolink>[CLASSIFIED]</nolink>? +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="ProfileDeletePick"     type="alertmodal">  Delete pick <nolink>[PICK]</nolink>?      <tag>confirm</tag> @@ -1507,6 +1519,32 @@ Delete pick <nolink>[PICK]</nolink>?    </notification>    <notification +   icon="alert.tga" +   name="ProfileUnpublishedClassified" +   type="alertmodal"> +    You have unpublished classifieds. They will be lost if you close the window. +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alert.tga" +   name="ProfileUnsavedChanges" +   type="alertmodal"> +    You have usaved changes. +    <tag>confirm</tag> +    <tag>save</tag> +    <usetemplate +     canceltext="Cancel" +     name="yesnocancelbuttons" +     notext="Discard" +     yestext="Save"/> +  </notification> + +  <notification     icon="alertmodal.tga"     name="DeleteOutfits"     type="alertmodal"> @@ -3942,7 +3980,7 @@ Are you sure you want to return objects owned by [USER_NAME]?  Couldn't set region textures:  Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again.    <tag>fail</tag>    </notification> @@ -3953,7 +3991,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click  Couldn't set region textures:  Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again.    </notification>    <notification diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index d4a2745d1d..04a0bc800d 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -38,28 +38,15 @@    name="auto_renew_off">      Disabled   </panel.string> -    <button -     follows="top|left" -     height="24" -     image_hover_unselected="BackButton_Over" -     image_pressed="BackButton_Press" -     image_unselected="BackButton_Off" -     layout="topleft" -     name="back_btn" -     left="10" -     tab_stop="false" -     top="2" -     width="30" -     use_draw_context_alpha="false" />      <text       follows="top|left|right"       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="4" +     left="12"       name="title"       text_color="LtGray" -     top="0" +     top="2"       value="Classified Info"       use_ellipses="true"       width="275" /> @@ -420,7 +407,7 @@  		         height="23"  		         label="Teleport"  		         layout="topleft" -		         left="0" +		         left="2"  		         name="teleport_btn"  		         top="0"  		         width="101" />	 @@ -443,24 +430,6 @@  		         top="0"  		         width="100" />  		  </layout_panel>	   -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left_pad="3" -			  name="edit_btn_lp" -		      auto_resize="true" -			  width="101"> -			  <button -		         follows="bottom|left|right" -		         height="23" -		         label="Edit" -		         layout="topleft" -		         name="edit_btn" -		         top="0" -		         width="101" /> -		  </layout_panel>  	   </layout_stack>      </panel>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml deleted file mode 100644 index e846edf1d4..0000000000 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ /dev/null @@ -1,354 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - bevel_style="in" - follows="left|top|right|bottom" - height="569" - label="Edit Classified" - layout="topleft" - left="0" - min_height="350" - name="panel_edit_classified" - help_topic="profile_edit_classified" - top="0" - width="333"> - <panel.string -  name="location_notice"> -    (will update after save) - </panel.string> - <string name="publish_label"> -  Publish - </string> - <string name="save_label"> -  Save - </string> -  <button -     follows="top|left" -     height="24" -     image_hover_unselected="BackButton_Over" -     image_pressed="BackButton_Press" -     image_unselected="BackButton_Off" -     layout="topleft" -     name="back_btn" -     left="10" -     tab_stop="false" -     top="2" -     width="30" -     use_draw_context_alpha="false" /> -   <text -     type="string" -     length="1" -     follows="top" -     font="SansSerifHugeBold" -     height="26" -     layout="topleft" -     left_pad="4" -     name="title" -     text_color="LtGray" -     top="0" -     width="250"> -        Edit Classified -    </text> -   <scroll_container -    color="DkGray2" -    follows="all" -    height="502" -    layout="topleft" -    left="8" -    top_pad="10" -    name="profile_scroll" -    reserve_scroll_corner="false" -    opaque="true" -    width="312"> -    <panel -     name="scroll_content_panel" -     follows="left|top" -     min_height="300" -     layout="topleft" -     top="0" -     background_visible="false" -     height="690" -     left="0" -     width="285"> -      <panel -         name="snapshot_panel" -         layout="topleft" -         follows="left|top|right" -         height="197" -         left="10" -         top="10" -         width="272"> -      <texture_picker -       fallback_image="default_land_picture.j2c" -       follows="left|top|right" -       height="197" -       width="272" -       layout="topleft" -       top="0" -       left="0" -       name="classified_snapshot" /> -       <icon -           height="197" -           image_name="spacer24.tga" -           layout="topleft" -           name="edit_icon" -           label="" -           tool_tip="Click to select an image" -           top="0" -           left="0" -           width="272" /> -       </panel> -        <text -         type="string" -         length="1" -         follows="left|top" -         height="15" -         font="SansSerifSmall" -         font.style="BOLD" -         layout="topleft" -         left="10" -         top="215" -         name="Name:" -         text_color="white" -         width="280"> -            Title: -        </text> -        <line_editor -         follows="left|top|right" -         font="SansSerif" -         height="20" -         layout="topleft" -         left="10" -         top_pad="2" -         max_length_bytes="30" -         name="classified_name" -         prevalidate_callback="ascii" -         text_color="black" -         width="273" /> -        <text -         type="string" -         length="1" -         follows="left|top" -         height="15" -         font="SansSerifSmall" -         font.style="BOLD" -         layout="topleft" -         left="10" -         top_pad="20" -         name="description_label" -         text_color="white" -         width="280"> -            Description: -        </text> -        <text_editor -         follows="left|top|right" -         height="100" -         width="273" -         layout="topleft" -         left="10" -         top_pad="2" -         max_length="256" -         name="classified_desc" -         text_color="black" -         word_wrap="true" /> -        <text -         type="string" -         length="1" -         font="SansSerifSmall" -         font.style="BOLD" -         follows="left|top" -         height="15" -         layout="topleft" -         left="10" -         name="location_label" -         text_color="white" -         top_pad="20" -         width="280"> -            Location: -        </text> -        <text -         type="string" -         length="1" -         follows="left|top" -         height="30" -         layout="topleft" -         left="10" -         name="classified_location" -         right="-10" -         top_pad="2" -         width="280" -         word_wrap="true"> -            loading... -        </text> -        <button -         follows="left|top" -         height="23" -         label="Set to Current Location" -         layout="topleft" -         left="10" -         top_pad="5" -         name="set_to_curr_location_btn" -         width="200" /> -        <text -         follows="left|top" -         font.style="BOLD" -         height="10" -         layout="topleft" -         left="10" -         name="category_label" -         text_color="white" -         top_pad="15" -         value="Category:" -         width="250" /> -        <combo_box -         follows="left|top"  -         height="23"  -         label="" -	     left="10"  -         name="category"  -         top_pad="5" -         width="156" /> -        <text -         follows="left|top" -         font.style="BOLD" -         height="10" -         layout="topleft" -         left="10" -         name="content_type_label" -         text_color="white" -         top_pad="15" -         value="Content type:" -         width="250" /> -        <icons_combo_box -         follows="left|top" -         height="23" -         label="General Content" -         layout="topleft" -         left="10" -         name="content_type" -         top_pad="5" -         width="156"> -            <icons_combo_box.drop_down_button -             image_overlay="Parcel_PG_Light" -             image_overlay_alignment="left" -             imgoverlay_label_space="3" -             pad_left="3"/> -            <icons_combo_box.item -             label="Moderate Content" -             name="mature_ci" -             value="Mature"> -                <item.columns -                 halign="center" -                 type="icon" -                 value="Parcel_M_Light" -                 width="20"/> -            </icons_combo_box.item> -            <icons_combo_box.item -             label="General Content" -             name="pg_ci" -             value="PG"> -                <item.columns -                 halign="center" -                 type="icon" -                 value="Parcel_PG_Light" -                 width="20"/> -            </icons_combo_box.item> -        </icons_combo_box> -        <check_box -         height="16" -         label="Auto renew each week" -         layout="topleft" -         left="10" -         name="auto_renew" -         top_pad="15" -         width="250" /> -        <text -         follows="left|top" -         height="10" -         layout="topleft" -         left="10" -         name="price_for_listing_label" -         text_color="white" -         top_pad="15" -         value="Price for listing:" -         width="250" /> -        <spinner -         decimal_digits="0" -         follows="left|top" -         halign="left" -         height="23" -         increment="1" -         label_width="20" -         label="L$" -         v_pad="10" -         layout="topleft" -         left="10" -         value="50" -         min_val="50" -         max_val="99999" -         name="price_for_listing" -         top_pad="5" -         tool_tip="Price for listing." -         width="105" /> -     </panel> -    </scroll_container> -    <panel -     follows="left|right|bottom" -     height="23" -     label="bottom_panel" -     layout="topleft" -     left="8" -     name="bottom_panel" -     top_pad="5" -     width="303"> -      -         <layout_stack -		  follows="bottom|left|right" -		  height="23" -		  layout="topleft" -		  name="bottom_panel_ls" -		  left="1" -		  orientation="horizontal" -		  top_pad="0" -		  width="309"> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left="0" -			  name="save_changes_btn_lp" -		      auto_resize="true" -			  width="156"> -			  <button -		         follows="bottom|left|right" -		         height="23" -		         label="[LABEL]" -		         layout="topleft" -		         name="save_changes_btn" -		         left="1" -		         top="0" -		         width="155" />	 -		  </layout_panel> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left_pad="3" -			  name="show_on_map_btn_lp" -		      auto_resize="true" -			  width="157"> -			  <button -		         follows="bottom|left|right" -		         height="23" -		         label="Cancel" -		         layout="topleft" -		         name="cancel_btn" -		         left="1" -		         top="0" -		         width="156" /> -		  </layout_panel> -	   </layout_stack> -    </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml deleted file mode 100644 index 357a5559bf..0000000000 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ /dev/null @@ -1,239 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - bevel_style="in" - follows="left|top|right|bottom" - height="569" - label="Edit Pick" - layout="topleft" - left="0" - min_height="350" - name="panel_edit_pick" - help_topic="profile_edit_pick" - top="0" - width="333"> - <panel.string -  name="location_notice"> -    (will update after save) - </panel.string> -  <button -     follows="top|left" -     height="24" -     image_hover_unselected="BackButton_Over" -     image_pressed="BackButton_Press" -     image_unselected="BackButton_Off" -     layout="topleft" -     name="back_btn" -     left="10" -     tab_stop="false" -     top="4" -     width="30" -     use_draw_context_alpha="false" /> -   <text -     type="string" -     length="1" -     follows="top" -     font="SansSerifHugeBold" -     height="26" -     layout="topleft" -     left_pad="4" -     name="title" -     text_color="LtGray" -     top="4" -     width="250"> -        Edit Pick -    </text> -   <scroll_container -     color="DkGray2" -     follows="all" -     height="501" -     layout="topleft" -     left="8" -     top_pad="9" -     name="profile_scroll" -     opaque="true" -     width="312"> -    <panel -     name="scroll_content_panel" -     follows="left|top|right" -     min_height="300" -     layout="topleft" -     top="0" -     background_visible="false" -     height="500" -     left="0" -     width="285"> -    <texture_picker -     fallback_image="default_land_picture.j2c" -     follows="left|top|right" -     height="197" -     width="272" -     layout="topleft" -     no_commit_on_selection="true" -     top="10" -     left="11" -     name="pick_snapshot" /> -          <icon -           height="197" -           image_name="spacer24.tga" -           layout="topleft" -           name="edit_icon" -           label="" -           tool_tip="Click to select an image" -           top="10" -           left="11" -           width="286" /> -        <text -         type="string" -         length="1" -         follows="left|top|right" -         height="15" -         font="SansSerifSmall" -         font.style="BOLD" -         layout="topleft" -         left="10" -         top="215" -         name="Name:" -         text_color="white" -         width="280"> -            Title: -        </text> -        <line_editor -         follows="left|top|right" -         font="SansSerif" -         height="20" -         layout="topleft" -         left="10" -         top_pad="2" -         max_length_bytes="63" -         name="pick_name" -         text_color="black" -         width="273" /> -        <text -         type="string" -         length="1" -         follows="left|top|right" -         height="15" -         font="SansSerifSmall" -         font.style="BOLD" -         layout="topleft" -         left="10" -         top_pad="20" -         name="description_label" -         text_color="white" -         width="280"> -            Description: -        </text> -        <text_editor -         follows="left|top|right" -         height="100" -         width="273" -         hide_scrollbar="false" -         layout="topleft" -         left="10" -         top_pad="2" -         max_length="1023" -         name="pick_desc" -         spellcheck="true" -         text_color="black" -         word_wrap="true" /> -        <text -         type="string" -         length="1" -         font="SansSerifSmall" -         font.style="BOLD" -         follows="left|top|right" -         height="15" -         layout="topleft" -         left="10" -         name="location_label" -         text_color="white" -         top_pad="20" -         width="280"> -            Location: -        </text> -        <text -         type="string" -         length="1" -         follows="left|top|right" -         height="50" -         layout="topleft" -         left="10" -         name="pick_location" -         top_pad="2" -         width="280" -         word_wrap="true"> -            loading... -        </text> -        <button -         follows="left|top" -         height="23" -         label="Set to Current Location" -         layout="topleft" -         left="8" -         top_pad="0" -         name="set_to_curr_location_btn" -         width="200" /> -    </panel> -    </scroll_container> -    <panel -     follows="left|right|bottom" -     height="23" -     label="bottom_panel" -     layout="topleft" -     left="8" -     name="bottom_panel" -     top_pad="5" -     width="315"> -      -     	 <layout_stack -		  follows="bottom|left|right" -		  height="23" -		  layout="topleft" -		  name="layout_stack1" -		  left="0" -		  orientation="horizontal" -		  top_pad="0" -		  width="313"> -		  	  -		  	 <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="topleft" -			  left="0" -			  name="layout_panel1" -		      auto_resize="true" -			  width="150"> -		        <button -		         follows="bottom|left|right" -		         height="23" -		         label="Save Pick" -		         layout="topleft" -		         name="save_changes_btn" -		         top="0" -		         left="1" -		         width="149" /> -			  </layout_panel> -			   -			 <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="topleft" -			  left_pad="4" -			  name="layout_panel2" -		      auto_resize="true" -			  width="146"> -		        <button -		         follows="bottom|left|right" -		         height="23" -		         label="Cancel" -		         layout="topleft" -		         name="cancel_btn" -		         top="0" -		         left="1" -		        width="145" /> -			  </layout_panel> -	</layout_stack> -		   -    </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml deleted file mode 100644 index 2c7c8133d1..0000000000 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ /dev/null @@ -1,472 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - class="edit_profile_panel" -  follows="all" - height="585" - label="Profile Edit" - layout="topleft" - left="0" - name="edit_profile_panel" -  top="0" - width="313"> -   <string -    name="CaptionTextAcctInfo"> -       [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] -   </string> -   <string  -    name="RegisterDateFormat"> -	[REG_DATE] ([AGE]) -   </string>  -   <string -    name="AcctTypeResident" -    value="Resident" /> -   <string -    name="AcctTypeTrial" -    value="Trial" /> -   <string -    name="AcctTypeCharterMember" -    value="Charter Member" /> -   <string -    name="AcctTypeEmployee" -    value="Linden Lab Employee" /> -   <string -    name="PaymentInfoUsed" -    value="Payment Info Used" /> -   <string -    name="PaymentInfoOnFile" -    value="Payment Info On File" /> -   <string -    name="NoPaymentInfoOnFile" -    value="No Payment Info On File" /> -   <string -    name="AgeVerified" -    value="Age-verified" /> -   <string -    name="NotAgeVerified" -    value="Not Age-verified" /> -   <string -    name="partner_edit_link_url"> -       http://www.secondlife.com/account/partners.php?lang=en -   </string> -   <string -    name="my_account_link_url"> -       http://secondlife.com/my -   </string> -   <string -    name="no_partner_text" -    value="None" /> - <scroll_container -     color="DkGray2" -     follows="all" -     height="537" -     min_height="300" -     layout="topleft" -     left="8" -     width="292" -     name="profile_scroll" -     reserve_scroll_corner="true" -     opaque="true" -     top="10"> -      <panel -         name="scroll_content_panel" -         follows="left|top|right" -         layout="topleft" -         top="0" -     height="537" -     min_height="300" -         left="0" -         width="292"> -    <panel -     name="data_panel" -     follows="left|top|right" -         layout="topleft" -         top="0" -     height="537" -     min_height="300" -         left="0" -         width="292"> -      <text -     top="5" -     follows="top|left" -     height="13" -     layout="topleft" -     left="10" -     name="display_name_label" -     text_color="LtGray" -     value="Display Name:" -     width="80" /> -      <text -     top="5" -     follows="top|left" -     height="13" -     layout="topleft" -     left="10" -     name="solo_username_label" -     text_color="LtGray" -     value="Username:" -     visible="false"  -     width="80" /> -      <button -         name="set_name" -         layout="topleft" -         follows="top|left" -         image_overlay="Edit_Wrench" -         top="21" -         left="10" -         height="23" -         width="23" -         tool_tip="Set Display Name"/> -      <text -       follows="top|left" -       font="SansSerifBigBold" -       height="20" -       layout="topleft" -       left="10" -       name="solo_user_name" -       text_color="white" -       top_delta="3" -       translate="false" -       value="TestString PleaseIgnore" -       use_ellipses="true" -       visible="false" -       width="275" /> -      <text -       follows="top|left" -       font="SansSerifBigBold" -       height="20" -       layout="topleft" -       left="43" -       name="user_name" -       text_color="white" -       top_delta="0" -       translate="false" -       value="TestString PleaseIgnore" -       use_ellipses="true" -       visible="true" -       width="250" /> -      <text -       follows="top|left" -       font="SansSerifBold" -       height="20" -       layout="topleft" -       left_delta="0" -       name="user_name_small" -       text_color="white" -       top_delta="-4" -       translate="false" -       value="TestString PleaseIgnore" -       use_ellipses="true" -       visible="false" -       wrap="true" -       width="245" /> -      <text -    follows="top|left" -    height="13" -    layout="topleft" -    left="10" -    name="user_label" -    text_color="LtGray" -    top_pad="8" -    value="Username:" -    width="70" /> -      <text -       follows="top|left" -       height="20" -       layout="topleft" -       left_pad="0" -       name="user_slid" -       text_color="EmphasisColor" -        font="SansSerifBold" -       top_delta="-2" -       translate="false" -       use_ellipses="true"  -       value="teststring.pleaseignore" -       wrap="true"  -       width="205" /> -     <panel -       name="lifes_images_panel" -         follows="left|top|right" -         height="244" -         layout="topleft" -         top="65" -         left="0" -         width="292"> -	 <panel -         follows="left|top" -         height="117" -         layout="topleft" -         left="10" -         name="second_life_image_panel" -         top="0" -         width="282"> -          <text -             follows="left|top|right" -	     font.style="BOLD" -             height="15" -             layout="topleft" -             left="0" -             top="10" -            name="second_life_photo_title_text" -             text_color="white" -             value="[SECOND_LIFE]:" -             width="100" /> -            <texture_picker -             allow_no_texture="true" -             default_image_name="None" -             enabled="false" -             fallback_image="default_profile_picture.j2c"  -             follows="top|left" -             height="124" -             layout="topleft" -             left="1" -             name="2nd_life_pic" -             top_pad="0" -             width="102" /> -          </panel> -           <icon -           height="102" -           image_name="spacer24.tga" -           layout="topleft" -           name="2nd_life_edit_icon" -           label="" -           left="11" -           top_pad="-92" -           tool_tip="Click to select an image" -           width="102" /> -      </panel> -      <text_editor -       type="string" -       length="1" -       follows="left|top|right" -       font="SansSerifSmall" -       height="102" -       layout="topleft" -       left="123" -       top="90" -       max_length="512" -       name="sl_description_edit" -       width="157" -       word_wrap="true"> -      </text_editor> -      <panel -         follows="left|top" -         height="117" -         layout="topleft" -	 top_pad="5" -         left="10" -         name="first_life_image_panel" -         width="285"> -        <text -             follows="left|top|right" -	     font.style="BOLD" -             height="15" -             layout="topleft" -             left="0" -             top_pad="10" -            name="real_world_photo_title_text" -             text_color="white" -             value="Real World:" -             width="100" /> -            <texture_picker -             allow_no_texture="true" -             default_image_name="None" -             enabled="false" -             fallback_image="Generic_Person_Large" -             follows="top|left" -             height="124" -             layout="topleft" -             left="1" -             name="real_world_pic" -             top_pad="0" -             width="102" /> -          </panel> -           <icon -           height="102" -           image_name="spacer24.tga" -           layout="topleft" -           name="real_world_edit_icon" -           label="" -           left="11" -           top_pad="-92" -           tool_tip="Click to select an image" -           width="102" /> -       <text_editor -       type="string" -       length="1" -       follows="left|top|right" -       font="SansSerifSmall" -       height="102" -       layout="topleft" -       left="123" -       max_length="512" -       top="223" -       name="fl_description_edit" -       width="157" -       word_wrap="true"> -      </text_editor> -      <text -       type="string" -       length="1" -       follows="left|top" -       font="SansSerifSmall" -       font.style="BOLD" -       height="15" -       layout="topleft" -       left="10" -       name="title_homepage_text" -       text_color="white" -       top_pad="10" -       width="100"> -          Homepage: -      </text> -      <line_editor -       follows="left|top|right" -       font="SansSerifSmall" -       height="20" -       layout="topleft" -       left="10" -       top_pad="0" -       value="http://" -       name="homepage_edit" -       width="272"> -      </line_editor> -      <text -         follows="left|top" -         font="SansSerifSmall" -	 font.style="BOLD" -         height="15" -         layout="topleft" -         left="10" -         name="title_acc_status_text" -         text_color="white" -         top_pad="10" -         value="My Account:" -         width="100" /> -        <text_editor -         allow_scroll="false" -         bg_visible="false" -         follows="left|top|right" -         h_pad="0" -         height="28" -         layout="topleft" -         left="10" -         name="acc_status_text" -         read_only="true" -         top_pad="5" -         v_pad="0" -         value="Resident. No payment info on file." -         width="200" -         word_wrap="true" /> -        <text -         type="string" -         follows="left|top" -         font="SansSerifSmall" -         height="15" -         layout="topleft" -         left="10" -         name="my_account_link" -         value="[[URL] Go to My Dashboard]" -         width="200" /> -        <text -         follows="left|top" -         font="SansSerifSmall" -      	 font.style="BOLD" -         height="15" -         layout="topleft" -         left="10" -         name="title_partner_text" -         text_color="white" -         top_pad="10" -         value="My Partner:" -         width="150" /> -        <panel -         follows="left|top|right" -         height="15" -         layout="topleft" -         left="10" -         name="partner_data_panel" -         width="200"> -          <text -           follows="left|top|right" -           height="12" -           initial_value="(retrieving)" -           layout="topleft" -           left="0" -           name="partner_text" -           top="0" -           use_ellipses="true" -           width="280"/> -         </panel> -        <text -         follows="left|top" -         height="15" -         layout="topleft" -           link="true" -         left="10" -         name="partner_edit_link" -         value="[[URL] Edit]" -         width="70" /> -    </panel> -    </panel> -    </scroll_container> -    <panel -       follows="bottom|left|right" -       height="28" -       left="0" -       name="profile_me_buttons_panel" -       top_pad="0" -       width="313"> -        -         <layout_stack -		  follows="bottom|left|right" -		  height="28" -		  layout="topleft" -		  name="bottom_panel_ls" -		  left="7" -		  orientation="horizontal" -		  top_pad="0" -		  width="295"> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  name="save_changes_btn_lp" -			  top="0" -		      auto_resize="true" -			  width="153"> -        <button -		         follows="bottom|left|right" -         height="23" -         label="Save Changes" -         layout="topleft" -		         left="1" -         name="save_btn" -		         top="0" -         width="152" /> -		  </layout_panel> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left_pad="3" -			  name="show_on_map_btn_lp" -			  top="0" -		      auto_resize="true" -			  width="154"> -        <button -		         follows="bottom|left|right" -         height="23" -         label="Cancel" -         layout="topleft" -		         left="1" -         name="cancel_btn" -		         top="0" -         width="153" /> -		  </layout_panel> -	   </layout_stack> -    </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml new file mode 100644 index 0000000000..b72af7221e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="group_list_item" + top="0" + left="0" + height="16" + width="320" + follows="top|right|left" + layout="topleft" +> +    <icon +     name="hovered_icon" +     top="0" +     left="0" +     height="16" +     width="320" +     follows="top|right|left" +     layout="topleft" +     image_name="ListItem_Over" +     visible="false" +    /> +    <icon +     name="selected_icon" +     top="0" +     left="0" +     height="16" +     width="320" +     follows="top|right|left" +     layout="topleft" +     image_name="ListItem_Select" +     visible="false" +    /> +    <group_icon +     name="group_icon" +     top="2" +     left="5" +     height="14" +     width="14" +     image_name="Generic_Group" +     mouse_opaque="true" +     use_draw_context_alpha="false" +    /> +    <text +     name="group_name" +     value="Unknown" +     top="2" +     left_pad="5" +     right="-2" +     height="16" +     follows="left|right" +     layout="topleft" +     parse_urls="false" +     text_color="ScrollUnselectedColor" +     use_ellipses="true" +    /> +    <button +     name="visibility_hide_btn" +     tool_tip="Hide group on my profile" +     top_delta="-3" +     left_pad="3" +     right="-53" +     height="20" +     width="20" +     follows="right" +     image_pressed="Profile_Group_Visibility_Off_Pressed" +     image_unselected="Profile_Group_Visibility_Off" +     tab_stop="false" +     visible="false" +    /> +    <button +     name="visibility_show_btn" +     tool_tip="Show group on my profile" +     top_delta="0" +     right_delta="0" +     height="20" +     width="20" +     follows="right" +     image_pressed="Profile_Group_Visibility_On_Pressed" +     image_unselected="Profile_Group_Visibility_On" +     tab_stop="false" +     visible="false" +    /> +    <button +     name="info_btn" +     tool_tip="More info" +     top_delta="2" +     left_pad="3" +     right="-30" +     height="16" +     width="16" +     follows="right" +     image_pressed="Info_Press" +     image_unselected="Info_Over" +     tab_stop="false" +    /> +    <!--*TODO: Should only appear on rollover--> +    <button +     name="profile_btn" +     tool_tip="View profile" +     top_delta="-2" +     left_pad="5" +     right="-3" +     height="20" +     width="20" +     follows="right" +     layout="topleft" +     image_overlay="Web_Profile_Off" +     tab_stop="false" +    /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml deleted file mode 100644 index 23e7814cad..0000000000 --- a/indra/newview/skins/default/xui/en/panel_me.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - border="false" - follows="all" - height="570" - label="My Profile" - layout="topleft" - left="0" - name="panel_me" - top="0" - width="333"> -    <panel -        class="panel_picks" -        filename="panel_picks.xml" -        label="MY PICKS" -        help_topic="panel_my_picks_tab" -        name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml deleted file mode 100644 index 99c47eb825..0000000000 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ /dev/null @@ -1,190 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - follows="all" - height="570" - layout="topleft" - left="0" - min_height="350" - name="panel_pick_info" - help_topic="profile_pick_info" - top="0" - width="333"> -    <button -     follows="top|left" -     height="24" -     image_hover_unselected="BackButton_Over" -     image_pressed="BackButton_Press" -     image_unselected="BackButton_Off" -     layout="topleft" -     name="back_btn" -     left="10" -     tab_stop="false" -     top="2" -     width="30" -     use_draw_context_alpha="false" /> -    <text -     follows="top|left|right" -     font="SansSerifHugeBold" -     height="26" -     layout="topleft" -     left_pad="4" -     name="title" -     text_color="LtGray" -     top="2" -     value="Pick Info" -     use_ellipses="true" -     width="275" /> -    <scroll_container -     color="DkGray2" -     opaque="true" -     follows="all" -     height="503" -     layout="topleft" -     left="8" -     top_pad="10" -     name="profile_scroll" -     width="312"> -    <panel -     name="scroll_content_panel" -     follows="left|top|right" -     min_height="300" -     layout="topleft" -     top="0" -     background_visible="false" -     height="400" -     left="0" -     width="285"> -        <texture_picker -         fallback_image="default_land_picture.j2c" -         enabled="false" -         follows="left|top|right" -         height="197" -         layout="topleft" -         left="11" -         name="pick_snapshot" -         top="10" -         width="272" /> -        <text_editor -         allow_scroll="false" -         bg_visible="false" -         follows="left|top|right" -         h_pad="0" -         height="35" -         width="280" -         layout="topleft" -         font="SansSerifBig" -         font.style="BOLD" -         left="10" -         top_pad="10" -         name="pick_name" -         read_only="true" -         text_color="white" -         v_pad="0" -         value="[name]" -         use_ellipses="true" /> -        <text_editor -         allow_scroll="false" -         bg_visible="false" -         follows="left|top|right" -         h_pad="0" -         height="25" -         layout="topleft" -         left="10" -         name="pick_location" -         read_only="true" -         width="280" -         word_wrap="true" -         v_pad="0" -         value="[loading...]" /> -        <text_editor -         bg_readonly_color="DkGray2" -         follows="all" -         height="100" -         width="280" -         parse_urls="true"	 -         layout="topleft" -         left="10" -         top_pad="2" -         max_length="1023" -         name="pick_desc" -         read_only="true" -         text_readonly_color="white" -         value="[description]" -         wrap="true" /> -    </panel> -    </scroll_container> -    <panel -     follows="left|right|bottom" -     height="23" -     layout="topleft" -     top_pad="5" -     left="8" -     name="buttons"> -        -       <layout_stack -		  follows="bottom|left|right" -		  height="23" -		  layout="topleft" -		  name="layout_stack1" -		  left="0" -		  orientation="horizontal" -		  top_pad="0" -		  width="312"> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left="0" -			  name="layout_panel1" -		      auto_resize="true" -			  width="101"> -			  <button -			  	 follows="bottom|left|right" -		         height="23" -		         label="Teleport" -		         layout="topleft" -		         name="teleport_btn" -		         top="0" -		         width="101" /> -		  </layout_panel> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left_pad="3" -			  name="show_on_map_btn_lp" -		      auto_resize="true" -			  width="100"> -			  <button -		         follows="bottom|left|right" -		         height="23" -		         label="Map" -		         layout="topleft" -		         name="show_on_map_btn" -		         top_pad="0" -		         width="100" /> -		  </layout_panel>	   -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="23" -			  layout="bottomleft" -			  left_pad="3" -			  name="edit_btn_lp" -		      auto_resize="true" -			  width="101"> -			  <button -		         follows="bottom|left|right" -		         height="23" -		         label="Edit" -		         layout="topleft" -		         name="edit_btn" -		         top_pad="0" -		         width="101" /> -		  </layout_panel> -	   </layout_stack> -    </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml deleted file mode 100644 index 8def96cada..0000000000 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ /dev/null @@ -1,227 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel -bg_opaque_color="DkGray2" -       background_visible="true" -       background_opaque="true" - follows="all" - height="571" - label="Picks" - layout="topleft" - left="8" - name="panel_picks" - top_pad="0" - width="313"> - <string -  name="no_picks" -  value="No Picks" /> - <string -  name="no_classifieds" -  value="No Classifieds" /> - <text -  type="string" -  follows="all" -  height="535" -  layout="topleft" -  left="6" -  name="picks_panel_text" -  wrap="true" -  top="10" -  width="313"/> - <accordion -  fit_parent="true"  -  follows="all" -  height="514" -  layout="topleft" -  left="0" -  name="accordion" -  top="0" -  single_expansion="true" -  width="313"> -    <accordion_tab -     layout="topleft" -     height="235" -     min_height="150" -     name="tab_picks" -     title="Picks" -     visible="false"> - <flat_list_view -         color="DkGray2" -         follows="all" -         layout="topleft" -         left="0" -         name="picks_list" -         opaque="true" -         top="0" -         width="313" /> -    </accordion_tab> -    <accordion_tab -     layout="topleft" -     height="235" -     name="tab_classifieds" -     title="Classifieds" -     visible="false"> -            <flat_list_view -             color="DkGray2" -             follows="all" -             layout="topleft" -             left="0" -             name="classifieds_list" -             opaque="true" -             top="0" -             width="313" /> -    </accordion_tab> - </accordion> -   <panel -       bg_opaque_color="DkGray2" -       background_visible="true" -       background_opaque="true" -       bevel_style="none" -       enabled="false" -       follows="bottom|left|right" -       left="1" -       height="27" -       label="bottom_panel" -       layout="topleft" -       name="edit_panel" -       top_pad="0" -       width="312"> -          -         <layout_stack -		  follows="bottom|left|right" -		  height="23" -		  layout="bottomleft" -		  name="edit_panel_ls" -		  left="10" -		  orientation="horizontal" -		  top_pad="0" -		  width="293"> -		   -		  <layout_panel -			  follows="bottom|left" -			  height="18" -			  layout="bottomleft" -			  left="0" -			  name="gear_menu_btn" -		      auto_resize="true" -			  width="51"> -				<button -	             follows="bottom|left" -	             height="18" -	             image_disabled="AddItem_Disabled" -	             image_selected="AddItem_Press" -	             image_unselected="AddItem_Off" -	             layout="topleft" -	             left="0" -	             name="new_btn" -	             tool_tip="Create a new pick or classified at the current location" -	             top="0" -	             width="18" /> -		  </layout_panel> -		   -		  <layout_panel -			  follows="bottom|right" -			  height="18" -			  layout="bottomleft" -			  name="trash_btn_lp" -		      auto_resize="true" -			  width="18"> -				<button -	             follows="bottom|right" -	             height="18" -	             image_disabled="TrashItem_Disabled" -	             image_selected="TrashItem_Press" -	             image_unselected="TrashItem_Off" -	             layout="topleft" -	             name="trash_btn" -	             top="0" -	             width="18" /> -		  </layout_panel> -		   -	  </layout_stack> -	  </panel> -	   -	  <panel - bg_opaque_color="DkGray" -       background_visible="true" -       background_opaque="true" -         follows="bottom|left|right" -         layout="topleft" -         left="0" -         height="30" -         name="buttons_cucks" -         top_pad="0" -         width="313"> -       -      <layout_stack -		  follows="bottom|left|right" -		  height="28" -		  layout="topleft" -		  left="2" -		  name="buttons_cucks_ls" -		  orientation="horizontal" -		  top="0" -		  width="313"> -		  	   -		  <layout_panel -			  follows="bottom|left|right" -			  height="28" -			  layout="topleft" -			  left="0" -			  name="info_btn_lp" -		      auto_resize="true" -			  top="0" -			  width="95"> -		       <button -		         enabled="false" -		         follows="top|left|right" -		         height="23" -		         label="Info" -		         layout="topleft" -		         name="info_btn" -		         tab_stop="false" -		         tool_tip="Show pick information" -		         width="95" /> -		  </layout_panel> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="28" -			  layout="bottomleft"  -			  left_pad="2" -			  name="teleport_btn_lp" -		      auto_resize="true" -			  width="117"> -		        <button -		         enabled="false" -		         follows="top|left|right" -		         height="23" -		         label="Teleport" -		         layout="topleft" -		         name="teleport_btn" -		         tab_stop="false" -		         tool_tip="Teleport to the corresponding area" -		         width="117" /> -		  </layout_panel> -		   -		  <layout_panel -			  follows="bottom|left|right" -			  height="28" -			  layout="bottomleft" -			  name="show_on_map_btn_lp" -		      auto_resize="true"  -			  left_pad="2" -			  width="90"> -		        <button -		         enabled="false" -		         follows="top|left|right" -		         height="23" -		         label="Map" -		         layout="topleft" -		         name="show_on_map_btn" -		         tab_stop="false" -		         tool_tip="Show the corresponding area on the World Map" -		         width="88" /> -		  </layout_panel> -	</layout_stack> -	</panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml new file mode 100644 index 0000000000..c9e8b242d4 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml @@ -0,0 +1,830 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_profile_classified" + top="0" + left="0" + height="420" + width="315" + follows="all" + layout="topleft" + help_topic="panel_profile_classified" + min_height="250" +> +    <panel.string +     name="type_mature" +    > +        Moderate +    </panel.string> +    <panel.string +     name="type_pg" +    > +        General Content +    </panel.string> +    <panel.string +     name="l$_price" +    > +        L$[PRICE] +    </panel.string> +    <panel.string +     name="click_through_text_fmt" +    > +        [TELEPORT] teleport, [MAP] map, [PROFILE] profile +    </panel.string> +    <panel.string +     name="date_fmt" +    > +        [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +    </panel.string> +    <panel.string +     name="auto_renew_on" +    > +        Enabled +    </panel.string> +    <panel.string +     name="auto_renew_off" +    > +        Disabled +    </panel.string> +    <panel.string +     name="location_notice" +    > +        (will update after save) +    </panel.string> +    <string +     name="publish_label" +    > +        Publish +    </string> +    <string +     name="save_label" +    > +        Save +    </string> + +  <layout_stack +   name="main_classifieds_stack" +   top="0" +   bottom="-1" +   left="0" +   width="310" +   follows="all" +   layout="topleft" +   orientation="vertical" +   animate="false" +    > +    <layout_panel +     follows="all" +     width="310" +     height="300" +     layout="topleft" +     name="scroll_layout_panel" +     auto_resize="true"> +      <scroll_container +       name="profile_scroll" +       top="0" +       left="0" +       height="300" +       width="310" +       follows="all" +       layout="topleft" +       color="DkGray2" +       opaque="true" +       reserve_scroll_corner="false" +      > +        <panel +         name="info_scroll_content_panel" +         top="0" +         left="0" +         height="562" +         width="280" +         follows="left|top|right" +         layout="topleft" +         background_visible="false" +         min_height="200" +        > +            <texture_picker +             name="classified_snapshot" +             enabled="false" +             top="0" +             left="10" +             height="161" +             width="260" +             follows="left|top" +             layout="topleft" +             fallback_image="default_land_picture.j2c" +            /> +            <icon +             name="edit_icon" +             label="" +             tool_tip="Click to select an image" +             top="0" +             left="0" +             height="161" +             width="260" +             layout="topleft" +             follows="left|top" +             image_name="spacer24.tga" +             visible="false" +            /> +            <layout_stack +             name="info_panel" +             top="145" +             left="0" +             height="375" +             width="310" +             follows="all" +             layout="topleft" +             visible="true" +             animate="false" +             orientation="vertical" +             > +                <layout_panel +                 name="main_info_panel" +                 top="0" +                 left="0" +                 height="160" +                 width="280" +                 follows="all" +                 layout="topleft" +                 auto_resize="false" +                    > +                    <text_editor +                     name="classified_name" +                     top="0" +                     left="10" +                     height="35" +                     width="270" +                     follows="left|top|right" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     font="SansSerifBig" +                     font.style="BOLD" +                     h_pad="0" +                     read_only="true" +                     text_color="white" +                     use_ellipses="true" +                     v_pad="0" +                     > +                        [name] +                    </text_editor> +                    <text +                     name="classified_location_label" +                     value="Location:" +                     top_pad="-2" +                     left="10" +                     height="10" +                     width="250" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text_editor +                     name="classified_location" +                     value="[loading...]" +                     top_pad="5" +                     left="10" +                     height="30" +                     width="280" +                     follows="left|top" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     read_only="true" +                     v_pad="0" +                     word_wrap="true" +                     /> +                    <text +                     name="content_type_label" +                     value="Content Type:" +                     top_pad="10" +                     left="10" +                     height="10" +                     width="140" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <icon +                     name="content_type_moderate" +                     top_pad="-11" +                     left_pad="0" +                     height="16" +                     width="18" +                     follows="top|left" +                     layout="topleft" +                     image_name="Parcel_M_Light" +                     /> +                    <icon +                     name="content_type_general" +                     top_delta="0" +                     left_delta="0" +                     height="16" +                     width="18" +                     follows="top|left" +                     layout="topleft" +                     image_name="Parcel_PG_Light" +                     /> +                    <text_editor +                     name="content_type" +                     value="[content type]" +                     top_delta="1" +                     left_pad="2" +                     height="18" +                     width="130" +                     follows="left|top|right" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     read_only="true" +                     v_pad="0" +                     /> +                    <text +                     name="category_label" +                     value="Category:" +                     top_pad="0" +                     left="10" +                     height="10" +                     width="140" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text_editor +                     name="category" +                     value="[category]" +                     top_pad="-10" +                     left_pad="0" +                     height="18" +                     width="150" +                     follows="left|top|right" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     parse_urls="true" +                     read_only="true" +                     v_pad="0" +                     /> +                    <text +                     name="creation_date_label" +                     value="Creation date:" +                     top_pad="0" +                     left="10" +                     height="10" +                     width="140" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text_editor +                     name="creation_date" +                     value="[date]" +                     tool_tip="Creation date" +                     top_pad="-10" +                     left_pad="0" +                     height="16" +                     width="150" +                     follows="left|top" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     halign="left" +                     read_only="true" +                     v_pad="0" +                     /> +                    <text +                     name="price_for_listing_label" +                     value="Price for listing:" +                     top_pad="5" +                     left="10" +                     height="10" +                     width="140" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text_editor +                     name="price_for_listing" +                     tool_tip="Price for listing." +                     top_pad="-10" +                     left_pad="0" +                     height="16" +                     width="105" +                     follows="left|top" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     halign="left" +                     read_only="true" +                     v_pad="0" +                     > +                     [PRICE] +                    </text_editor> +                </layout_panel> +                <layout_panel +                 name="clickthrough_layout_panel" +                 top="0" +                 left="0" +                 height="16" +                 width="290" +                 follows="all" +                 layout="topleft" +                 auto_resize="false" +                 > +                    <text +                     name="click_through_label" +                     value="Clicks:" +                     top_pad="0" +                     left="10" +                     height="10" +                     width="140" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text_editor +                     name="click_through_text" +                     value="[clicks]" +                     tool_tip="Click through data" +                     top_pad="-10" +                     left_pad="0" +                     height="16" +                     width="150" +                     follows="left|top" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     halign="left" +                     read_only="true" +                     v_pad="0" +                     /> +                </layout_panel> +                <layout_panel +                 name="auto_renew_layout_panel" +                 top="0" +                 left="0" +                 height="16" +                 width="290" +                 follows="all" +                 layout="topleft" +                 auto_resize="false" +                 > +                    <text +                     name="auto_renew_label" +                     value="Auto renew:" +                     top="0" +                     left="10" +                     height="10" +                     width="140" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text +                     name="auto_renew" +                     value="Enabled" +                     top_pad="-10" +                     left_pad="0" +                     height="16" +                     width="150" +                     follows="top|left" +                     layout="topleft" +                     /> +                </layout_panel> +                <layout_panel +                 name="descr_layout_panel" +                 top="0" +                 left="0" +                 height="220" +                 width="290" +                 follows="all" +                 layout="topleft" +                 auto_resize="true" +                 > +                    <text +                     name="classified_desc_label" +                     value="Description:" +                     top="0" +                     left="10" +                     height="10" +                     width="250" +                     follows="left|top" +                     layout="topleft" +                     font.style="BOLD" +                     text_color="white" +                     /> +                    <text_editor +                     name="classified_desc" +                     trusted_content="false" +                     value="[description]" +                     top_pad="7" +                     left="10" +                     height="200" +                     width="280" +                     follows="all" +                     layout="topleft" +                     allow_scroll="false" +                     bg_visible="false" +                     h_pad="0" +                     max_length="1023" +                     parse_urls="true" +                     read_only="true" +                     v_pad="0" +                     word_wrap="true" +                     /> +                </layout_panel> +            </layout_stack> +            <panel +             name="edit_panel" +             top="145" +             left="0" +             height="420" +             width="320" +             follows="left|top|right" +             layout="topleft" +             visible="false" +            > +                <text +                 name="Name:" +                 top="0" +                 left="10" +                 height="15" +                 width="280" +                 follows="left|top" +                 layout="topleft" +                 font="SansSerifSmall" +                 font.style="BOLD" +                 length="1" +                 text_color="white" +                 type="string" +                > +                    Title: +                </text> +                <line_editor +                 name="classified_name_edit" +                 top_pad="2" +                 left="10" +                 height="20" +                 width="273" +                 follows="left|top|right" +                 layout="topleft" +                 font="SansSerif" +                 max_length_bytes="30" +                 prevalidate_callback="ascii" +                 commit_on_focus_lost="false" +                 text_color="black" +                /> +                <text +                 name="description_label" +                 top_pad="10" +                 left="10" +                 height="15" +                 width="280" +                 follows="left|top" +                 layout="topleft" +                 font="SansSerifSmall" +                 font.style="BOLD" +                 length="1" +                 text_color="white" +                 type="string" +                > +                    Description: +                </text> +                <text_editor +                 name="classified_desc_edit" +                 top_pad="2" +                 left="10" +                 height="100" +                 width="273" +                 follows="left|top|right" +                 layout="topleft" +                 max_length="256" +                 text_color="black" +                 word_wrap="true" +                /> +                <text +                 name="location_label" +                 top_pad="10" +                 left="10" +                 height="15" +                 width="280" +                 follows="left|top" +                 layout="topleft" +                 font="SansSerifSmall" +                 font.style="BOLD" +                 length="1" +                 text_color="white" +                 type="string" +                > +                    Location: +                </text> +                <text +                 name="classified_location_edit" +                 top_pad="2" +                 left="10" +                 right="-10" +                 height="30" +                 width="280" +                 follows="left|top" +                 layout="topleft" +                 length="1" +                 type="string" +                 word_wrap="true" +                > +                    loading... +                </text> +                <button +                 name="set_to_curr_location_btn" +                 label="Set to Current Location" +                 top_pad="5" +                 left="10" +                 height="23" +                 width="200" +                 follows="left|top" +                 layout="topleft" +                /> +                <text +                 name="category_label" +                 value="Category:" +                 top_pad="10" +                 left="10" +                 height="10" +                 width="120" +                 follows="left|top" +                 layout="topleft" +                 font.style="BOLD" +                 text_color="white" +                /> +                <combo_box +                 name="category_edit" +                 label="" +                 top_delta="-3" +                 left_pad="0" +                 height="23" +                 width="156" +                 follows="left|top" +                /> +                <text +                 name="content_type_label" +                 value="Content type:" +                 top_pad="15" +                 left="10" +                 height="10" +                 width="120" +                 follows="left|top" +                 layout="topleft" +                 font.style="BOLD" +                 text_color="white" +                /> +                <icons_combo_box +                 name="content_type_edit" +                 label="General Content" +                 top_delta="-3" +                 left_pad="0" +                 height="23" +                 width="156" +                 follows="left|top" +                 layout="topleft" +                > +                    <icons_combo_box.drop_down_button +                     image_overlay="Parcel_PG_Light" +                     image_overlay_alignment="left" +                     imgoverlay_label_space="3" +                     pad_left="3" +                    /> +                    <icons_combo_box.item +                     name="mature_ci" +                     label="Moderate Content" +                     value="Mature" +                    > +                        <item.columns +                         value="Parcel_M_Light" +                         width="20" +                         halign="center" +                         type="icon" +                        /> +                    </icons_combo_box.item> +                    <icons_combo_box.item +                     name="pg_ci" +                     label="General Content" +                     value="PG" +                    > +                        <item.columns +                         value="Parcel_PG_Light" +                         width="20" +                         halign="center" +                         type="icon" +                        /> +                    </icons_combo_box.item> +                </icons_combo_box> +                <check_box +                 name="auto_renew_edit" +                 label="Auto renew each week" +                 top_pad="10" +                 left="10" +                 height="16" +                 width="250" +                 layout="topleft" +                /> +              </panel> +        </panel> +      </scroll_container> +    </layout_panel> + +    <layout_panel +     follows="all" +     width="310" +     height="25" +     layout="topleft" +     name="util_buttons_lp" +     auto_resize="true"> +      <layout_stack +       name="util_buttons_stack" +       bottom="-1" +       left="1" +       right="-1" +       height="25" +       follows="left|bottom|right" +       layout="topleft" +       orientation="horizontal" +       animate="false" +      > +        <layout_panel +         follows="all" +         layout="topleft" +         name="util_resizer_left" +         auto_resize="true" +         user_resize="false" +         width="1"/> +         +        <layout_panel +            follows="all" +            height="25" +            layout="topleft" +            left="0" +            name="teleport_btn_lp" +            auto_resize="false" +            top="0" +            width="85"> +            <button +             name="teleport_btn" +             label="Teleport" +             top="0" +             left="0" +             height="23" +             max_width="101" +             width="85" +             follows="bottom|left|right" +             layout="topleft" +             /> +        </layout_panel> + +        <layout_panel +            follows="all" +            height="25" +            layout="bottomleft" +            left_pad="2" +            name="map_btn_lp" +            auto_resize="false" +            max_width="101" +            width="85"> +            <button +             name="show_on_map_btn" +             label="Map" +             top="0" +             left="0" +             height="23" +             width="85" +             follows="bottom|left|right" +             layout="topleft" +             /> +        </layout_panel> + +        <layout_panel +            follows="all" +            height="25" +            layout="bottomleft" +            left_pad="2" +            name="edit_btn_lp" +            auto_resize="false" +            max_width="101" +            width="85"> +            <button +             name="edit_btn" +             label="Edit" +             top="0" +             left="0" +             height="23" +             width="85" +             follows="bottom|left|right" +             layout="topleft" +             /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="topleft" +         name="util_resizer_right" +         auto_resize="true" +         width="1"> +        </layout_panel> +      </layout_stack> +    </layout_panel> +    <layout_panel +     follows="all" +     width="310" +     height="41" +     layout="topleft" +     name="publish_layout_panel" +     auto_resize="false"> +      <view_border +          bevel_style="none" +          height="0" +          follows="left|top|right" +          layout="topleft" +          left="0" +          name="publish_emphasis_border" +          top="5" +          width="310"/> +      <layout_stack +       name="publish_stack" +       left="1" +       right="-1" +       top="11" +       height="25" +       follows="left|top|right" +       layout="topleft" +       orientation="horizontal" +       animate="false" +      > +        <layout_panel +         follows="all" +         layout="topleft" +         name="pbl_resizer_left" +         auto_resize="true" +         user_resize="false" +         width="1"/> +         +        <layout_panel +         follows="all" +         layout="topleft" +         name="save_btn_lp" +         auto_resize="false" +         width="134"> +          <button +           name="save_changes_btn" +           label="[LABEL]" +           top="0" +           left="0" +           left_pad="5" +           height="23" +           width="134" +           follows="left|top" +           layout="topleft" +             /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="bottomleft" +         left_pad="2" +         name="cancel_btn_lp" +         auto_resize="false" +         width="134"> +          <button +           name="cancel_btn" +           label="Cancel" +           top="0" +           left="0" +           height="23" +           width="134" +           follows="left|top" +           layout="topleft" +             /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="topleft" +         name="pbl_resizer_right" +         auto_resize="true" +         width="1"> +        </layout_panel> +         +      </layout_stack> +    </layout_panel> +  </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml new file mode 100644 index 0000000000..2b2f60e0c2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml @@ -0,0 +1,142 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_profile_classifieds" + label="Classified" + top="0" + left="0" + height="480" + width="420" + follows="all" + layout="topleft" +> +    <string +     name="no_classifieds" +     value="No Classifieds" +    /> + +  <layout_stack +   name="main_stack" +   top="0" +   left="0" +   right="-1" +   bottom="-1" +   follows="all" +   layout="topleft" +   animate="false" +   orientation="vertical"> +    <layout_panel +     name="buttons_header" +     follows="all" +     layout="topleft" +     height="50" +     auto_resize="false" +     user_resize="false"> +      <button +       name="new_btn" +       label="New..." +       tool_tip="Create a new classified at the current location" +       enabled="false" +       top="25" +       left="5" +       height="20" +       width="70" +       follows="left|top" +       layout="topleft" +       visible="true" +      /> +      <button +       name="delete_btn" +       label="Delete..." +       tool_tip="Delete currently selected classified" +       enabled="false" +       left_pad="5" +       height="20" +       width="70" +       follows="left|top" +       layout="topleft" +       visible="true" +      /> +    </layout_panel> +    <layout_panel +     name="main_body" +     follows="all" +     layout="topleft" +     height="430" +     auto_resize="true" +     user_resize="false"> +      <tab_container +       name="tab_classifieds" +       top="0" +       bottom="-1" +       left="4" +       right="-4" +       follows="all" +       layout="topleft" +       halign="left" +       tab_position="left" +       tab_width="150" +       use_ellipses="true" +      /> + +      <layout_stack +       name="indicator_stack" +       top="220" +       left="0" +       right="-1" +       height="28" +       follows="top|left|right" +       layout="topleft" +       animate="false" +       orientation="horizontal"> +        <layout_panel +         name="indicator_spacer_left" +         follows="all" +         layout="topleft" +         width="100" +         auto_resize="true" +         user_resize="false"> +        </layout_panel> +        <layout_panel +         name="buttons_header" +         follows="all" +         layout="topleft" +         width="25" +         auto_resize="false" +         user_resize="false"> +          <loading_indicator +           name="progress_indicator" +           top="1" +           left="1" +           height="23" +           width="23" +           follows="top|left" +           layout="topleft" +           visible="false" +            /> +        </layout_panel> +        <layout_panel +         name="indicator_spacer_right" +         follows="all" +         layout="topleft" +         width="100" +         auto_resize="true" +         user_resize="false"> +        </layout_panel> +      </layout_stack> +      <text +       name="classifieds_panel_text" +       top="250" +       left="110" +       right="-110" +       height="25" +       follows="left|top|right" +       layout="topleft" +       halign="center" +       mouse_opaque="false" +       wrap="true" +      > +          Loading... +      </text> +    </layout_panel> +  </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml new file mode 100644 index 0000000000..ca1e405a62 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_profile_firstlife" + label="Profile" + top="0" + left="0" + height="480" + width="420" + follows="all" + layout="topleft" +> +    <loading_indicator +     name="progress_indicator" +     top="5" +     right="-10" +     height="23" +     width="23" +     follows="top|right" +     layout="topleft" +     visible="false" +    /> +    <icon +     name="real_world_pic" +     image_name="Generic_Person_Large" +     follows="top|left" +     layout="topleft" +     top="10" +     left="8" +     height="160" +     width="160"/> +    <loading_indicator +     name="image_upload_indicator" +     top="79" +     left="77" +     height="23" +     width="23" +     follows="top|left" +     layout="topleft" +     visible="false"/> +    <button +     name="fl_upload_image" +     label="Upload Photo" +     top="102" +     left="175" +     height="20" +     width="120" +     follows="top|left" +     layout="topleft"/> +    <button +     name="fl_change_image" +     label="Change Photo" +     top_pad="5" +     left="175" +     height="20" +     width="120" +     follows="top|left" +     layout="topleft"/> +    <button +     name="fl_remove_image" +     label="Remove Photo" +     top_pad="5" +     left_delta="0" +     height="20" +     width="120" +     follows="top|left" +     layout="topleft"/> +    <text_editor +     name="fl_description_edit" +     trusted_content="false" +     enabled="false" +     top="180" +     left="6" +     right="-6" +     height="224" +     follows="all" +     layout="topleft" +     bg_readonly_color="Transparent" +     border_visible="true" +     max_length="65000" +     parse_urls="true" +     word_wrap="true" +    /> +    <button +     name="fl_save_changes" +     label="Save" +     top_pad="5" +     right="-108" +     height="20" +     width="80" +     enabled="false" +     follows="right|bottom" +     layout="topleft"/> +    <button +     name="fl_discard_changes" +     label="Discard" +     top_delta="0" +     right="-4" +     height="20" +     width="100" +     enabled="false" +     follows="right|bottom" +     layout="topleft"/> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_notes.xml new file mode 100644 index 0000000000..16e7365042 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_notes.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_notes" + label="Notes & Privacy" + top="0" + left="0" + height="480" + width="420" + follows="all" + layout="topleft" +> +    <loading_indicator +     name="progress_indicator" +     top="3" +     right="-10" +     height="23" +     width="23" +     follows="top|right" +     layout="topleft" +     visible="false" +    /> +    <text +     name="status_message" +     value="Make notes about this person here. No one else can see your notes." +     top="6" +     left="6" +     right="-6" +     height="16" +     follows="left|top|right" +     layout="topleft" +     font.style="BOLD" +    /> +    <text_editor +     name="notes_edit" +     enabled="false" +     top="28" +     left="6" +     right="-6" +     bottom="-26" +     follows="all" +     layout="topleft" +     max_length="65530" +     word_wrap="true" +    /> +    <button +     name="notes_save_changes" +     label="Save" +     bottom="-1" +     right="-108" +     height="20" +     width="80" +     enabled="false" +     follows="bottom|right" +     layout="topleft"/> +    <button +     name="notes_discard_changes" +     label="Discard" +     bottom="-1" +     right="-4" +     height="20" +     width="100" +     enabled="false" +     follows="bottom|right" +     layout="topleft"/> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml new file mode 100644 index 0000000000..3e91640093 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml @@ -0,0 +1,314 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_pick_info" + top="0" + left="0" + height="360" + width="310" + follows="all" + layout="topleft" + help_topic="profile_pick_info" +> +    <panel.string +     name="location_notice" +    > +        (will update after save) +    </panel.string> + +  <layout_stack +   name="main_pick_stack" +   left="1" +   right="-1" +   top="0" +   bottom="-1" +   follows="all" +   layout="topleft" +   orientation="vertical" +   animate="false"> +    <layout_panel +     follows="all" +     layout="bottomleft" +     left_pad="2" +     name="main_pick_lp" +     auto_resize="true" +     height="314"> +      <texture_picker +       name="pick_snapshot" +       top="10" +       left="10" +       height="161" +       width="260" +       follows="left|top" +       layout="topleft" +       fallback_image="default_land_picture.j2c" +      /> +      <text +       name="title_label" +       top_pad="-15" +       left="10" +       height="15" +       width="280" +       follows="left|top" +       layout="topleft" +       font="SansSerifSmall" +       font.style="BOLD" +       length="1" +       text_color="white" +       type="string" +                > +        Title: +      </text> +      <line_editor +       name="pick_name" +       enabled="false" +       top_pad="2" +       left="10" +       height="20" +       width="290" +       follows="left|right|top" +       layout="topleft" +      /> +      <text +       name="description_label" +       top_pad="10" +       left="10" +       height="15" +       width="280" +       follows="left|top" +       layout="topleft" +       font="SansSerifSmall" +       font.style="BOLD" +       length="1" +       text_color="white" +       type="string" +                > +        Description: +      </text> +      <text_editor +       name="pick_desc" +       trusted_content="false" +       always_show_icons="true" +       enabled="false" +       top_pad="2" +       left="10" +       height="45" +       width="290" +       follows="all" +       layout="topleft" +       allow_html="true" +       border_visible="true" +       h_pad="4" +       max_length="1023" +       v_pad="3" +       word_wrap="true" +      /> +      <text +       name="location_label" +       bottom="-25" +       left="10" +       height="15" +       width="280" +       follows="left|right|bottom" +       layout="topleft" +       font="SansSerifSmall" +       font.style="BOLD" +       length="1" +       text_color="white" +       type="string" +                > +        Location: +      </text> +      <line_editor +       name="pick_location" +       enabled="false" +       bottom="-1" +       left="10" +       height="23" +       width="290" +       follows="left|right|bottom" +       layout="topleft" +       length="1" +       type="string" +      > +          Loading... +      </line_editor> +    </layout_panel> + + +    <layout_panel +     follows="all" +     layout="bottomleft" +     name="save_changes_lp" +     auto_resize="false" +     height="25"> +      <layout_stack +       name="save_changes_stack" +       left="1" +       right="-1" +       top="0" +       height="25" +       follows="left|top|right" +       layout="topleft" +       orientation="horizontal" +       animate="false"> + +        <layout_panel +         follows="all" +         layout="topleft" +         name="util_resizer_left" +         auto_resize="true" +         width="1"> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="bottomleft" +         left_pad="2" +         name="map_btn_lp" +         auto_resize="false" +         width="100"> +          <button +           name="show_on_map_btn" +           label="Show on Map" +           left="0" +           top="0" +           height="23" +           width="100" +           follows="left|top" +           layout="topleft" +      /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="bottomleft" +         left_pad="2" +         name="tp_btn_lp" +         auto_resize="false" +         width="100"> +          <button +           name="teleport_btn" +           label="Teleport" +           left="0" +           top="0" +           height="23" +           width="100" +           follows="left|top" +           layout="topleft" +          /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="topleft" +         name="util_resizer_right" +         auto_resize="true" +         width="1"> +        </layout_panel> + +      </layout_stack> +    </layout_panel> + +    <layout_panel +     follows="all" +     layout="bottomleft" +     name="save_changes_lp" +     auto_resize="false" +     height="41"> +      <view_border +          bevel_style="none" +          height="0" +          follows="left|top|right" +          layout="topleft" +          left="0" +          name="save_emphasis_border" +          top="5" +          width="310"/> +      <layout_stack +       name="save_changes_stack" +       left="1" +       right="-1" +       top="11" +       height="25" +       follows="left|top|right" +       layout="topleft" +       orientation="horizontal" +       animate="false"> + +        <layout_panel +         follows="all" +         layout="topleft" +         name="save_resizer_left" +         auto_resize="true" +         width="1"> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="bottomleft" +         left_pad="2" +         name="create_btn_lp" +         auto_resize="false" +         width="130"> +          <button +           name="create_changes_btn" +           label="Create Pick" +           left="0" +           top="0" +           height="23" +           width="130" +           follows="left|top" +           layout="topleft" +          /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="bottomleft" +         left_pad="2" +         name="save_btn_lp" +         auto_resize="false" +         width="130"> +          <button +           name="save_changes_btn" +           label="Save Pick" +           left="0" +           top="0" +           height="23" +           width="130" +           follows="left|top" +           layout="topleft" +          /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="bottomleft" +         left_pad="2" +         name="cancel_btn_lp" +         auto_resize="false" +         width="130"> +          <button +           name="cancel_changes_btn" +           label="Cancel" +           left="0" +           top="0" +           height="23" +           width="130" +           follows="left|top" +           layout="topleft" +          /> +        </layout_panel> + +        <layout_panel +         follows="all" +         layout="topleft" +         name="save_resizer_right" +         auto_resize="true" +         width="1"> +        </layout_panel> + +      </layout_stack> +    </layout_panel> +  </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml new file mode 100644 index 0000000000..44d5c448c0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_picks" + label="Picks" + top="0" + left="0" + height="480" + width="420" + follows="all" + layout="topleft" +> +    <string +     name="no_picks" +     value="No Picks" +    /> + +  <layout_stack +   name="main_stack" +   top="0" +   left="0" +   right="-1" +   bottom="-1" +   follows="all" +   layout="topleft" +   animate="false" +   orientation="vertical"> +    <layout_panel +     name="buttons_header" +     follows="all" +     layout="topleft" +     height="50" +     auto_resize="false" +     user_resize="false"> +      <text +       name="header_text" +       top="5" +       left="5" +       right="-5" +       height="16" +       follows="left|top|right" +       layout="topleft" +       halign="center" +    > +        Tell everyone about your favorite places in Second Life. +      </text> +      <button +       name="new_btn" +       label="New..." +       tool_tip="Create a new pick at the current location" +       enabled="false" +       top_pad="4" +       left="5" +       height="20" +       width="70" +       follows="left|top" +       layout="topleft" +       visible="false" +    /> +      <button +       name="delete_btn" +       label="Delete..." +       tool_tip="Delete currently selected pick" +       enabled="false" +       left_pad="5" +       height="20" +       width="70" +       follows="left|top" +       layout="topleft" +       visible="false" +    /> +    </layout_panel> +    <layout_panel +     name="main_body" +     follows="all" +     layout="topleft" +     height="430" +     auto_resize="true" +     user_resize="false"> +      <tab_container +       name="tab_picks" +       top="0" +       bottom="-5" +       left="4" +       right="-4" +       tab_width="150" +       follows="all" +       layout="topleft" +       halign="left" +       tab_position="left" +       use_ellipses="true" +    /> +       +    <layout_stack +     name="indicator_stack" +     top="220" +     left="0" +     right="-1" +     height="28" +     follows="top|left|right" +     layout="topleft" +     animate="false" +     orientation="horizontal"> +      <layout_panel +       name="indicator_spacer_left" +       follows="all" +       layout="topleft" +       width="100" +       auto_resize="true" +       user_resize="false"> +      </layout_panel> +      <layout_panel +       name="buttons_header" +       follows="all" +       layout="topleft" +       width="25" +       auto_resize="false" +       user_resize="false"> +        <loading_indicator +         name="progress_indicator" +         top="1" +         left="1" +         height="23" +         width="23" +         follows="top|left" +         layout="topleft" +         visible="false" +        /> +      </layout_panel> +      <layout_panel +       name="indicator_spacer_right" +       follows="all" +       layout="topleft" +       width="100" +       auto_resize="true" +       user_resize="false"> +      </layout_panel> +    </layout_stack> +    <text +       name="picks_panel_text" +       top="250" +       left="100" +       right="-100" +       height="25" +       follows="left|top|right" +       layout="topleft" +       halign="center" +       mouse_opaque="false" +       wrap="true" +    > +        Loading... +      </text> +    </layout_panel> +  </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml new file mode 100644 index 0000000000..551b477876 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -0,0 +1,549 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_profile" + label="Profile" + top="0" + left="0" + height="480" + width="420" + follows="all" + layout="topleft" +> +   <string  +    name="date_format" +    value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" /> +   <string +    name="age_format" +    value="[AGE]" /> +   <string +    name="partner_text" +    value="Partner: [LINK]" /> +   <string +    name="CaptionTextAcctInfo"> +Account: [ACCTTYPE] +[PAYMENTINFO] +    </string> + +  <layout_stack +   name="image_stack" +   top="8" +   left="6" +   bottom="-1" +   width="160" +   border_size="0" +   follows="left|top|bottom" +   layout="topleft" +   animate="false" +   orientation="vertical"> +    <layout_panel +     name="image_panel" +     follows="all" +     layout="topleft" +     width="160" +     height="160" +     auto_resize="false" +     user_resize="false"> + +      <icon +       name="2nd_life_pic" +       image_name="Generic_Person_Large" +       layout="topleft" +       follows="all" +       interactable="true" +       top="0" +       left="2" +       bottom="-1" +       right="-1"/> + +      <loading_indicator +       name="image_upload_indicator" +       top="69" +       left="69" +       height="23" +       width="23" +       follows="top|left" +       layout="topleft" +       visible="false"/> +    </layout_panel> + +    <layout_panel +     name="basics_panel" +     follows="all" +     layout="topleft" +     height="54" +     auto_resize="false" +     user_resize="false" +        > +      <line_editor +       name="user_name" +       border_thickness="0" +       use_bg_color="false" +       background_image_disabled="" +       background_image_focused="" +       enabled="false" +       value="(loading...)" +       top="4" +       left="3" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft"/> + +      <line_editor +       name="sl_birth_date" +       border_thickness="0" +       use_bg_color="false" +       background_image_disabled="" +       background_image_focused="" +       enabled="false" +       value="(loading...)" +       top_pad="0" +       left_delta="0" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft"/> + +      <line_editor +       name="user_age" +       border_thickness="0" +       use_bg_color="false" +       background_image_disabled="" +       background_image_focused="" +       enabled="false" +       value="(loading...)" +       top_pad="0" +       left_delta="0" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft"/> +    </layout_panel> +    <layout_panel +     name="partner_layout" +     follows="all" +     layout="topleft" +     height="30" +     auto_resize="false" +     user_resize="false" +     visible="true"> +      <text +       type="string" +       name="partner_link" +       value="Partner: (loading...)" +       top="0" +       left="5" +       right="-1" +       height="28" +       follows="left|top|right" +       layout="topleft" +       translate="false" +       use_ellipses="true" +       word_wrap="true" +       visible="true"/> +    </layout_panel> + +    <layout_panel +     name="partner_spacer_layout" +     follows="all" +     layout="topleft" +     height="14" +     auto_resize="false" +     user_resize="false" +     visible="true"> +    </layout_panel> +     +    <layout_panel +     name="frind_layout" +     follows="all" +     layout="topleft" +     height="16" +     auto_resize="false" +     user_resize="false" +     visible="false"> +      <text +       name="frind_text" +       value="You are friends" +       text_color="ConversationFriendColor" +       top="0" +       left="5" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft" +       translate="false" +       visible="true"/> +    </layout_panel> +    <layout_panel +     name="online_layout" +     follows="all" +     layout="topleft" +     height="16" +     auto_resize="false" +     user_resize="false" +     visible="false"> +      <icon +       name="online_icon" +       image_name="Profile_Friend_Online" +       layout="topleft" +       follows="left|top" +       top="0" +       left="5" +       height="10" +       width="10"/> +      <text +       name="online_text" +       value="Online" +       top="0" +       left="18" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft" +       translate="false" +       visible="true"/> +    </layout_panel> +    <layout_panel +     name="offline_layout" +     follows="all" +     layout="topleft" +     height="16" +     auto_resize="false" +     user_resize="false" +     visible="false"> +      <icon +       name="offline_icon" +       image_name="Profile_Friend_Offline" +       layout="topleft" +       follows="left|top" +       top="0" +       left="5" +       height="10" +       width="10"/> +      <text +       name="offline_text" +       value="Offline" +       top="0" +       left="18" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft" +       translate="false" +       visible="true"/> +    </layout_panel> +    <layout_panel +     name="account_layout" +     follows="all" +     layout="topleft" +     height="33" +     auto_resize="false" +     user_resize="false"> +      <text +       name="account_info" +       value="Account: (loading...)" +       top="0" +       left="5" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft" +       word_wrap="true"/> +    </layout_panel> +    <layout_panel +     name="indicator_stack" +     follows="all" +     layout="topleft" +     height="33" +     auto_resize="false" +     user_resize="false"> +      <loading_indicator +       name="progress_indicator" +       left="67" +       top="0" +       height="23" +       width="23" +       follows="left|top" +       layout="topleft" +       visible="true"/> +    </layout_panel> +    <layout_panel +     name="settings_panel" +     follows="all" +     layout="topleft" +     height="50" +     auto_resize="false" +     user_resize="false"> +      <!-- only for self --> +      <text +       name="search_label" +       value="Show my profile in search:" +       top="1" +       left="6" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft"/> +      <combo_box +       name="show_in_search" +       tool_tip="Let people see you in search results" +       left="1" +       top="18" +       height="23" +       width="140" +       follows="left|top" +       layout="topleft" +       visible="true" +       enabled="false"> +        <combo_box.item +           name="Hide" +           label="Hide" +           value="0" /> +        <combo_box.item +           name="Show" +           label="Show" +           value="1" /> +      </combo_box> +    </layout_panel> +     +    <layout_panel +     name="menu_panel" +     follows="all" +     layout="topleft" +     height="55" +     auto_resize="false" +     user_resize="false" +        > +      <menu_button +       layout="topleft" +       follows="left|top" +       left="1" +       top="25" +       height="25" +       width="140" +       label="Actions" +       halign="left" +       image_unselected="DropDown_Off" +       image_selected="DropDown_On" +       image_pressed="DropDown_Press" +       image_pressed_selected="DropDown_Press" +       image_disabled="DropDown_Disabled" +       name="agent_actions_menu" /> +    </layout_panel> +  </layout_stack> + +  <layout_stack +   name="main_stack" +   top="8" +   left="168" +   bottom="-1" +   right="-1" +   follows="all" +   layout="topleft" +   animate="false" +   orientation="vertical"> +    <layout_panel +     name="display_name_panel" +     follows="all" +     layout="topleft" +     height="24" +     auto_resize="false" +     user_resize="false"> +      <line_editor +       name="display_name" +       border_thickness="0" +       use_bg_color="false" +       background_image_disabled="" +       background_image_focused="" +       enabled="false" +       value="(loading...)" +       font="SansSerifBigLarge" +       top="0" +       left="6" +       height="19" +       right="-86" +       follows="left|top|right" +       layout="topleft"/> + +      <icon +       tool_tip="Friend can see my online status" +       mouse_opaque="true" +       name="can_see_online" +       image_name="Profile_Perm_Online_Enabled" +       layout="topleft" +       follows="right|top" +       interactable="true" +       top="0" +       right="-61" +       height="24" +       width="24" +       left_pad="2" /> + +      <icon +       tool_tip="Friend can not see my online status" +       mouse_opaque="true" +       name="cant_see_online" +       image_name="Profile_Perm_Online_Disabled" +       layout="topleft" +       follows="right|top" +       interactable="true" +       top="0" +       right="-61" +       height="24" +       width="24" +       left_pad="2" /> + +      <icon +       tool_tip="Friend can see me on map" +       mouse_opaque="true" +       name="can_see_on_map" +       image_name="Profile_Perm_Find_Enabled" +       layout="topleft" +       follows="right|top" +       interactable="true" +       top="0" +       right="-30" +       height="24" +       width="24" +       left_pad="2" /> + +      <icon +       tool_tip="Friend can not see me on map" +       mouse_opaque="true" +       name="cant_see_on_map" +       image_name="Profile_Perm_Find_Disabled" +       layout="topleft" +       follows="right|top" +       interactable="true" +       top="0" +       right="-30" +       height="24" +       width="24" +       left_pad="2" /> + +      <icon +       tool_tip="Friend can edit my objects" +       mouse_opaque="true" +       name="can_edit_objects" +       image_name="Profile_Perm_Objects_Enabled" +       layout="topleft" +       follows="right|top" +       interactable="true" +       top="0" +       right="-1" +       height="24" +       width="24" +       left_pad="2" /> + +      <icon +       tool_tip="Friend can not edit my objects" +       mouse_opaque="true" +       name="cant_edit_objects" +       image_name="Profile_Perm_Objects_Disabled" +       layout="topleft" +       follows="right|top" +       interactable="true" +       top="0" +       right="-1" +       height="24" +       width="24" +       left_pad="2" /> + +    </layout_panel> + +    <layout_panel +     name="about_panel" +     follows="all" +     layout="topleft" +     height="159" +     auto_resize="true" +     user_resize="false"> +      <text_editor +       name="sl_description_edit" +       trusted_content="false" +       always_show_icons="true" +       commit_on_focus_lost="false" +       enabled="false" +       top="0" +       left="2" +       right="-1" +       bottom="-1" +       follows="all" +       layout="topleft" +       bg_readonly_color="Transparent" +       border_visible="true" +       font="SansSerifSmall" +       h_pad="2" +       max_length="65000" +       parse_urls="true" +       word_wrap="true" +        /> +    </layout_panel> +    <layout_panel +     name="about_buttons_panel" +     follows="all" +     layout="topleft" +     height="34" +     auto_resize="false" +     user_resize="false"> +        <button +         name="save_description_changes" +         label="Save" +         top="1" +         right="-105" +         height="20" +         width="80" +         enabled="false" +         follows="top|right" +         layout="topleft"/> +        <button +         name="discard_description_changes" +         label="Discard" +         top="1" +         right="-1" +         height="20" +         width="100" +         enabled="false" +         follows="top|right" +         layout="topleft"/> +        <view_border +         bevel_style="none" +         height="0" +         layout="topleft" +         left="0" +         name="cost_text_border" +         top_pad="9" +         width="492"/> +    </layout_panel> + +    <layout_panel +     name="groups_panel" +     follows="all" +     layout="topleft" +     height="159" +     auto_resize="true" +     user_resize="false"> +      <text +       name="group_label" +       value="Group memberships" +       top="1" +       left="2" +       right="-1" +       height="16" +       follows="left|top|right" +       layout="topleft"/> +      <group_list +       name="group_list" +       top="18" +       left="2" +       right="-1" +       bottom="-1" +       follows="all" +       layout="topleft" +       border_visible="true" +       color="ScrollBgWriteableColor" +       for_agent="false"/> + +    </layout_panel> +  </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_web.xml b/indra/newview/skins/default/xui/en/panel_profile_web.xml new file mode 100644 index 0000000000..e0cb4d3d06 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_web.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="panel_profile_web" + label="Web" + top="0" + left="0" + height="480" + width="420" + follows="all" + layout="topleft" +> +    <panel.string +     name="LoadTime" +     value="Load Time: [TIME] seconds" +    /> +    <web_browser +     name="profile_html" +     top="10" +     bottom="-18" +     left="10" +     right="-10" +     follows="all" +     layout="topleft" +     start_url="" +    /> +    <text +     name="status_text" +     bottom="-4" +     left="110" +     right="-110" +     follows="bottom|left|right" +     layout="topleft" +     halign="center" +     parse_urls="false" +    /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 8243c2715d..2aaea04a6d 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -86,7 +86,7 @@       name="detail_texture_text"       top="110"       width="300"> -        Terrain Textures (requires 512x512, 24 bit .tga files) +        Terrain Textures (requires 1024x1024, 24 bit .tga files)      </text>      <texture_picker       follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 0cbd7fe2dd..c7052bb737 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -550,10 +550,7 @@  			 top_pad="4"  			 tool_tip="Add Media"  			 label="Choose..." -			 width="85"> -				<button.commit_callback -				function="BuildTool.AddMedia"/> -			</button> +			 width="85"/>  			<button  			 follows="top|left"  			 height="18" @@ -563,10 +560,7 @@  			 tool_tip="Delete this media texture"  			 top_delta="0"  			 label="Remove" -			 width="85"> -				<button.commit_callback -				function="BuildTool.DeleteMedia"/> -			</button> +			 width="85"/>              <button  			 follows="left|top"  			 height="18" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 672bd31547..22aef0826a 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -348,8 +348,6 @@ can be attached to notecards.  	<!-- Group name: text shown for LLUUID::null -->  	<string name="GroupNameNone">(none)</string> -	<string name="AvalineCaller">Avaline Caller [ORDER]</string> -  	<!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. -->  	<string name="AssetErrorNone">No error</string>  	<string name="AssetErrorRequestFailed">Asset request: failed</string> @@ -2342,6 +2340,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.  An error occurred while opening Marketplace Listings.  If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com  	</string> +	<string name="InventoryMarketplaceConnectionError"> +Marketplace Listings failed to connect. +If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com +	</string> +	<string name="InventoryMarketplaceConnectionErrorReason"> +Marketplace Listings failed to connect. Reason: [REASON] +If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com +	</string>  	<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>  	<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>  	<string name="InventoryMarketplaceListingsNoItems"> @@ -2808,10 +2814,14 @@ If you continue to receive this message, please contact Second Life support for  	<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>  	<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string> -  <!-- panel picks --> -  <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string> -  <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string> -  <string name="PicksClassifiedsLoadingText">Loading...</string> +    <!-- panel picks --> +    <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string> +    <string name="NoPicksText">You haven't created any Picks. Click the New button to create a Pick.</string> +    <string name="NoClassifiedsText">You haven't created any Classifieds. Click the New button to create a Classified.</string> +    <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string> +    <string name="NoAvatarPicksText">This person has no picks</string> +    <string name="NoAvatarClassifiedsText">This person has no classifieds</string> +    <string name="PicksClassifiedsLoadingText">Loading...</string>  	<!-- Multi Preview Floater -->  	<string name="MultiPreviewTitle">Preview</string> diff --git a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml index 4f3c177976..87f93e8fcf 100644 --- a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml @@ -6,7 +6,7 @@  	<check_box label="Gestos" name="check_gesture"/>  	<check_box label="Hitos" name="check_landmark"/>  	<check_box label="Notas" name="check_notecard"/> -	<check_box label="Redes" name="check_mesh"/> +	<check_box label="Meshs" name="check_mesh"/>  	<check_box label="Objetos" name="check_object"/>  	<check_box label="Scripts" name="check_script"/>  	<check_box label="Sonidos" name="check_sound"/> diff --git a/indra/newview/skins/default/xui/es/floater_preview_texture.xml b/indra/newview/skins/default/xui/es/floater_preview_texture.xml index b0afd44750..2543508c40 100644 --- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		Copiar al inventario  	</floater.string> -	<text name="desc txt"> -		Descripción: -	</text> -	<text name="dimensions"> -		[WIDTH]px x [HEIGHT]px -	</text> -	<text name="aspect_ratio"> -		Previsualizar la ratio de las proporciones -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta"> -		<combo_item name="Unconstrained"> -			Sin restricciones -		</combo_item> -		<combo_item name="1:1" tool_tip="Emblema del grupo o perfil del Mundo real"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="Perfil de [SECOND_LIFE]"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="Clasificados (también en las listas de búsqueda), hitos"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="Acerca del terreno"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Destacados del perfil"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="Descartar" name="Discard"/> -	<button label="Guardar como" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Descripción: +			</text> +			<text name="dimensions"> +				[WIDTH]px x [HEIGHT]px +			</text> +			<text name="aspect_ratio"> +				Previsualizar la ratio de las proporciones +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="Descartar" name="Discard"/> +			<button label="Guardar como" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/es/floater_profile.xml b/indra/newview/skins/default/xui/es/floater_profile.xml new file mode 100644 index 0000000000..c9448a0d4e --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Perfil"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="Intereses" name="panel_profile_interests"/> +			<panel label="Destacados" name="panel_profile_picks"/> +			<panel label="Clasificado" name="panel_profile_classifieds"/> +			<panel label="Vida real" name="panel_profile_firstlife"/> +			<panel label="Notas" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="Salvar cambios en el perfil y cerrar"/> +		<button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml index c2c996aa8a..2dfaecf3e3 100644 --- a/indra/newview/skins/default/xui/es/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		Enviando el correo electrónico  	</string> +	<string name="facebook_progress_str"> +		Publicando en Facebook +	</string>  	<string name="profile_progress_str">  		Publicando  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Guardando en el equipo  	</string> +	<string name="facebook_succeeded_str"> +		Imagen subida +	</string>  	<string name="profile_succeeded_str">  		Imagen subida  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		¡Guardado en el equipo!  	</string> +	<string name="facebook_failed_str"> +		Error al subir la imagen a tu biografía de Facebook. +	</string>  	<string name="profile_failed_str">  		Error al subir la imagen a los comentarios de tu perfil.  	</string> diff --git a/indra/newview/skins/default/xui/es/menu_name_field.xml b/indra/newview/skins/default/xui/es/menu_name_field.xml new file mode 100644 index 0000000000..0d51fbffeb --- /dev/null +++ b/indra/newview/skins/default/xui/es/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Copiar Nombre mostrado" name="copy_display"/> +	<menu_item_call label="Copiar Nombre de agente" name="copy_name"/> +	<menu_item_call label="Copiar ID de agente" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 54707116d4..36f27bc3c6 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -2690,6 +2690,9 @@ Inténtalo seleccionando un trozo más pequeño de terreno.  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/es/panel_edit_classified.xml b/indra/newview/skins/default/xui/es/panel_edit_classified.xml index ffad843732..09f87015cc 100644 --- a/indra/newview/skins/default/xui/es/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/es/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="Cancelar" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/es/panel_facebook_place.xml b/indra/newview/skins/default/xui/es/panel_facebook_place.xml index 5139bd1d0b..29f6147f23 100644 --- a/indra/newview/skins/default/xui/es/panel_facebook_place.xml +++ b/indra/newview/skins/default/xui/es/panel_facebook_place.xml @@ -3,7 +3,7 @@  	<text name="place_caption_label">  		Cuenta algo del lugar donde te encuentras:  	</text> -	<check_box initial_value="false" label="Incluir una vista general del lugar" name="add_place_view_cb"/> +	<check_box initial_value="false" label="Incluye una vista general del lugar" name="add_place_view_cb"/>  	<button label="Publicar" name="post_place_btn"/>  	<button label="Cancelar" name="cancel_place_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml index a17814d15d..ef919f396e 100644 --- a/indra/newview/skins/default/xui/es/panel_group_general.xml +++ b/indra/newview/skins/default/xui/es/panel_group_general.xml @@ -46,7 +46,7 @@ Deja el cursor sobre las opciones para ver más ayuda.  		<check_box label="Cualquiera puede entrar" name="open_enrollement" tool_tip="Configura si se permite la entrada de nuevos miembros sin ser invitados."/>  		<check_box label="Cuota de entrada" name="check_enrollment_fee" tool_tip="Configura si hay que pagar una cuota para entrar al grupo"/>  		<spinner label="L$" left_delta="130" name="spin_enrollment_fee" tool_tip="Si la opción Cuota de entrada está marcada, los nuevos miembros han de pagar esta cuota para entrar al grupo." width="60"/> -		<combo_box bottom_delta="-38" name="group_mature_check" tool_tip="La calificación de contenido designa el tipo de contenido y conducta que se permiten en un grupo" width="150"> +		<combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si tu grupo contiene información clasificada como Moderada" width="150">  			<combo_item name="select_mature">  				- Selecciona el nivel de calificación -  			</combo_item> diff --git a/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml new file mode 100644 index 0000000000..4d682068d7 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Desconocido"/> +	<button name="info_btn" tool_tip="Más información"/> +	<button name="profile_btn" tool_tip="Ver el perfil"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_me.xml b/indra/newview/skins/default/xui/es/panel_me.xml deleted file mode 100644 index 850cd6ec71..0000000000 --- a/indra/newview/skins/default/xui/es/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Mi perfil" name="panel_me"> -	<panel label="MIS DESTACADOS" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml index 73b9af3665..2aaf7e89be 100644 --- a/indra/newview/skins/default/xui/es/panel_people.xml +++ b/indra/newview/skins/default/xui/es/panel_people.xml @@ -40,6 +40,7 @@  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="Conectado"/>  				<accordion_tab name="tab_all" title="Todos"/> +				<accordion_tab name="tab_suggested_friends" title="Personas de las que podrías querer ser amigo"/>  			</accordion>  		</panel>  		<panel label="GRUPOS" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/es/panel_profile_classified.xml b/indra/newview/skins/default/xui/es/panel_profile_classified.xml new file mode 100644 index 0000000000..679026d350 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Moderado +	</panel.string> +	<panel.string name="type_pg"> +		Contenido general +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Activados +	</panel.string> +	<panel.string name="auto_renew_off"> +		Inhabilitado +	</panel.string> +	<panel.string name="location_notice"> +		(se actualizará tras guardarlo) +	</panel.string> +	<string name="publish_label"> +		Publicar +	</string> +	<string name="save_label"> +		Guardar +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Pulsa para elegir una imagen"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Ubicación:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="Tipo de contenido:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Categoría:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Fecha de creación:"/> +					<text_editor name="creation_date" tool_tip="Fecha de creación" value="[date]"/> +					<text name="price_for_listing_label" value="Precio por publicarlo:"/> +					<text_editor name="price_for_listing" tool_tip="Precio por publicarlo."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Clics:"/> +					<text_editor name="click_through_text" tool_tip="Información sobre Click through" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Renovación:"/> +					<text name="auto_renew" value="Activados"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Descripción:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Título: +				</text> +				<text name="description_label"> +					Descripción: +				</text> +				<text name="location_label"> +					Ubicación: +				</text> +				<text name="classified_location_edit"> +					cargando... +				</text> +				<button label="Configurar en mi posición" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Categoría:"/> +				<text name="content_type_label" value="Tipo de contenido:"/> +				<icons_combo_box label="Contenido general" name="content_type_edit"> +					<icons_combo_box.item label="Contenido Moderado" name="mature_ci" value="Contenido para adultos"/> +					<icons_combo_box.item label="Contenido general" name="pg_ci" value="General"/> +				</icons_combo_box> +				<check_box label="Renovar automáticamente cada semana" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="Precio por publicarlo:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="Precio por publicarlo." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Teleporte" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Mapa" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Editar" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="Cancelar" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml new file mode 100644 index 0000000000..2520348094 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Clasificado" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="No hay clasificados"/> +	<button label="Nuevo..." name="new_btn"/> +	<button label="Eliminar..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		Cargando... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/fr/floater_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml index f058ff668b..0fb502e441 100644 --- a/indra/newview/skins/default/xui/fr/floater_picks.xml +++ b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml @@ -1,2 +1,2 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Favoris"/> +<panel label="Perfil" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/es/panel_profile_interests.xml b/indra/newview/skins/default/xui/es/panel_profile_interests.xml new file mode 100644 index 0000000000..86dd63390c --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Intereses" name="panel_profile_interests"> +	<text name="I Want To:"> +		Quiero: +	</text> +	<check_box label="Construye" name="chk0"/> +	<check_box label="Explora" name="chk1"/> +	<check_box label="Conoce" name="chk2"/> +	<check_box label="Encuentra empleo" name="chk6"/> +	<check_box label="Agrupa" name="chk3"/> +	<check_box label="Compra" name="chk4"/> +	<check_box label="Vende" name="chk5"/> +	<check_box label="Contrata" name="chk7"/> +	<line_editor name="want_to_edit"> +		(cargando...) +	</line_editor> +	<text name="Skills:"> +		Habilidades: +	</text> +	<check_box label="Texturas" name="schk0"/> +	<check_box label="Arquitectura" name="schk1"/> +	<check_box label="Modelo" name="schk3"/> +	<check_box label="Planificación de eventos" name="schk2"/> +	<check_box label="Preparación de scripts" name="schk4"/> +	<check_box label="Personajes personalizados" name="schk5"/> +	<line_editor name="skills_edit"> +		(cargando...) +	</line_editor> +	<text name="Languages:"> +		Idiomas: +	</text> +	<line_editor name="languages_edit"> +		(cargando...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_notes.xml b/indra/newview/skins/default/xui/es/panel_profile_notes.xml new file mode 100644 index 0000000000..4cc14e1487 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Notas y Privacidad" name="panel_notes"> +	<text name="status_message" value="Notas privadas en este avatar:"/> +	<text name="status_message2" value="Permitir que este avatar:"/> +	<check_box label="Ver cuándo estoy conectado" name="status_check"/> +	<check_box label="Encontrarme en el mapa del mundo" name="map_check"/> +	<check_box label="Edita, borrar o tomar mis objetos" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_pick.xml b/indra/newview/skins/default/xui/es/panel_profile_pick.xml new file mode 100644 index 0000000000..4e9f5bbdd5 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(se actualizará tras guardarlo) +	</panel.string> +	<line_editor name="pick_location"> +		Cargando... +	</line_editor> +	<button label="Teleporte" name="teleport_btn"/> +	<button label="Mostrar en el mapa" name="show_on_map_btn"/> +	<button label="Establecer ubicación" name="set_to_curr_location_btn" tool_tip="Configurar en mi posición"/> +	<button label="Guardar" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_picks.xml new file mode 100644 index 0000000000..0641b72c13 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Destacados" name="panel_picks"> +	<string name="no_picks" value="No hay destacados"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Cuéntale a todos sobre tus lugares favoritos de Second Life. +	</text> +	<button label="Nuevo..." name="new_btn"/> +	<button label="Eliminar..." name="delete_btn"/> +	<text name="picks_panel_text"> +		Cargando... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml new file mode 100644 index 0000000000..541593660d --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Perfil" name="panel_profile"> +	<string name="status_online"> +		Actualmente en línea +	</string> +	<string name="status_offline"> +		Actualmente sin conexión +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Ninguno"/> +	<string name="no_group_text" value="Ninguno"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Desarrollador"/> +	<string name="FSSupp" value="Soporte"/> +	<string name="FSQualityAssurance" value="Buscador de fallos"/> +	<string name="FSGW" value="Portal"/> +	<text name="name_label" value="Nombre:"/> +	<button label="Nombre:" name="set_name" tool_tip="Configurar nombre mostrado"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(cargando...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Status Desconocido"/> +			<text name="label" value="Fecha de nacimiento en Second Life:"/> +			<text name="label2" value="Cuenta:"/> +			<text name="partner_label" value="Compañero/a:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Grupos:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="Invitar al grupo"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="Acerca de:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Dar objeto:"/> +			<text name="Give inventory" tool_tip="Soltar elementos de inventario aquí para dárselos a esta persona."> +				Soltar aquí el nuevo elemento de inventario. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Encontrar en el mapa" label_selected="Encontrar en el mapa" name="show_on_map_btn" tool_tip="Mostrar al Residente en el mapa"/> +			<button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pagar a este Residente"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Ofrecer teleporte" label_selected="Ofrecer teleporte" name="teleport" tool_tip="Ofrecer teleporte al residente"/> +			<button label="Mensaje instantáneo" label_selected="Mensaje instantáneo" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Añadir como amigo" label_selected="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/> +			<button label="Bloquear" name="block" tool_tip="Bloquear al residente"/> +			<button label="Desbloquear" name="unblock" tool_tip="Desbloquear al residente"/> +		</layout_panel> +	</layout_stack> +	<check_box label="Mostrar en la búsqueda" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_web.xml b/indra/newview/skins/default/xui/es/panel_profile_web.xml new file mode 100644 index 0000000000..f9a8f4b113 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Tiempo de carga: [TIME] segundos"/> +	<line_editor name="url_edit"> +		(cargando..) +	</line_editor> +	<flyout_button label="Cargar" name="load" tool_tip="Cargar esta página de perfil con el navegador incorporado."> +		<flyout_button.item label="Abrir navegador in-viewer" name="open_item"/> +		<flyout_button.item label="Abrir navegador externo" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Perfil web emergente"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml index cb6c03dbb5..9aba5299cb 100644 --- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml @@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/>  	<spinner bottom_delta="-34" label="Límite de bajada del   terreno" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Texturas del terreno (requiere archivos .tga de 512x512, 24 bits) -	</text> +    Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits) +  </text>  	<text name="height_text_lbl">  		1 (bajo)  	</text> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 4b7f6a0081..5a03e65b49 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -348,6 +348,24 @@ Intenta iniciar sesión de nuevo en unos instantes.  	<string name="TestingDisconnect">  		Probando la desconexión del visor  	</string> +	<string name="SocialFacebookConnecting"> +		Conectando con Facebook... +	</string> +	<string name="SocialFacebookPosting"> +		Publicando... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Desconectando de Facebook... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Problema al conectar con Facebook +	</string> +	<string name="SocialFacebookErrorPosting"> +		Problema al publicar en Facebook +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Problema al desconectar de Facebook +	</string>  	<string name="SocialFlickrConnecting">  		Conectándose a Flickr...  	</string> @@ -662,9 +680,6 @@ pueden adjuntarse a las notas.  	<string name="GroupNameNone">  		(ninguno)  	</string> -	<string name="AvalineCaller"> -		Avaline: [ORDER] -	</string>  	<string name="AssetErrorNone">  		No hay ningún error  	</string> @@ -2549,9 +2564,21 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia  	<string name="NoPicksClassifiedsText">  		No has creado destacados ni clasificados. Pulsa el botón Más para crear uno.  	</string> +	<string name="NoPicksText"> +		No has creado destacados. Haz clic en el botón Más para crear uno. +	</string> +	<string name="NoClassifiedsText"> +		No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado. +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		El usuario no tiene clasificados ni destacados  	</string> +	<string name="NoAvatarPicksText"> +		El usuario no tiene destacados +	</string> +	<string name="NoAvatarClassifiedsText"> +		El usuario no tiene clasificados +	</string>  	<string name="PicksClassifiedsLoadingText">  		Cargando...  	</string> @@ -4469,6 +4496,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].  	<string name="share_alert">  		Arrastra los ítems desde el invenbtario hasta aquí  	</string> +	<string name="facebook_post_success"> +		Has publicado en Facebook. +	</string>  	<string name="flickr_post_success">  		Has publicado en Flickr.  	</string> diff --git a/indra/newview/skins/default/xui/fr/floater_facebook.xml b/indra/newview/skins/default/xui/fr/floater_facebook.xml index f5097e7a88..f6e8696e53 100644 --- a/indra/newview/skins/default/xui/fr/floater_facebook.xml +++ b/indra/newview/skins/default/xui/fr/floater_facebook.xml @@ -10,6 +10,6 @@  		Erreur  	</text>  	<text name="connection_loading_text"> -		Chargement... +		En cours de chargement...  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml index d63d9903ec..46703fe612 100644 --- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		Copier dans l'inventaire  	</floater.string> -	<text name="desc txt"> -		Description : -	</text> -	<text name="dimensions"> -		[WIDTH]px x [HEIGHT]px -	</text> -	<text name="aspect_ratio"> -		Rapport d'aspect fixe -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d'aspect fixe"> -		<combo_item name="Unconstrained"> -			Sans contraintes -		</combo_item> -		<combo_item name="1:1" tool_tip="Logo du groupe ou profil dans la vie réelle"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="Profil [SECOND_LIFE]"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="Petites annonces, repères"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="À propos du terrain"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Favoris du profil"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="Jeter" name="Discard"/> -	<button label="Enregistrer sous" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Description : +			</text> +			<text name="dimensions"> +				[WIDTH]px x [HEIGHT]px +			</text> +			<text name="aspect_ratio"> +				Rapport d'aspect fixe +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d'aspect fixe"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="Jeter" name="Discard"/> +			<button label="Enregistrer sous" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_profile.xml b/indra/newview/skins/default/xui/fr/floater_profile.xml new file mode 100644 index 0000000000..c4af79e946 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Profil"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="Centres d'intérêt" name="panel_profile_interests"/> +			<panel label="Favoris" name="panel_profile_picks"/> +			<panel label="Petite annonce" name="panel_profile_classifieds"/> +			<panel label="Vie réelle" name="panel_profile_firstlife"/> +			<panel label="Remarques" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="Enregistrer les changements apportés au profil et fermer"/> +		<button label="Annuler" label_selected="Annuler" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml index 8eb05dd945..adb98a68d2 100644 --- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		Envoi par e-mail  	</string> +	<string name="facebook_progress_str"> +		Publication sur Facebook +	</string>  	<string name="profile_progress_str">  		Publication  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Enregistrement sur l'ordinateur  	</string> +	<string name="facebook_succeeded_str"> +		Image chargée +	</string>  	<string name="profile_succeeded_str">  		Image chargée  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		Enregistrement sur l'ordinateur effectué !  	</string> +	<string name="facebook_failed_str"> +		Échec de chargement de l'image dans votre journal Facebook. +	</string>  	<string name="profile_failed_str">  		Échec de chargement de l'image sur le flux de votre profil.  	</string> diff --git a/indra/newview/skins/default/xui/fr/menu_name_field.xml b/indra/newview/skins/default/xui/fr/menu_name_field.xml new file mode 100644 index 0000000000..6c3fba4110 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Copier le Nom d'affichage" name="copy_display"/> +	<menu_item_call label="Copier le  Nom de l'agent" name="copy_name"/> +	<menu_item_call label="Copier l'ID de l'agent" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index e84de375d8..09905f4e5d 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2683,6 +2683,9 @@ Veuillez sélectionner un terrain plus petit.  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml index 7b58f2e825..b892d25f26 100644 --- a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="Annuler" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml index 319737a2af..0e36c2092c 100644 --- a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml +++ b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_friends"> -	<string name="facebook_friends_empty" value="Vous n'avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life !"/> +	<string name="facebook_friends_empty" value="Vous n'avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life aujourd'hui !"/>  	<string name="facebook_friends_no_connected" value="Vous n'êtes pas connecté(e) à Facebook. Allez à l'onglet Statut pour vous connecter et activer cette fonctionnalité."/>  	<accordion name="friends_accordion">  		<accordion_tab name="tab_second_life_friends" title="Amis SL"/> diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml index 3236f35b55..cc4045bc74 100644 --- a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml @@ -4,14 +4,14 @@  		<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>  		<combo_box.item label="640 x 480" name="640x480"/>  		<combo_box.item label="800 x 600" name="800x600"/> -		<combo_box.item label="1 024 x 768" name="1024x768"/> -		<combo_box.item label="1 200 x 630" name="1200x630"/> +		<combo_box.item label="1024 x 768" name="1024x768"/> +		<combo_box.item label="1200 x 630" name="1200x630"/>  	</combo_box> -	<combo_box name="filters_combobox" tool_tip="Filtres d'image"> +	<combo_box name="filters_combobox" tool_tip="Filtres d’image">  		<combo_box.item label="Aucun filtre" name="NoFilter"/>  	</combo_box>  	<button label="Actualiser" name="new_snapshot_btn" tool_tip="Cliquer pour actualiser"/> -	<button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour activer/désactiver l'aperçu"/> +	<button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour basculer l'aperçu"/>  	<text name="caption_label">  		Commentaire (facultatif) :  	</text> diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml index 9afa42d2aa..dc8e4b9ecc 100644 --- a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml +++ b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml @@ -6,7 +6,7 @@  		Pas connecté(e) à Facebook.  	</text>  	<panel name="panel_buttons"> -		<button label="Connexion..." name="connect_btn"/> +		<button label="Connexion en cours..." name="connect_btn"/>  		<button label="Déconnexion" name="disconnect_btn"/>  		<text name="account_learn_more_label">  			[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Apprenez comment publier sur Facebook] diff --git a/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml new file mode 100644 index 0000000000..b1b32af7c6 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Inconnu"/> +	<button name="info_btn" tool_tip="En savoir plus"/> +	<button name="profile_btn" tool_tip="Voir le profil"/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml deleted file mode 100644 index 5676986228..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Mon profil" name="panel_me"> -	<panel label="MES FAVORIS" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml index 3be6bae52a..e096b5cfe0 100644 --- a/indra/newview/skins/default/xui/fr/panel_people.xml +++ b/indra/newview/skins/default/xui/fr/panel_people.xml @@ -40,6 +40,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="En ligne"/>  				<accordion_tab name="tab_all" title="Tout"/> +				<accordion_tab name="tab_suggested_friends" title="Personnes avec lesquelles vous aimeriez peut-être devenir ami(e)"/>  			</accordion>  		</panel>  		<panel label="GROUPES" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classified.xml b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml new file mode 100644 index 0000000000..b223684c60 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Modéré +	</panel.string> +	<panel.string name="type_pg"> +		Contenu Général +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] téléporter, [MAP] carte, [PROFILE] profile +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Activé +	</panel.string> +	<panel.string name="auto_renew_off"> +		Désactivé +	</panel.string> +	<panel.string name="location_notice"> +		(mise à jour après enregistrement) +	</panel.string> +	<string name="publish_label"> +		Publier +	</string> +	<string name="save_label"> +		Enregistrer +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Cliquer pour sélectionner une image"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Endroit :"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="Type de contenu :"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Catégorie :"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Date de création :"/> +					<text_editor name="creation_date" tool_tip="Date de création" value="[date]"/> +					<text name="price_for_listing_label" value="Coût de l'annonce :"/> +					<text_editor name="price_for_listing" tool_tip="Coût de l’annonce."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Clics :"/> +					<text_editor name="click_through_text" tool_tip="Parcourir les données en cliquant" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Renouv. auto :"/> +					<text name="auto_renew" value="Activé"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Description :"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Titre : +				</text> +				<text name="description_label"> +					Description : +				</text> +				<text name="location_label"> +					Endroit : +				</text> +				<text name="classified_location_edit"> +					en cours de chargement... +				</text> +				<button label="Définir sur l’emplacement actuel" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Catégorie :"/> +				<text name="content_type_label" value="Type de contenu :"/> +				<icons_combo_box label="Contenu Général" name="content_type_edit"> +					<icons_combo_box.item label="Contenu Modéré" name="mature_ci" value="Adulte"/> +					<icons_combo_box.item label="Contenu Général" name="pg_ci" value="PG"/> +				</icons_combo_box> +				<check_box label="Renouvellement auto toutes les semaines" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="Coût de l'annonce :"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="Coût de l’annonce." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Téléportation" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Carte" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Modifier" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="Annuler" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml new file mode 100644 index 0000000000..adb3501422 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Petite annonce" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="Pas de petites annonces"/> +	<button label="Nouveau..." name="new_btn"/> +	<button label="Supprimer..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		En cours de chargement... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/es/floater_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml index 255aa5dcdc..0f65090209 100644 --- a/indra/newview/skins/default/xui/es/floater_picks.xml +++ b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml @@ -1,2 +1,2 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Destacados"/> +<panel label="Profil" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_interests.xml b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml new file mode 100644 index 0000000000..e8212817d2 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Centres d'intérêt" name="panel_profile_interests"> +	<text name="I Want To:"> +		Je veux : +	</text> +	<check_box label="Construire" name="chk0"/> +	<check_box label="Explorer" name="chk1"/> +	<check_box label="Rencontrer" name="chk2"/> +	<check_box label="Être recruté" name="chk6"/> +	<check_box label="Grouper" name="chk3"/> +	<check_box label="Acheter" name="chk4"/> +	<check_box label="Vendre" name="chk5"/> +	<check_box label="Louer" name="chk7"/> +	<line_editor name="want_to_edit"> +		(en cours de chargement...) +	</line_editor> +	<text name="Skills:"> +		Compétences : +	</text> +	<check_box label="Textures" name="schk0"/> +	<check_box label="Architecture" name="schk1"/> +	<check_box label="Modèle" name="schk3"/> +	<check_box label="Planification des événements" name="schk2"/> +	<check_box label="Langage de scripts" name="schk4"/> +	<check_box label="Personnages personnalisés" name="schk5"/> +	<line_editor name="skills_edit"> +		(en cours de chargement...) +	</line_editor> +	<text name="Languages:"> +		Langues : +	</text> +	<line_editor name="languages_edit"> +		(en cours de chargement...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml new file mode 100644 index 0000000000..03fb37d72b --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Notes & respect de la vie privée" name="panel_notes"> +	<text name="status_message" value="Notes personnelles sur cet avatar:"/> +	<text name="status_message2" value="Autoriser cet avatar à :"/> +	<check_box label="Voir quand je suis en ligne" name="status_check"/> +	<check_box label="Me trouver sur la carte du monde" name="map_check"/> +	<check_box label="Modifier, supprimer ou prendre mes objets" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_pick.xml b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml new file mode 100644 index 0000000000..017fcff88a --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(mise à jour après enregistrement) +	</panel.string> +	<line_editor name="pick_location"> +		En cours de chargement... +	</line_editor> +	<button label="Téléportation" name="teleport_btn"/> +	<button label="Voir sur la carte" name="show_on_map_btn"/> +	<button label="Définir l'emplacement" name="set_to_curr_location_btn" tool_tip="Définir sur l’emplacement actuel"/> +	<button label="Enregistrer les favoris" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml new file mode 100644 index 0000000000..1644722813 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Favoris" name="panel_picks"> +	<string name="no_picks" value="Pas de favoris"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Faites connaître aux autres résidents vos endroits favoris dans Second Life. +	</text> +	<button label="Nouveau..." name="new_btn"/> +	<button label="Supprimer..." name="delete_btn"/> +	<text name="picks_panel_text"> +		En cours de chargement... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml new file mode 100644 index 0000000000..de9cbf6dce --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profil" name="panel_profile"> +	<string name="status_online"> +		Actuellement connecté +	</string> +	<string name="status_offline"> +		Actuellement déconnecté +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Aucun"/> +	<string name="no_group_text" value="Aucun"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Développeur"/> +	<string name="FSSupp" value="Assistance"/> +	<string name="FSQualityAssurance" value="Suivi des anomalies"/> +	<string name="FSGW" value="Portail"/> +	<text name="name_label" value="Nom :"/> +	<button label="Nom :" name="set_name" tool_tip="Définir un nom d'affichage"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(en cours de chargement...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Statut inconnu"/> +			<text name="label" value="Date de naissance dans Second Life :"/> +			<text name="label2" value="Compte :"/> +			<text name="partner_label" value="Partenaire :"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Groupes :"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="Inviter dans le groupe"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="À propos :"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Donner des objets :"/> +			<text name="Give inventory" tool_tip="Placer les objets de l'inventaire ici pour les donner à cette personne"> +				Placer les objets de l'inventaire ici. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Situer sur la carte" label_selected="Situer sur la carte" name="show_on_map_btn" tool_tip="Localiser le Résident sur la carte"/> +			<button label="Payer" label_selected="Payer" name="pay" tool_tip="Payer le résident"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Proposer de téléporter" label_selected="Proposer de téléporter" name="teleport" tool_tip="Proposer une téléportation au Résident"/> +			<button label="Message instantané" label_selected="Message instantané" name="im" tool_tip="Ouvrir une session IM."/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Ajouter un ami" label_selected="Ajouter un ami" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/> +			<button label="Bloquer" name="block" tool_tip="Bloquer ce Résident"/> +			<button label="Débloquer" name="unblock" tool_tip="Débloquer ce Résident"/> +		</layout_panel> +	</layout_stack> +	<check_box label="Afficher avec la recherche" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_web.xml b/indra/newview/skins/default/xui/fr/panel_profile_web.xml new file mode 100644 index 0000000000..70e145ade9 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Heure de chargement : [TIME] secondes"/> +	<line_editor name="url_edit"> +		(en cours de chargement..) +	</line_editor> +	<flyout_button label="Charger" name="load" tool_tip="Charger ce profil avec le navigateur Web incorporé"> +		<flyout_button.item label="Ouvrir dans mon navigateur Web" name="open_item"/> +		<flyout_button.item label="Ouvrir dans un navigateur externe" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Profil de fenêtres web"/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml index 97f486d3a3..bbab00ca24 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml @@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/>  	<spinner bottom_delta="-34" label="Limite d'abaissement   du terrain" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Textures du terrain (fichiers .tga 512 x 512, 24 bit requis) -	</text> +    Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis) +  </text>  	<text name="height_text_lbl">  		1 (Bas)  	</text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 16423503e7..21825c6b2f 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -357,6 +357,24 @@ Veuillez réessayer de vous connecter dans une minute.  	<string name="TestingDisconnect">  		Test de déconnexion du client  	</string> +	<string name="SocialFacebookConnecting"> +		Connexion à Facebook… +	</string> +	<string name="SocialFacebookPosting"> +		Publication… +	</string> +	<string name="SocialFacebookDisconnecting"> +		Déconnexion de Facebook… +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Un problème est survenu lors de la connexion à Facebook. +	</string> +	<string name="SocialFacebookErrorPosting"> +		Un problème est survenu lors de la publication sur Facebook. +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Un problème est survenu lors de la déconnexion à Facebook. +	</string>  	<string name="SocialFlickrConnecting">  		Connexion à Flickr...  	</string> @@ -674,9 +692,6 @@ peuvent être joints aux notes.  	<string name="GroupNameNone">  		(aucun)  	</string> -	<string name="AvalineCaller"> -		Appelant Avaline [ORDER] -	</string>  	<string name="AssetErrorNone">  		Aucune erreur  	</string> @@ -2579,9 +2594,21 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life   	<string name="NoPicksClassifiedsText">  		Vous n'avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce.  	</string> +	<string name="NoPicksText"> +		Vous n'avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori +	</string> +	<string name="NoClassifiedsText"> +		Vous n'avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce. +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		L'utilisateur n'a ni favoris ni petites annonces.  	</string> +	<string name="NoAvatarPicksText"> +		L'utilisateur n'a pas de favoris +	</string> +	<string name="NoAvatarClassifiedsText"> +		L'utilisateur n'a pas de petites annonces +	</string>  	<string name="PicksClassifiedsLoadingText">  		Chargement...  	</string> @@ -4559,6 +4586,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].  	<string name="share_alert">  		Faire glisser les objets de l'inventaire ici  	</string> +	<string name="facebook_post_success"> +		Vous avez publié sur Facebook. +	</string>  	<string name="flickr_post_success">  		Vous avez publié sur Flickr.  	</string> diff --git a/indra/newview/skins/default/xui/it/floater_preview_texture.xml b/indra/newview/skins/default/xui/it/floater_preview_texture.xml index 8e8d020067..02f15b6b7b 100644 --- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		Copia nell'Inventario  	</floater.string> -	<text name="desc txt"> -		Descrizione: -	</text> -	<text name="dimensions"> -		[WIDTH]px x [HEIGHT]px -	</text> -	<text name="aspect_ratio"> -		Antreprima rapporto di visualizzazione -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso"> -		<combo_item name="Unconstrained"> -			Libero -		</combo_item> -		<combo_item name="1:1" tool_tip="Logo del gruppo o profilo nel mondo reale"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="Profilo [SECOND_LIFE]"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="Annunci e inserzioni, punti di riferimento"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="Informazioni sul terreno"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Preferiti del Profilo"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="Elimina" name="Discard"/> -	<button label="Salva con nome" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Descrizione: +			</text> +			<text name="dimensions"> +				[WIDTH]px x [HEIGHT]px +			</text> +			<text name="aspect_ratio"> +				Antreprima rapporto di visualizzazione +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="Elimina" name="Discard"/> +			<button label="Salva con nome" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/it/floater_profile.xml b/indra/newview/skins/default/xui/it/floater_profile.xml new file mode 100644 index 0000000000..7e23f9bbbb --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Profilo"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="Interessi" name="panel_profile_interests"/> +			<panel label="Preferiti" name="panel_profile_picks"/> +			<panel label="Annuncio" name="panel_profile_classifieds"/> +			<panel label="Vita reale" name="panel_profile_firstlife"/> +			<panel label="Note" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="Salva modifiche al profilo e chiudi"/> +		<button label="Annulla" label_selected="Annulla" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml index d21c206f6f..c9f71a167e 100644 --- a/indra/newview/skins/default/xui/it/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		Invio e-mail in corso  	</string> +	<string name="facebook_progress_str"> +		Pubblicazione su Facebook in corso +	</string>  	<string name="profile_progress_str">  		Caricamento post  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Salvataggio sul computer in corso  	</string> +	<string name="facebook_succeeded_str"> +		Immagine caricata +	</string>  	<string name="profile_succeeded_str">  		Immagine caricata  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		Salvato sul computer.  	</string> +	<string name="facebook_failed_str"> +		Caricamento immagine sul diario di Facebook non riuscito. +	</string>  	<string name="profile_failed_str">  		Caricamento immagine sul feed del profilo non riuscito.  	</string> diff --git a/indra/newview/skins/default/xui/it/menu_name_field.xml b/indra/newview/skins/default/xui/it/menu_name_field.xml new file mode 100644 index 0000000000..9ac863323c --- /dev/null +++ b/indra/newview/skins/default/xui/it/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Copia Nome Visualizzato" name="copy_display"/> +	<menu_item_call label="Copia Nome Agente" name="copy_name"/> +	<menu_item_call label="Copia ID Agente" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 1c43013255..a69fa07c50 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -2685,6 +2685,9 @@ Prova a selezionare una parte di terreno più piccola.  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml index ad827696ff..57e422a25b 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="Annulla" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml index c1c0489f88..28769a010f 100644 --- a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml +++ b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml @@ -1,12 +1,12 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_friends"> -	<string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti in Second Life. Invita i tuoi amici di Facebook a partecipare a Second Life!"/> -	<string name="facebook_friends_no_connected" value="Attualmente non sei in collegamento con Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/> +	<string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti Second Life. Invita ora i tuoi amici di Facebook a unirsi a Second Life!"/> +	<string name="facebook_friends_no_connected" value="Non sei connesso a Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>  	<accordion name="friends_accordion">  		<accordion_tab name="tab_second_life_friends" title="Amici SL"/>  		<accordion_tab name="tab_suggested_friends" title="Aggiungi queste persone come amici SL"/>  	</accordion>  	<text name="facebook_friends_status"> -		Non in collegamento con Facebook. +		Non connesso a Facebook.  	</text>  </panel> diff --git a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml index 044b8b6164..8d66f35c3c 100644 --- a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml @@ -1,13 +1,13 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_photo"> -	<combo_box name="resolution_combobox" tool_tip="Risoluzione immagini"> +	<combo_box name="resolution_combobox" tool_tip="Risoluzione immagine">  		<combo_box.item label="Finestra attuale" name="CurrentWindow"/>  		<combo_box.item label="640x480" name="640x480"/>  		<combo_box.item label="800x600" name="800x600"/>  		<combo_box.item label="1024x768" name="1024x768"/>  		<combo_box.item label="1200x630" name="1200x630"/>  	</combo_box> -	<combo_box name="filters_combobox" tool_tip="Filtri immagini"> +	<combo_box name="filters_combobox" tool_tip="Filtri immagine">  		<combo_box.item label="Nessun filtro" name="NoFilter"/>  	</combo_box>  	<button label="Aggiorna" name="new_snapshot_btn" tool_tip="Fai clic per aggiornare"/> diff --git a/indra/newview/skins/default/xui/it/panel_facebook_status.xml b/indra/newview/skins/default/xui/it/panel_facebook_status.xml index 9b5171043a..7fb1cec78e 100644 --- a/indra/newview/skins/default/xui/it/panel_facebook_status.xml +++ b/indra/newview/skins/default/xui/it/panel_facebook_status.xml @@ -1,13 +1,13 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_status"> -	<string name="facebook_connected" value="Sei in collegamento con Facebook come:"/> -	<string name="facebook_disconnected" value="Non in collegamento con Facebook"/> +	<string name="facebook_connected" value="Sei connesso a Facebook come:"/> +	<string name="facebook_disconnected" value="Non connesso a Facebook"/>  	<text name="account_caption_label"> -		Non in collegamento con Facebook. +		Non connesso a Facebook.  	</text>  	<panel name="panel_buttons"> -		<button label="Collegamento..." name="connect_btn"/> -		<button label="Interrompi collegamento" name="disconnect_btn"/> +		<button label="Connessione in corso..." name="connect_btn"/> +		<button label="Disconnetti" name="disconnect_btn"/>  		<text name="account_learn_more_label">  			[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Come pubblicare su Facebook]  		</text> diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml index 60028e6098..168524d1ad 100644 --- a/indra/newview/skins/default/xui/it/panel_group_general.xml +++ b/indra/newview/skins/default/xui/it/panel_group_general.xml @@ -46,7 +46,7 @@ Muovi il tuo mouse sopra le opzioni per maggiore aiuto.  		<check_box label="Chiunque può aderire" name="open_enrollement" tool_tip="Imposta se questo gruppo permette ai nuovi membri di aderire senza essere invitati."/>  		<check_box label="Quota di adesione" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa d'iscrizione per aderire al gruppo"/>  		<spinner label="L$" left_delta="136" name="spin_enrollment_fee" tool_tip="I nuovi soci devono pagare questa tassa d'iscrizione quando è selezionata." width="60"/> -		<combo_box name="group_mature_check" tool_tip="Le categorie di accesso definiscono il tipo di contenuti e di comportamenti ammessi in un gruppo"> +		<combo_box name="group_mature_check" tool_tip="Determina se il tuo gruppo contiene informazioni contrassegnate come Moderate opppure no">  			<combo_item name="select_mature">  				- Seleziona categoria di accesso -  			</combo_item> diff --git a/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml new file mode 100644 index 0000000000..72e644008c --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Sconosciuto"/> +	<button name="info_btn" tool_tip="Maggiori informazioni"/> +	<button name="profile_btn" tool_tip="Vedi profilo"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_me.xml b/indra/newview/skins/default/xui/it/panel_me.xml deleted file mode 100644 index a134f6f1de..0000000000 --- a/indra/newview/skins/default/xui/it/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Il mio profilo" name="panel_me"> -	<panel label="I MIEI PREFERITI" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml index 3df2368ae0..9eb93a26e5 100644 --- a/indra/newview/skins/default/xui/it/panel_people.xml +++ b/indra/newview/skins/default/xui/it/panel_people.xml @@ -40,6 +40,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="Online"/>  				<accordion_tab name="tab_all" title="Tutto"/> +				<accordion_tab name="tab_suggested_friends" title="Persone che potresti voler aggiungere agli amici"/>  			</accordion>  		</panel>  		<panel label="GRUPPI" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/it/panel_profile_classified.xml b/indra/newview/skins/default/xui/it/panel_profile_classified.xml new file mode 100644 index 0000000000..3c88fbe92f --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Moderato +	</panel.string> +	<panel.string name="type_pg"> +		Contenuto Generale +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] teletrasporto, [MAP] mappa, [PROFILE] profilo +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Abilitato +	</panel.string> +	<panel.string name="auto_renew_off"> +		Disabilitato +	</panel.string> +	<panel.string name="location_notice"> +		(si aggiornerà dopo il salvataggio) +	</panel.string> +	<string name="publish_label"> +		Pubblica +	</string> +	<string name="save_label"> +		Salva +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Fai clic per selezionare un'immagine"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Posizione:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="Tipo di contenuto:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Categoria:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Data di creazione:"/> +					<text_editor name="creation_date" tool_tip="Data di creazione" value="[date]"/> +					<text name="price_for_listing_label" value="Prezzo per inserzione:"/> +					<text_editor name="price_for_listing" tool_tip="Prezzo per inserzione."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Clic:"/> +					<text_editor name="click_through_text" tool_tip="Numero di clic" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Rinnovo automatico:"/> +					<text name="auto_renew" value="Abilitato"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Descrizione:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Titolo: +				</text> +				<text name="description_label"> +					Descrizione: +				</text> +				<text name="location_label"> +					Posizione: +				</text> +				<text name="classified_location_edit"> +					caricamento in corso... +				</text> +				<button label="Imposta come Luogo Attuale" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Categoria:"/> +				<text name="content_type_label" value="Tipo di contenuto:"/> +				<icons_combo_box label="Contenuto Generale" name="content_type_edit"> +					<icons_combo_box.item label="Contenuto Moderato" name="mature_ci" value="Per adulti"/> +					<icons_combo_box.item label="Contenuto Generale" name="pg_ci" value="PG"/> +				</icons_combo_box> +				<check_box label="Rinnovo automatico ogni settimana" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="Prezzo per inserzione:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="Prezzo per inserzione." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Teletrasporto" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Mappa" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Modifica" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="Annulla" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml new file mode 100644 index 0000000000..6fc0fd0729 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Annuncio" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="Nessuno annuncio"/> +	<button label="Nuovo..." name="new_btn"/> +	<button label="Elimina..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		Caricamento in corso... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml new file mode 100644 index 0000000000..bf8ccef273 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profilo" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/it/panel_profile_interests.xml b/indra/newview/skins/default/xui/it/panel_profile_interests.xml new file mode 100644 index 0000000000..9fe7331e5c --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Interessi" name="panel_profile_interests"> +	<text name="I Want To:"> +		Desidero: +	</text> +	<check_box label="Costruire" name="chk0"/> +	<check_box label="Esplorare" name="chk1"/> +	<check_box label="Incontrare" name="chk2"/> +	<check_box label="Essere assunto" name="chk6"/> +	<check_box label="Gruppo" name="chk3"/> +	<check_box label="Acquistare" name="chk4"/> +	<check_box label="Vendere" name="chk5"/> +	<check_box label="Assumere" name="chk7"/> +	<line_editor name="want_to_edit"> +		(caricamento in corso...) +	</line_editor> +	<text name="Skills:"> +		Abilità: +	</text> +	<check_box label="Texture" name="schk0"/> +	<check_box label="Architettura" name="schk1"/> +	<check_box label="Realizzazione modelli 3D" name="schk3"/> +	<check_box label="Organizzazione eventi" name="schk2"/> +	<check_box label="Scripting" name="schk4"/> +	<check_box label="Personaggi personalizzati" name="schk5"/> +	<line_editor name="skills_edit"> +		(caricamento in corso...) +	</line_editor> +	<text name="Languages:"> +		Lingue: +	</text> +	<line_editor name="languages_edit"> +		(caricamento in corso...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_notes.xml b/indra/newview/skins/default/xui/it/panel_profile_notes.xml new file mode 100644 index 0000000000..abd5a347c3 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Note e Privacy" name="panel_notes"> +	<text name="status_message" value="Annotazioni private su questo avatar:"/> +	<text name="status_message2" value="Consenti a questo avatar di:"/> +	<check_box label="Vedere quando sono in linea" name="status_check"/> +	<check_box label="Trovarmi sulla mappa del mondo" name="map_check"/> +	<check_box label="Modificare, eliminare o prendere i miei oggetti" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_pick.xml b/indra/newview/skins/default/xui/it/panel_profile_pick.xml new file mode 100644 index 0000000000..5d2b145565 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(si aggiornerà dopo il salvataggio) +	</panel.string> +	<line_editor name="pick_location"> +		Caricamento in corso... +	</line_editor> +	<button label="Teletrasporto" name="teleport_btn"/> +	<button label="Mostra sulla mappa" name="show_on_map_btn"/> +	<button label="Imposta Luogo" name="set_to_curr_location_btn" tool_tip="Imposta come Luogo Attuale"/> +	<button label="Salva Luogo preferito" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_picks.xml b/indra/newview/skins/default/xui/it/panel_profile_picks.xml new file mode 100644 index 0000000000..37cffcf622 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Preferiti" name="panel_picks"> +	<string name="no_picks" value="Nessun preferito"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Comunica a tutti quali sono i tuoi posti preferiti in Second Life. +	</text> +	<button label="Nuovo..." name="new_btn"/> +	<button label="Elimina..." name="delete_btn"/> +	<text name="picks_panel_text"> +		Caricamento in corso... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml new file mode 100644 index 0000000000..47af1960a5 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profilo" name="panel_profile"> +	<string name="status_online"> +		Ora in linea +	</string> +	<string name="status_offline"> +		Ora non in linea +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Nessuno"/> +	<string name="no_group_text" value="Nessuno"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Sviluppatore"/> +	<string name="FSSupp" value="Assistenza"/> +	<string name="FSQualityAssurance" value="Bug Hunter"/> +	<string name="FSGW" value="Gateway"/> +	<text name="name_label" value="Nome:"/> +	<button label="Nome:" name="set_name" tool_tip="Imposta nome visualizzato"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(caricamento in corso...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Stato Sconosciuto"/> +			<text name="label" value="Compleanno Second Life:"/> +			<text name="label2" value="Account:"/> +			<text name="partner_label" value="Partner:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Gruppi:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="Invita al gruppo:"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="Informazioni generali:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Consegna oggetto:"/> +			<text name="Give inventory" tool_tip="Rilascia gli oggetti dell’inventario per consegnarli a questa persona."> +				Rilascia l’oggetto dell’inventario qui. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Trova sulla mappa" label_selected="Trova sulla mappa" name="show_on_map_btn" tool_tip="Localizza il Residente sulla mappa"/> +			<button label="Paga" label_selected="Paga" name="pay" tool_tip="Paga del denaro al Residente"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Offri Teletrasporto" label_selected="Offri Teletrasporto" name="teleport" tool_tip="Offri il teletrasporto al Residente"/> +			<button label="Messaggio istantaneo" label_selected="Messaggio istantaneo" name="im" tool_tip="Apri sessione di messaggistica istantanea"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Aggiungi come amico" label_selected="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia al Residente"/> +			<button label="Blocca" name="block" tool_tip="Blocca questo Residente"/> +			<button label="Sblocca" name="unblock" tool_tip="Sblocca questo Residente"/> +		</layout_panel> +	</layout_stack> +	<check_box label="Mostra nella ricerca" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_web.xml b/indra/newview/skins/default/xui/it/panel_profile_web.xml new file mode 100644 index 0000000000..0c3a8ddcf5 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Tempo di caricamento: [TIME] secondi"/> +	<line_editor name="url_edit"> +		(caricamento in corso..) +	</line_editor> +	<flyout_button label="Carica" name="load" tool_tip="Carica la pagina profilo con il browser Web integrato."> +		<flyout_button.item label="Apri browser interno" name="open_item"/> +		<flyout_button.item label="Apri browser esterno" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Profilo web a comparsa"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml index c61ac3ecce..e08c55f63b 100644 --- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml @@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>  	<spinner bottom_delta="-34" label="Limite di abbassamento   del terreno" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Texture terreno (richiede file 512x512, 24 bit .tga) -	</text> +    Texture terreno (richiede file 1024x1024, 24 bit .tga) +  </text>  	<text name="height_text_lbl">  		1 (basso)  	</text> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index ea972e5a13..1ebdadb930 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -353,6 +353,24 @@ Prova ad accedere nuovamente tra un minuto.  	<string name="TestingDisconnect">  		Verifica scollegamento viewer  	</string> +	<string name="SocialFacebookConnecting"> +		Connessione a Facebook in corso... +	</string> +	<string name="SocialFacebookPosting"> +		Caricamento post... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Disconnessione da Facebook in corso... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Problemi con la connessione a Facebook +	</string> +	<string name="SocialFacebookErrorPosting"> +		Problemi con la connessione a Facebook +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Problemi con la disconnessione da Facebook +	</string>  	<string name="SocialFlickrConnecting">  		Collegamento a Flickr...  	</string> @@ -667,9 +685,6 @@ possono essere allegati ai biglietti.  	<string name="GroupNameNone">  		(nessuno)  	</string> -	<string name="AvalineCaller"> -		Chiamante Avaline [ORDER] -	</string>  	<string name="AssetErrorNone">  		Nessun errore  	</string> @@ -2557,9 +2572,21 @@ Se continui a ricevere questo messaggio, contatta l'assistenza Second Life  	<string name="NoPicksClassifiedsText">  		Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un'inserzione.  	</string> +	<string name="NoPicksText"> +		Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito. +	</string> +	<string name="NoClassifiedsText"> +		Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio. +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		L'utente non ha luoghi preferiti né inserzioni  	</string> +	<string name="NoAvatarPicksText"> +		L'utente non ha luoghi preferiti +	</string> +	<string name="NoAvatarClassifiedsText"> +		L'utente non ha annunci +	</string>  	<string name="PicksClassifiedsLoadingText">  		Caricamento in corso...  	</string> @@ -4474,6 +4501,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].  	<string name="inventory_folder_offered-im">  		Offerta cartella di inventario "[ITEM_NAME]"  	</string> +	<string name="facebook_post_success"> +		Hai pubblicato su Facebook. +	</string>  	<string name="flickr_post_success">  		Hai pubblicato su Flickr.  	</string> diff --git a/indra/newview/skins/default/xui/ja/floater_picks.xml b/indra/newview/skins/default/xui/ja/floater_picks.xml deleted file mode 100644 index 359585eb86..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_picks.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="ピック"/> diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml index 4617fd1d92..66ef13948a 100644 --- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		インベントリにコピー  	</floater.string> -	<text name="desc txt"> -		説明: -	</text> -	<text name="dimensions"> -		[WIDTH]px x [HEIGHT]px -	</text> -	<text name="aspect_ratio"> -		縦横比のプレビュー -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー"> -		<combo_item name="Unconstrained"> -			非拘束 -		</combo_item> -		<combo_item name="1:1" tool_tip="グループ記章か現実世界のプロフィール"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="[SECOND_LIFE] プロフィール"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="クラシファイド広告、検索一覧、ランドマーク"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="土地情報"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="プロフィールのピック"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="処分する" name="Discard"/> -	<button label="別名で保存" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				説明: +			</text> +			<text name="dimensions"> +				[WIDTH]px x [HEIGHT]px +			</text> +			<text name="aspect_ratio"> +				縦横比のプレビュー +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="処分する" name="Discard"/> +			<button label="別名で保存" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_profile.xml b/indra/newview/skins/default/xui/ja/floater_profile.xml new file mode 100644 index 0000000000..e06cd6e8f6 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="プロフィール"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="趣味" name="panel_profile_interests"/> +			<panel label="ピック" name="panel_profile_picks"/> +			<panel label="クラシファイド広告" name="panel_profile_classifieds"/> +			<panel label="リアルライフ(現実世界)" name="panel_profile_firstlife"/> +			<panel label="メモ" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="プロフィールの変更を保存して閉じる"/> +		<button label="キャンセル" label_selected="キャンセル" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml index f04193d034..64f292c75c 100644 --- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		メールの送信  	</string> +	<string name="facebook_progress_str"> +		Facebook へ投稿中 +	</string>  	<string name="profile_progress_str">  		投稿  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		コンピュータに保存  	</string> +	<string name="facebook_succeeded_str"> +		画像がアップロードされました +	</string>  	<string name="profile_succeeded_str">  		画像がアップロードされました  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		コンピュータに保存されました  	</string> +	<string name="facebook_failed_str"> +		Facebook のタイムラインに画像をアップロードできませんでした。 +	</string>  	<string name="profile_failed_str">  		プロフィールフィードに画像をアップロードできませんでした。  	</string> diff --git a/indra/newview/skins/default/xui/ja/menu_name_field.xml b/indra/newview/skins/default/xui/ja/menu_name_field.xml new file mode 100644 index 0000000000..8c37d95073 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="表示名をコピー" name="copy_display"/> +	<menu_item_call label="エージェント名をコピー" name="copy_name"/> +	<menu_item_call label="エージェント ID をコピー" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index a66552d3fe..92952f4c8a 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -2727,6 +2727,9 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml index cf5f2489f1..619e9de65a 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="キャンセル" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml index c48f13456b..ee57d178e8 100644 --- a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml @@ -16,5 +16,5 @@  		コメント (オプション):  	</text>  	<button label="投稿" name="post_photo_btn"/> -	<button label="取り消し" name="cancel_photo_btn"/> +	<button label="キャンセル" name="cancel_photo_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml index 61138f90c1..e97422a9df 100644 --- a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml +++ b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml @@ -5,5 +5,5 @@  	</text>  	<check_box initial_value="false" label="場所の俯瞰図を含める" name="add_place_view_cb"/>  	<button label="投稿" name="post_place_btn"/> -	<button label="取り消し" name="cancel_place_btn"/> +	<button label="キャンセル" name="cancel_place_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml index 9d962c9d62..1f48c9c8c7 100644 --- a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml +++ b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml @@ -9,12 +9,12 @@  		<button label="接続..." name="connect_btn"/>  		<button label="切断" name="disconnect_btn"/>  		<text name="account_learn_more_label"> -			[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]] +			[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]  		</text>  	</panel>  	<text name="status_caption_label">  		今、何を考えている?  	</text>  	<button label="投稿" name="post_status_btn"/> -	<button label="取り消し" name="cancel_status_btn"/> +	<button label="キャンセル" name="cancel_status_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml new file mode 100644 index 0000000000..77d3d8f391 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="不明"/> +	<button name="info_btn" tool_tip="詳細"/> +	<button name="profile_btn" tool_tip="プロフィールの表示"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml deleted file mode 100644 index 9b1cf1c8a4..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="プロフィール" name="panel_me"> -	<panel label="マイ ピック" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml index 0a295855d0..be00a3c122 100644 --- a/indra/newview/skins/default/xui/ja/panel_people.xml +++ b/indra/newview/skins/default/xui/ja/panel_people.xml @@ -40,6 +40,7 @@  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="オンライン"/>  				<accordion_tab name="tab_all" title="全員"/> +				<accordion_tab name="tab_suggested_friends" title="友だちになりたくない人"/>  			</accordion>  		</panel>  		<panel label="グループ" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classified.xml b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml new file mode 100644 index 0000000000..2d1bc07e2c --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Moderate +	</panel.string> +	<panel.string name="type_pg"> +		General コンテンツ +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] テレポート、 [MAP] 地図、 [PROFILE] プロフィール +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		有効 +	</panel.string> +	<panel.string name="auto_renew_off"> +		無効 +	</panel.string> +	<panel.string name="location_notice"> +		(掲載後更新) +	</panel.string> +	<string name="publish_label"> +		掲載 +	</string> +	<string name="save_label"> +		保存 +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="クリックして画像を選択"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="場所:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="コンテンツの種類:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="カテゴリ:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="制作日:"/> +					<text_editor name="creation_date" tool_tip="制作日" value="[date]"/> +					<text name="price_for_listing_label" value="掲載価格:"/> +					<text_editor name="price_for_listing" tool_tip="掲載価格。"> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="クリック数:"/> +					<text_editor name="click_through_text" tool_tip="クリックスルーデータ" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="自動更新:"/> +					<text name="auto_renew" value="有効"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="説明:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					タイトル: +				</text> +				<text name="description_label"> +					説明: +				</text> +				<text name="location_label"> +					場所: +				</text> +				<text name="classified_location_edit"> +					ロード中... +				</text> +				<button label="現在地に設定" name="set_to_curr_location_btn"/> +				<text name="category_label" value="カテゴリ:"/> +				<text name="content_type_label" value="コンテンツの種類:"/> +				<icons_combo_box label="General コンテンツ" name="content_type_edit"> +					<icons_combo_box.item label="Moderate コンテンツ" name="mature_ci" value="Mature"/> +					<icons_combo_box.item label="General コンテンツ" name="pg_ci" value="PG"/> +				</icons_combo_box> +				<check_box label="毎週自動更新" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="掲載価格:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="掲載価格。" value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="テレポート" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="地図" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="編集" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="キャンセル" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml new file mode 100644 index 0000000000..1980c0fa62 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="クラシファイド広告" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="クラシファイド広告なし"/> +	<button label="新規…" name="new_btn"/> +	<button label="削除…" name="delete_btn"/> +	<text name="classifieds_panel_text"> +		ロード中... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml new file mode 100644 index 0000000000..a4ee262cb3 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="プロフィール" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_interests.xml b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml new file mode 100644 index 0000000000..93cde6ffec --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="趣味" name="panel_profile_interests"> +	<text name="I Want To:"> +		次の内容を実行: +	</text> +	<check_box label="作る" name="chk0"/> +	<check_box label="探検" name="chk1"/> +	<check_box label="出会う" name="chk2"/> +	<check_box label="雇ってもらう" name="chk6"/> +	<check_box label="グループ" name="chk3"/> +	<check_box label="買う" name="chk4"/> +	<check_box label="販売する" name="chk5"/> +	<check_box label="雇う" name="chk7"/> +	<line_editor name="want_to_edit"> +		(ロード中...) +	</line_editor> +	<text name="Skills:"> +		スキル: +	</text> +	<check_box label="テクスチャ" name="schk0"/> +	<check_box label="建築" name="schk1"/> +	<check_box label="モデリング" name="schk3"/> +	<check_box label="イベント計画" name="schk2"/> +	<check_box label="スクリプト" name="schk4"/> +	<check_box label="キャラクターのカスタマイズ" name="schk5"/> +	<line_editor name="skills_edit"> +		(ロード中...) +	</line_editor> +	<text name="Languages:"> +		言語: +	</text> +	<line_editor name="languages_edit"> +		(ロード中...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_notes.xml b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml new file mode 100644 index 0000000000..4b4e0d5e4e --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="メモとプライバシー" name="panel_notes"> +	<text name="status_message" value="このアバターのプライベートメモ:"/> +	<text name="status_message2" value="このアバターに次の許可を与える:"/> +	<check_box label="自分のオンラインステータスを表示する" name="status_check"/> +	<check_box label="世界地図で自分を探せるようにする" name="map_check"/> +	<check_box label="自分のオブジェクトを編集・削除・取得できるようにする" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_pick.xml b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml new file mode 100644 index 0000000000..0a20c04ad6 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(掲載後更新) +	</panel.string> +	<line_editor name="pick_location"> +		ロード中... +	</line_editor> +	<button label="テレポート" name="teleport_btn"/> +	<button label="地図に表示" name="show_on_map_btn"/> +	<button label="場所を設定" name="set_to_curr_location_btn" tool_tip="現在地に設定"/> +	<button label="ピックを保存" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml new file mode 100644 index 0000000000..4cbfadd09d --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="ピック" name="panel_picks"> +	<string name="no_picks" value="ピックなし"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Second Life のお気に入りの場所を紹介しましょう。 +	</text> +	<button label="新規…" name="new_btn"/> +	<button label="削除…" name="delete_btn"/> +	<text name="picks_panel_text"> +		ロード中... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml new file mode 100644 index 0000000000..5470dc6c82 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="プロフィール" name="panel_profile"> +	<string name="status_online"> +		オンライン中 +	</string> +	<string name="status_offline"> +		オフライン中 +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="なし"/> +	<string name="no_group_text" value="なし"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="開発者"/> +	<string name="FSSupp" value="サポート"/> +	<string name="FSQualityAssurance" value="バグハンター"/> +	<string name="FSGW" value="ゲートウェイ"/> +	<text name="name_label" value="名前:"/> +	<button label="名前:" name="set_name" tool_tip="表示名を設定"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(ロード中...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="ステータス不明"/> +			<text name="label" value="Second Life 生年月日:"/> +			<text name="label2" value="アカウント:"/> +			<text name="partner_label" value="パートナー:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="グループ:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="グループに招待"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="詳細:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="アイテムを渡す:"/> +			<text name="Give inventory" tool_tip="インベントリのアイテムをここにドロップしてこの人に渡します。"> +				インベントリのアイテムをここにドロップしてください。 +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="地図上で見つける" label_selected="地図上で見つける" name="show_on_map_btn" tool_tip="住人を地図上で探す"/> +			<button label="お金を払う" label_selected="お金を払う" name="pay" tool_tip="住人にお金を支払う"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="テレポートを送る" label_selected="テレポートを送る" name="teleport" tool_tip="住人にテレポートを送る"/> +			<button label="インスタントメッセージ" label_selected="インスタントメッセージ" name="im" tool_tip="インスタントメッセージを開きます"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="フレンド登録" label_selected="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/> +			<button label="ブロック" name="block" tool_tip="この住人をブロックする"/> +			<button label="ブロック解除" name="unblock" tool_tip="この住人のブロックを解除する"/> +		</layout_panel> +	</layout_stack> +	<check_box label="検索に表示" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_web.xml b/indra/newview/skins/default/xui/ja/panel_profile_web.xml new file mode 100644 index 0000000000..4f56a7e98d --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="ロード時間:[TIME] 秒"/> +	<line_editor name="url_edit"> +		(ロード中...) +	</line_editor> +	<flyout_button label="ロード" name="load" tool_tip="このプロフィールページを、組み込み Web ブラウザでロードします。"> +		<flyout_button.item label="ビューワ内のブラウザを開く" name="open_item"/> +		<flyout_button.item label="外部ブラウザを開く" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Web プロフィールのポップアウト"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml index fb853c1925..c1080a7d7b 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml @@ -10,8 +10,8 @@  	<spinner label="地形の上昇限度" name="terrain_raise_spin"/>  	<spinner label="地形の下降限度" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		地形テクスチャ(512x512 の 24 bit .tga ファイル) -	</text> +    地形テクスチャ(1024x1024 の 24 bit .tga ファイル) +  </text>  	<text name="height_text_lbl">  		1(低)  	</text> diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml index 04dfc0176d..f222a4d61a 100644 --- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml @@ -3,7 +3,7 @@  	<button label="ディスクに保存" name="save_to_computer_btn"/>  	<button label="持ち物に保存(L$[AMOUNT])" name="save_to_inventory_btn"/>  	<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/> -	<button label="Facebook で共有する" name="send_to_facebook_btn"/> +	<button label="Facebook でシェア" name="send_to_facebook_btn"/>  	<button label="Twitter で共有する" name="send_to_twitter_btn"/>  	<button label="Flickr で共有する" name="send_to_flickr_btn"/>  	<button label="メールにより送信" name="save_to_email_btn"/> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 344f9fcd94..d90772ab0a 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -356,6 +356,24 @@ support@secondlife.com にお問い合わせください。  	<string name="TestingDisconnect">  		ビューワの接続を切るテスト中  	</string> +	<string name="SocialFacebookConnecting"> +		Facebook に接続中... +	</string> +	<string name="SocialFacebookPosting"> +		投稿中... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Facebook から切断中... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Facebook への接続時のエラー +	</string> +	<string name="SocialFacebookErrorPosting"> +		Facebook への投稿時のエラー +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Facebook からの切断時のエラー +	</string>  	<string name="SocialFlickrConnecting">  		Flickr に接続中...  	</string> @@ -673,9 +691,6 @@ support@secondlife.com にお問い合わせください。  	<string name="GroupNameNone">  		(なし)  	</string> -	<string name="AvalineCaller"> -		Avaline コール [ORDER] -	</string>  	<string name="AssetErrorNone">  		エラーなし  	</string> @@ -2577,9 +2592,21 @@ support@secondlife.com にお問い合わせください。  	<string name="NoPicksClassifiedsText">  		ピックやクラシファイド広告を作成していません。 作成するには、下にある「プラス」ボタンをクリックします。  	</string> +	<string name="NoPicksText"> +		ピックを作成していません。[新規] ボタンをクリックしてピックを作成する。 +	</string> +	<string name="NoClassifiedsText"> +		クラシファイド広告を作成していません。[新規] ボタンをクリックしてクラシファイド広告を作成する。 +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		ピック、またはクラシファイド広告がありません  	</string> +	<string name="NoAvatarPicksText"> +		ピックがありません +	</string> +	<string name="NoAvatarClassifiedsText"> +		クラシファイド広告がありません +	</string>  	<string name="PicksClassifiedsLoadingText">  		ローディング...  	</string> @@ -4557,6 +4584,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ  	<string name="share_alert">  		インベントリからここにアイテムをドラッグします  	</string> +	<string name="facebook_post_success"> +		Facebook に投稿しました。 +	</string>  	<string name="flickr_post_success">  		Flickr に投稿しました。  	</string> diff --git a/indra/newview/skins/default/xui/pl/floater_picks.xml b/indra/newview/skins/default/xui/pl/floater_picks.xml deleted file mode 100644 index a329e834db..0000000000 --- a/indra/newview/skins/default/xui/pl/floater_picks.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<floater name="floater_picks" title="Miejsca" /> diff --git a/indra/newview/skins/default/xui/pl/panel_me.xml b/indra/newview/skins/default/xui/pl/panel_me.xml deleted file mode 100644 index 431929420a..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel label="Mój Profil" name="panel_me"> -	<panel label="MIEJSCA" name="panel_picks" /> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml index f086a52dcd..2d4286334f 100644 --- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml @@ -7,7 +7,7 @@  	<spinner label="Górny limit terenu" name="terrain_raise_spin" />  	<spinner label="Dolny limit terenu" name="terrain_lower_spin" />  	<text name="detail_texture_text"> -		Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga) +		Tekstury terenu (1024x1024, 24 bitowy plik .tga)  	</text>  	<text name="height_text_lbl">  		1 (Nisko) diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 2b182dc3cc..90d2d86c02 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -596,9 +596,6 @@ Spróbuj zalogować się ponownie za minutę.  	<string name="GroupNameNone">  		(brak danych)  	</string> -	<string name="AvalineCaller"> -		Avaline [ORDER] -	</string>  	<string name="AssetErrorNone">  		Brak błędu  	</string> diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml index c50d7dcda0..a43dec4e7b 100644 --- a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml @@ -6,7 +6,7 @@  	<check_box label="Gestos" name="check_gesture"/>  	<check_box label="Landmarks" name="check_landmark"/>  	<check_box label="Anotações" name="check_notecard"/> -	<check_box label="Meshes:" name="check_mesh"/> +	<check_box label="Malhas" name="check_mesh"/>  	<check_box label="Objetos" name="check_object"/>  	<check_box label="Scripts" name="check_script"/>  	<check_box label="Sons" name="check_sound"/> diff --git a/indra/newview/skins/default/xui/pt/floater_picks.xml b/indra/newview/skins/default/xui/pt/floater_picks.xml deleted file mode 100644 index 9766196319..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_picks.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Destaques"/> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml index 6f39635240..90102023a3 100644 --- a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		Copiar para inventário  	</floater.string> -	<text name="desc txt"> -		Descrição: -	</text> -	<text name="dimensions"> -		[WIDTH]px x [HEIGHT]px -	</text> -	<text name="aspect_ratio"> -		Visualizar relação de aspecto -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa"> -		<combo_item name="Unconstrained"> -			Sem limites -		</combo_item> -		<combo_item name="1:1" tool_tip="Símbolo ou perfil RW do grupo"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="[SECOND_LIFE] perfil"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="Procurar anúncios classificados e marcos"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="Sobre terrenos"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Perfis destacados"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="Descartar" name="Discard"/> -	<button label="Salvar como" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Descrição: +			</text> +			<text name="dimensions"> +				[WIDTH]px x [HEIGHT]px +			</text> +			<text name="aspect_ratio"> +				Visualizar relação de aspecto +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="Descartar" name="Discard"/> +			<button label="Salvar como" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_profile.xml b/indra/newview/skins/default/xui/pt/floater_profile.xml new file mode 100644 index 0000000000..0327211d8f --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Perfil"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="Interesses" name="panel_profile_interests"/> +			<panel label="Destaques" name="panel_profile_picks"/> +			<panel label="Anúncio" name="panel_profile_classifieds"/> +			<panel label="Vida real" name="panel_profile_firstlife"/> +			<panel label="Observações" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="Salvar alterações do perfil e fechar"/> +		<button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml index e3812ed708..89901b539f 100644 --- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		Enviando e-mail  	</string> +	<string name="facebook_progress_str"> +		Como publicar no Facebook +	</string>  	<string name="profile_progress_str">  		Postando  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Salvo no computador  	</string> +	<string name="facebook_succeeded_str"> +		Imagem carregada +	</string>  	<string name="profile_succeeded_str">  		Imagem carregada  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		Salvo no computador!  	</string> +	<string name="facebook_failed_str"> +		Falha ao carregar a imagem na sua linha do tempo no Facebook. +	</string>  	<string name="profile_failed_str">  		Falha ao carregar a imagem no feed do seu perfil.  	</string> diff --git a/indra/newview/skins/default/xui/pt/menu_name_field.xml b/indra/newview/skins/default/xui/pt/menu_name_field.xml new file mode 100644 index 0000000000..2157de9813 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Exibir Cópia do Nome" name="copy_display"/> +	<menu_item_call label="Copiar Nome do Agente" name="copy_name"/> +	<menu_item_call label="Copiar Id do Agente" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index bd1185bdd2..733ec2c709 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -2673,6 +2673,9 @@ Selecione só um objeto.  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml index 23e00bfc3a..7b27c811f5 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="Cancelar" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml index 64a7d13fdb..f6c6d11b87 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_general.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml @@ -46,7 +46,7 @@ Para obter mais ajuda, passe o mouse sobre as opções.  		<check_box label="Qualquer um pode entrar" name="open_enrollement" tool_tip="Controla a entrada de novos membros, com ou sem convite."/>  		<check_box label="Taxa de inscrição" name="check_enrollment_fee" tool_tip="Controla a cobrança de uma taxa de associação ao grupo."/>  		<spinner label="L$" left_delta="120" name="spin_enrollment_fee" tool_tip="Se a opção 'Taxa de associação' estiver marcada, novos membros precisam pagar o valor definido para entrar no grupo." width="60"/> -		<combo_box name="group_mature_check" tool_tip="Os níveis de maturidade determinam o tipo de conteúdo e comportamento permitidos em um grupo" width="170"> +		<combo_box name="group_mature_check" tool_tip="Definir se o seu grupo contém informações classificadas como Moderado" width="170">  			<combo_item name="select_mature">  				- Selecione o nível de maturidade -  			</combo_item> diff --git a/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml new file mode 100644 index 0000000000..0490878507 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Desconhecido"/> +	<button name="info_btn" tool_tip="Mais informações"/> +	<button name="profile_btn" tool_tip="Ver perfil"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_me.xml b/indra/newview/skins/default/xui/pt/panel_me.xml deleted file mode 100644 index 281c886bd4..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Meu perfil" name="panel_me"> -	<panel label="MEUS DESTAQUES" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml index 2ef01841c5..ce50449b03 100644 --- a/indra/newview/skins/default/xui/pt/panel_people.xml +++ b/indra/newview/skins/default/xui/pt/panel_people.xml @@ -40,6 +40,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="Online"/>  				<accordion_tab name="tab_all" title="Todos"/> +				<accordion_tab name="tab_suggested_friends" title="Pessoas que talvez você deseje adicionar"/>  			</accordion>  		</panel>  		<panel label="GRUPOS" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classified.xml b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml new file mode 100644 index 0000000000..b43a0ad9f2 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Moderado +	</panel.string> +	<panel.string name="type_pg"> +		Conteúdo Geral +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE]- +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Ativado +	</panel.string> +	<panel.string name="auto_renew_off"> +		Desativado +	</panel.string> +	<panel.string name="location_notice"> +		(salvar para atualizar) +	</panel.string> +	<string name="publish_label"> +		Publicar +	</string> +	<string name="save_label"> +		Salvar +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Selecione uma imagem"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Localização:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="Tipo de conteúdo:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Categoria:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Data de criação:"/> +					<text_editor name="creation_date" tool_tip="Data de criação" value="[date]"/> +					<text name="price_for_listing_label" value="Preço do anúncio:"/> +					<text_editor name="price_for_listing" tool_tip="Preço do anúncio."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Cliques:"/> +					<text_editor name="click_through_text" tool_tip="Dados de click-through" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Renovação automática:"/> +					<text name="auto_renew" value="Ativado"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Descrição:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Título: +				</text> +				<text name="description_label"> +					Descrição: +				</text> +				<text name="location_label"> +					Localização: +				</text> +				<text name="classified_location_edit"> +					Carregando... +				</text> +				<button label="Usar configuração local" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Categoria:"/> +				<text name="content_type_label" value="Tipo de conteúdo:"/> +				<icons_combo_box label="Conteúdo Geral" name="content_type_edit"> +					<icons_combo_box.item label="Conteúdo Moderado" name="mature_ci" value="Moderado"/> +					<icons_combo_box.item label="Conteúdo Geral" name="pg_ci" value="Adequado para menores"/> +				</icons_combo_box> +				<check_box label="Renovar automaticamente todas as semanas" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="Preço do anúncio:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="Preço do anúncio." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Teletransportar" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Mapa" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Editar" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="Cancelar" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml new file mode 100644 index 0000000000..f8369954fd --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Anúncio" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="Nenhum classificado"/> +	<button label="Novo..." name="new_btn"/> +	<button label="Excluir..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		Carregando... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/it/floater_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml index dfc539da66..0fb502e441 100644 --- a/indra/newview/skins/default/xui/it/floater_picks.xml +++ b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml @@ -1,2 +1,2 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Preferiti"/> +<panel label="Perfil" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_interests.xml b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml new file mode 100644 index 0000000000..edf74115f2 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Interesses" name="panel_profile_interests"> +	<text name="I Want To:"> +		Quero: +	</text> +	<check_box label="Crie" name="chk0"/> +	<check_box label="Explore" name="chk1"/> +	<check_box label="Encontrar" name="chk2"/> +	<check_box label="Seja contratado" name="chk6"/> +	<check_box label="Grupo" name="chk3"/> +	<check_box label="Comprar" name="chk4"/> +	<check_box label="Venda" name="chk5"/> +	<check_box label="Contratar" name="chk7"/> +	<line_editor name="want_to_edit"> +		(carregando...) +	</line_editor> +	<text name="Skills:"> +		Habilidades: +	</text> +	<check_box label="Texturas" name="schk0"/> +	<check_box label="Arquitetura" name="schk1"/> +	<check_box label="Modelo" name="schk3"/> +	<check_box label="Planejamento de evento" name="schk2"/> +	<check_box label="Scripts" name="schk4"/> +	<check_box label="Personagens personalizados" name="schk5"/> +	<line_editor name="skills_edit"> +		(carregando...) +	</line_editor> +	<text name="Languages:"> +		Idiomas: +	</text> +	<line_editor name="languages_edit"> +		(carregando...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_notes.xml b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml new file mode 100644 index 0000000000..499e371bb7 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Anotações e Privacidade" name="panel_notes"> +	<text name="status_message" value="Notas particulares neste avatar:"/> +	<text name="status_message2" value="Permitir que esse avatar:"/> +	<check_box label="Ver quando eu estiver conectado" name="status_check"/> +	<check_box label="Encontre-me no mapa-múndi" name="map_check"/> +	<check_box label="Pegar, editar ou excluir objetos meus" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_pick.xml b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml new file mode 100644 index 0000000000..2dd37b38f9 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(salvar para atualizar) +	</panel.string> +	<line_editor name="pick_location"> +		Carregando... +	</line_editor> +	<button label="Teletransportar" name="teleport_btn"/> +	<button label="Mostrar no mapa" name="show_on_map_btn"/> +	<button label="Definir Localização" name="set_to_curr_location_btn" tool_tip="Usar configuração local"/> +	<button label="Salvar destaque" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml new file mode 100644 index 0000000000..f9ead974dc --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Destaques" name="panel_picks"> +	<string name="no_picks" value="Nenhum"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Conte a todos sobre os seu lugares favoritos no Second Life. +	</text> +	<button label="Novo..." name="new_btn"/> +	<button label="Excluir..." name="delete_btn"/> +	<text name="picks_panel_text"> +		Carregando... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml new file mode 100644 index 0000000000..8723b1bf58 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Perfil" name="panel_profile"> +	<string name="status_online"> +		Atualmente Online +	</string> +	<string name="status_offline"> +		Atualmente Offline +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Nenhum"/> +	<string name="no_group_text" value="Nenhum"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Desenvolvedor"/> +	<string name="FSSupp" value="Suporte"/> +	<string name="FSQualityAssurance" value="Caçador de Bug"/> +	<string name="FSGW" value="Gateway"/> +	<text name="name_label" value="Nome:"/> +	<button label="Nome:" name="set_name" tool_tip="Definir nome de tela"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(carregando...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Status desconhecido"/> +			<text name="label" value="Aniversário Second Life:"/> +			<text name="label2" value="Conta:"/> +			<text name="partner_label" value="Parceiro(a):"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Grupos:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="Convidar para entrar no grupo"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="Sobre:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Dar o item:"/> +			<text name="Give inventory" tool_tip="Arraste e solte o item novo do inventário aqui para dá-los a esta pessoa."> +				Arraste e solte o item novo do inventário aqui. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Localizar no mapa" label_selected="Localizar no mapa" name="show_on_map_btn" tool_tip="Localizar o Residente no mapa"/> +			<button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pague em dinheiro para o Residente"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Teletransportar?" label_selected="Teletransportar?" name="teleport" tool_tip="Oferecer teletransporte ao Residente"/> +			<button label="Mensagem instantânea" label_selected="Mensagem instantânea" name="im" tool_tip="Abrir sessão de mensagem instantânea"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Adicionar amigo" label_selected="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/> +			<button label="Bloquear" name="block" tool_tip="Bloquear este Residente"/> +			<button label="Desbloquear" name="unblock" tool_tip="Desbloquear este Residente"/> +		</layout_panel> +	</layout_stack> +	<check_box label="Mostrar nos resultados de busca" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_web.xml b/indra/newview/skins/default/xui/pt/panel_profile_web.xml new file mode 100644 index 0000000000..0f556c7dad --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Carregar tempo: [TIME] segundos"/> +	<line_editor name="url_edit"> +		(carregando..) +	</line_editor> +	<flyout_button label="Carregar" name="load" tool_tip="Carregar esta página de perfil com navegador embutido"> +		<flyout_button.item label="Abrir no visualizador do navegador" name="open_item"/> +		<flyout_button.item label="Abrir no navegador externo" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Abra o perfil da web"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml index 74330a8946..1d312aeed9 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml @@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>  	<spinner bottom_delta="-34" label="Limite mais baixo do   terreno" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Texturas de terreno (exige arquivos .tga 512x512, 24 bit) -	</text> +    Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit) +  </text>  	<text name="height_text_lbl">  		1 (Baixo)  	</text> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 7c593ab3be..ae452d6a4d 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -47,7 +47,7 @@ Placa de vídeo: [GRAPHICS_CARD_VENDOR]  Placa gráfica: [GRAPHICS_CARD]  	</string>  	<string name="AboutDriver"> -		Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR] +		Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]  	</string>  	<string name="AboutOGL">  		Versão do OpenGL: [OPENGL_VERSION] @@ -313,6 +313,24 @@ Aguarde um minuto antes que tentar logar-se novamente.  	<string name="TestingDisconnect">  		Teste de desconexão  	</string> +	<string name="SocialFacebookConnecting"> +		Conectando ao Facebook... +	</string> +	<string name="SocialFacebookPosting"> +		Publicando... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Desconectando do Facebook... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Problema ao conectar ao Facebook +	</string> +	<string name="SocialFacebookErrorPosting"> +		Problema ao publicar no Facebook +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Problema ao desconectar do Facebook +	</string>  	<string name="SocialFlickrConnecting">  		Conectando ao Flickr...  	</string> @@ -627,9 +645,6 @@ ser anexado às anotações.  	<string name="GroupNameNone">  		(nenhum)  	</string> -	<string name="AvalineCaller"> -		Interlocutor Avaline [ORDER] -	</string>  	<string name="AssetErrorNone">  		Nenhum erro  	</string> @@ -2517,9 +2532,21 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se  	<string name="NoPicksClassifiedsText">  		Você não criou nenhum Destaque ou Anúncio.  Clique no botão "+" para criar um Destaque ou Anúncio.  	</string> +	<string name="NoPicksText"> +		Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher +	</string> +	<string name="NoClassifiedsText"> +		Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		O usuário não tem nenhum destaque ou anúncio  	</string> +	<string name="NoAvatarPicksText"> +		Usuário não tem escolha +	</string> +	<string name="NoAvatarClassifiedsText"> +		Usuário não tem anúncio +	</string>  	<string name="PicksClassifiedsLoadingText">  		Carregando...  	</string> @@ -4433,6 +4460,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	<string name="inventory_folder_offered-im">  		Pasta do inventário '[ITEM_NAME]' oferecida  	</string> +	<string name="facebook_post_success"> +		Você publicou no Facebook. +	</string>  	<string name="flickr_post_success">  		Você publicou no Flickr.  	</string> diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml index 7c1d3b52c5..bf90d898f9 100644 --- a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml @@ -6,7 +6,7 @@  	<check_box label="Жесты" name="check_gesture"/>  	<check_box label="Закладки" name="check_landmark"/>  	<check_box label="Заметки" name="check_notecard"/> -	<check_box label="Меши" name="check_mesh"/> +	<check_box label="Полисетки" name="check_mesh"/>  	<check_box label="Объекты" name="check_object"/>  	<check_box label="Скрипты" name="check_script"/>  	<check_box label="Звуки" name="check_sound"/> diff --git a/indra/newview/skins/default/xui/ru/floater_picks.xml b/indra/newview/skins/default/xui/ru/floater_picks.xml deleted file mode 100644 index e0ae8d6f03..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_picks.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Подборка"/> diff --git a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml index 46d2a37503..e3921a75ac 100644 --- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		Копировать в инвентарь  	</floater.string> -	<text name="desc txt"> -		Описание: -	</text> -	<text name="dimensions"> -		[WIDTH]пикселей x [HEIGHT]пикселей -	</text> -	<text name="aspect_ratio"> -		Просмотр изображения с соотношением сторон -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон"> -		<combo_item name="Unconstrained"> -			Без ограничения -		</combo_item> -		<combo_item name="1:1" tool_tip="Символ группы или профиль в реальном мире"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="Профиль для [SECOND_LIFE]"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="Реклама, поиск и закладки"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="О земле"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Профиль подборки"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="OK" name="Keep"/> -	<button label="Отменить" name="Discard"/> -	<button label="Сохранить как" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Описание: +			</text> +			<text name="dimensions"> +				[WIDTH]пикселей x [HEIGHT]пикселей +			</text> +			<text name="aspect_ratio"> +				Предварительный просмотр соотношения сторон +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="OK" name="Keep"/> +			<button label="Сбросить" name="Discard"/> +			<button label="Сохранить как" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_profile.xml b/indra/newview/skins/default/xui/ru/floater_profile.xml new file mode 100644 index 0000000000..6f8daf0a62 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Профиль"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Веб" name="panel_profile_web"/> +			<panel label="Круг интересов" name="panel_profile_interests"/> +			<panel label="Подборка" name="panel_profile_picks"/> +			<panel label="Объявление" name="panel_profile_classifieds"/> +			<panel label="Реальная жизнь" name="panel_profile_firstlife"/> +			<panel label="Примечания" name="panel_profile_notes"/> +		</tab_container> +		<button label="OK" name="ok_btn" tool_tip="Сохранить изменения в профиле и закрыть"/> +		<button label="Отменить" label_selected="Отменить" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml index 3ac8cb74b4..89a453d9cd 100644 --- a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml @@ -67,7 +67,7 @@  		<combo_box.item label="Земля > Посягательство > Объекты или текстуры" name="Land__Encroachment__Objects_textures"/>  		<combo_box.item label="Земля > Посягательство > Частицы" name="Land__Encroachment__Particles"/>  		<combo_box.item label="Земля > Посягательство > Деревья/растения" name="Land__Encroachment__Trees_plants"/> -		<combo_box.item label="Нарушение правил игр на ловкость" name="Wagering_gambling"/> +		<combo_box.item label="Нарушение игровых правил" name="Wagering_gambling"/>  		<combo_box.item label="Другое" name="Other"/>  	</combo_box>  	<text name="abuser_name_title"> diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml index 97de279b8f..a796d942f3 100644 --- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		Отправка письма  	</string> +	<string name="facebook_progress_str"> +		Публикация в Facebook +	</string>  	<string name="profile_progress_str">  		Публикация  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Сохранение на компьютере  	</string> +	<string name="facebook_succeeded_str"> +		Изображение загружено +	</string>  	<string name="profile_succeeded_str">  		Изображение отправлено  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		Сохранено на компьютере!  	</string> +	<string name="facebook_failed_str"> +		Не удалось передать изображение на вашу хронику Facebook. +	</string>  	<string name="profile_failed_str">  		Не удалось передать изображение в ваш профиль.  	</string> diff --git a/indra/newview/skins/default/xui/ru/menu_name_field.xml b/indra/newview/skins/default/xui/ru/menu_name_field.xml new file mode 100644 index 0000000000..889f3c37ab --- /dev/null +++ b/indra/newview/skins/default/xui/ru/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Копировать отображаемое имя" name="copy_display"/> +	<menu_item_call label="Копировать имя агента" name="copy_name"/> +	<menu_item_call label="Копировать Id агента" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index bfcda798be..e75fd1fd82 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -2682,6 +2682,9 @@  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml index a2f06dbadf..ec457c4565 100644 --- a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml @@ -46,8 +46,8 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> -				<button label="Отмена" name="cancel_btn"/> +			<layout_panel name="cancel_btn_lp"> +				<button label="Отменить" name="cancel_btn"/>  			</layout_panel>  		</layout_stack>  	</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml index 746da8d523..1e4d1346f7 100644 --- a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml +++ b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_friends"> -	<string name="facebook_friends_empty" value="Сейчас у вас нет друзей по Facebook, которые также были бы жителями Second Life. Предложите своим друзьям по Facebook присоединиться к Second Life!"/> +	<string name="facebook_friends_empty" value="Сейчас у вас нет друзей в Facebook, которые являются также жителями Second Life. Предложите своим друзьям в Facebook присоединиться к Second Life!"/>  	<string name="facebook_friends_no_connected" value="Сейчас вы не подключены к Facebook. Перейдите на вкладку «Статус», чтобы подключиться и включить эту функцию."/>  	<accordion name="friends_accordion">  		<accordion_tab name="tab_second_life_friends" title="Друзья по SL"/> diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml index 143a57fec7..50296778ff 100644 --- a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml @@ -2,19 +2,19 @@  <panel name="panel_facebook_photo">  	<combo_box name="resolution_combobox" tool_tip="Разрешение изображения">  		<combo_box.item label="Текущее окно" name="CurrentWindow"/> -		<combo_box.item label="640x480" name="640x480"/> -		<combo_box.item label="800x600" name="800x600"/> -		<combo_box.item label="1024x768" name="1024x768"/> -		<combo_box.item label="1200x630" name="1200x630"/> +		<combo_box.item label="640 x 480" name="640x480"/> +		<combo_box.item label="800 x 600" name="800x600"/> +		<combo_box.item label="1024 x 768" name="1024x768"/> +		<combo_box.item label="1200 x 630" name="1200x630"/>  	</combo_box>  	<combo_box name="filters_combobox" tool_tip="Фильтры изображений">  		<combo_box.item label="Без фильтра" name="NoFilter"/>  	</combo_box> -	<button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкните для обновления"/> -	<button label="Просмотр" name="big_preview_btn" tool_tip="Щелкните для смены вида"/> +	<button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкнуть для обновления"/> +	<button label="Предпросмотр" name="big_preview_btn" tool_tip="Щелкнуть для смены вида"/>  	<text name="caption_label">  		Комментарий (не обязательно):  	</text>  	<button label="Опубликовать" name="post_photo_btn"/> -	<button label="Отмена" name="cancel_photo_btn"/> +	<button label="Отменить" name="cancel_photo_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml index 7d0917a43a..a7fadca059 100644 --- a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml +++ b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml @@ -1,9 +1,9 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_place">  	<text name="place_caption_label"> -		Напишите о том, где вы: +		Сообщите, где вы находитесь:  	</text>  	<check_box initial_value="false" label="Включить вид места сверху" name="add_place_view_cb"/>  	<button label="Опубликовать" name="post_place_btn"/> -	<button label="Отмена" name="cancel_place_btn"/> +	<button label="Отменить" name="cancel_place_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml index c651a8087c..826ac6a08c 100644 --- a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml +++ b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml @@ -1,20 +1,20 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_status">  	<string name="facebook_connected" value="Вы подключились к Facebook как:"/> -	<string name="facebook_disconnected" value="Не подключено к Facebook"/> +	<string name="facebook_disconnected" value="Нет подключения к Facebook"/>  	<text name="account_caption_label"> -		Не подключено к Facebook. +		Нет подключения к Facebook.  	</text>  	<panel name="panel_buttons"> -		<button label="Подключение..." name="connect_btn"/> -		<button label="Отключить" name="disconnect_btn"/> +		<button label="Соединение..." name="connect_btn"/> +		<button label="Разъединить" name="disconnect_btn"/>  		<text name="account_learn_more_label"> -			[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 О публикации в Facebook] +			[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Узнать о публикации в Facebook]  		</text>  	</panel>  	<text name="status_caption_label">  		О чем вы думаете?  	</text>  	<button label="Опубликовать" name="post_status_btn"/> -	<button label="Отмена" name="cancel_status_btn"/> +	<button label="Отменить" name="cancel_status_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml new file mode 100644 index 0000000000..3408969d09 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Неизвестно"/> +	<button name="info_btn" tool_tip="Больше информации"/> +	<button name="profile_btn" tool_tip="Посмотреть профиль"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_me.xml b/indra/newview/skins/default/xui/ru/panel_me.xml deleted file mode 100644 index 21a125af87..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Мой профиль" name="panel_me"> -	<panel label="МОЯ ПОДБОРКА" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml index 0812eb7433..8170c8d26f 100644 --- a/indra/newview/skins/default/xui/ru/panel_people.xml +++ b/indra/newview/skins/default/xui/ru/panel_people.xml @@ -40,6 +40,7 @@  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="Онлайн"/>  				<accordion_tab name="tab_all" title="Все"/> +				<accordion_tab name="tab_suggested_friends" title="С кем вы можете подружиться"/>  			</accordion>  		</panel>  		<panel label="ГРУППЫ" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classified.xml b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml new file mode 100644 index 0000000000..2d3ed685c0 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Умеренная +	</panel.string> +	<panel.string name="type_pg"> +		Общий контент +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		Телепорт [TELEPORT], карта [MAP], профиль [PROFILE] +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Включен +	</panel.string> +	<panel.string name="auto_renew_off"> +		Отключен +	</panel.string> +	<panel.string name="location_notice"> +		(будет обновлено после сохранения) +	</panel.string> +	<string name="publish_label"> +		Опубликовать +	</string> +	<string name="save_label"> +		Сохранить +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Щелкнуть для выбора изображения"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Местоположение:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="Тип контента:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Категория:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Дата создания:"/> +					<text_editor name="creation_date" tool_tip="Дата создания" value="[date]"/> +					<text name="price_for_listing_label" value="Стоимость размещения:"/> +					<text_editor name="price_for_listing" tool_tip="Цена за размещение."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Клики:"/> +					<text_editor name="click_through_text" tool_tip="Информация о переходах" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Автоматическое продление:"/> +					<text name="auto_renew" value="Включен"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Описание:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Название: +				</text> +				<text name="description_label"> +					Описание: +				</text> +				<text name="location_label"> +					Местоположение: +				</text> +				<text name="classified_location_edit"> +					загрузка... +				</text> +				<button label="Установить в текущее местоположение" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Категория:"/> +				<text name="content_type_label" value="Тип контента:"/> +				<icons_combo_box label="Общий контент" name="content_type_edit"> +					<icons_combo_box.item label="Умеренный контент" name="mature_ci" value="Возрастной"/> +					<icons_combo_box.item label="Общий контент" name="pg_ci" value="C разрешения родителей"/> +				</icons_combo_box> +				<check_box label="Автоматическое обновление каждую неделю" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="Стоимость размещения:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="Цена за размещение." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Телепорт" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Карта" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Редактировать" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="Отменить" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml new file mode 100644 index 0000000000..fac494682a --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Объявление" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="Нет рекламы"/> +	<button label="Новый..." name="new_btn"/> +	<button label="Удалить..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		Загрузка... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml new file mode 100644 index 0000000000..f5ac5e906a --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Профиль" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_interests.xml b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml new file mode 100644 index 0000000000..ba1c3d0357 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Круг интересов" name="panel_profile_interests"> +	<text name="I Want To:"> +		Я собираюсь: +	</text> +	<check_box label="Построить" name="chk0"/> +	<check_box label="Просмотреть" name="chk1"/> +	<check_box label="Встретить" name="chk2"/> +	<check_box label="Получить работу" name="chk6"/> +	<check_box label="Группа" name="chk3"/> +	<check_box label="Купить" name="chk4"/> +	<check_box label="Продать" name="chk5"/> +	<check_box label="Нанять" name="chk7"/> +	<line_editor name="want_to_edit"> +		(загрузка…) +	</line_editor> +	<text name="Skills:"> +		Навыки: +	</text> +	<check_box label="Текстуры" name="schk0"/> +	<check_box label="Архитектура" name="schk1"/> +	<check_box label="Моделирование" name="schk3"/> +	<check_box label="Планирование мероприятия" name="schk2"/> +	<check_box label="Создавать сценарии" name="schk4"/> +	<check_box label="Пользовательские символы" name="schk5"/> +	<line_editor name="skills_edit"> +		(загрузка…) +	</line_editor> +	<text name="Languages:"> +		Языки: +	</text> +	<line_editor name="languages_edit"> +		(загрузка…) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_notes.xml b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml new file mode 100644 index 0000000000..41117c743a --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Примечания и конфиденциальность" name="panel_notes"> +	<text name="status_message" value="Личные заметки об этом аватаре:"/> +	<text name="status_message2" value="Разрешить этому аватару:"/> +	<check_box label="Смотреть, когда я в сети" name="status_check"/> +	<check_box label="Найти меня на карте мира" name="map_check"/> +	<check_box label="Редактировать, удалять или брать мои объекты" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_pick.xml b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml new file mode 100644 index 0000000000..a2ff5710ea --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(будет обновлено после сохранения) +	</panel.string> +	<line_editor name="pick_location"> +		Загрузка... +	</line_editor> +	<button label="Телепорт" name="teleport_btn"/> +	<button label="Показать на карте" name="show_on_map_btn"/> +	<button label="Указать местоположение" name="set_to_curr_location_btn" tool_tip="Установить в текущее местоположение"/> +	<button label="Сохранить подборку" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_picks.xml b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml new file mode 100644 index 0000000000..227b3f82b8 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Подборка" name="panel_picks"> +	<string name="no_picks" value="Нет подборки"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Сообщить всем о ваших избранных службах в Second Life. +	</text> +	<button label="Новый..." name="new_btn"/> +	<button label="Удалить..." name="delete_btn"/> +	<text name="picks_panel_text"> +		Загрузка... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml new file mode 100644 index 0000000000..e7a66ba29e --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Профиль" name="panel_profile"> +	<string name="status_online"> +		В настоящее время в режиме онлайн +	</string> +	<string name="status_offline"> +		В настоящее время в режиме оффлайн +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Никто"/> +	<string name="no_group_text" value="Никто"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Разработчик"/> +	<string name="FSSupp" value="Поддержка"/> +	<string name="FSQualityAssurance" value="Отладчик"/> +	<string name="FSGW" value="Межсетевой интерфейс"/> +	<text name="name_label" value="Имя:"/> +	<button label="Имя:" name="set_name" tool_tip="Задать отображаемое имя"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(загрузка…)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Статус неизвестен"/> +			<text name="label" value="Дата рождения в Second Life:"/> +			<text name="label2" value="Аккаунт:"/> +			<text name="partner_label" value="Партнер:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Группы:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="Пригласить в группу"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="О нас:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Передать вещь:"/> +			<text name="Give inventory" tool_tip="Сбросить вещи из инвентаря здесь для передачи их этому игроку."> +				Сбросить вещь из инвентаря здесь. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Найти на карте" label_selected="Найти на карте" name="show_on_map_btn" tool_tip="Найти жителя на карте"/> +			<button label="Оплатить" label_selected="Оплатить" name="pay" tool_tip="Выплатить деньги резиденту"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Предложить телепорт" label_selected="Предложить телепорт" name="teleport" tool_tip="Предложить телепорт этому жителю"/> +			<button label="Мгновенное сообщение" label_selected="Мгновенное сообщение" name="im" tool_tip="Начать сеанс IM"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Добавить друга" label_selected="Добавить друга" name="add_friend" tool_tip="Предложить дружбу этому жителю"/> +			<button label="Заблокировать" name="block" tool_tip="Заблокировать этого жителя"/> +			<button label="Разблокировать" name="unblock" tool_tip="Разблокировать этого жителя"/> +		</layout_panel> +	</layout_stack> +	<check_box label="Показать в поиске" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_web.xml b/indra/newview/skins/default/xui/ru/panel_profile_web.xml new file mode 100644 index 0000000000..18a17e2586 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Веб" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Время загрузки: [TIME] секунд"/> +	<line_editor name="url_edit"> +		(загрузка…) +	</line_editor> +	<flyout_button label="Загрузить" name="load" tool_tip="Загрузить эту страницу с профилем с помощью встроенного веб-браузера."> +		<flyout_button.item label="Открыть в просмотрщике браузера" name="open_item"/> +		<flyout_button.item label="Открыть во внешнем браузере" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Всплывающий веб-профиль"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml index af25565226..76b4f513a8 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml @@ -10,8 +10,8 @@  	<spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/>  	<spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Текстуры ландшафта (требования: 512x512, 24-битные, TGA) -	</text> +    Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA) +  </text>  	<text name="height_text_lbl">  		1 (Низ)  	</text> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 95b1664279..61d836a2d1 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -357,6 +357,24 @@ support@secondlife.com.  	<string name="TestingDisconnect">  		Тестирование отключения клиента  	</string> +	<string name="SocialFacebookConnecting"> +		Подключение к Facebook... +	</string> +	<string name="SocialFacebookPosting"> +		Публикация... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Отключение от Facebook... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Проблема с подключением к Facebook +	</string> +	<string name="SocialFacebookErrorPosting"> +		Проблемы при публикации в Facebook +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Проблема с отключением от Facebook +	</string>  	<string name="SocialFlickrConnecting">  		Подключение к Flickr...  	</string> @@ -671,9 +689,6 @@ support@secondlife.com.  	<string name="GroupNameNone">  		(нет)  	</string> -	<string name="AvalineCaller"> -		[ORDER] абонента Avaline -	</string>  	<string name="AssetErrorNone">  		Ошибок нет  	</string> @@ -2576,9 +2591,21 @@ support@secondlife.com.  	<string name="NoPicksClassifiedsText">  		Вы не создали подборки или рекламы. Нажмите кнопку со знаком «плюс» ниже, чтобы создать подборку или рекламу  	</string> +	<string name="NoPicksText"> +		Вы не сделали никакой подборки. Нажмите кнопку Создать, чтобы сделать подборку. +	</string> +	<string name="NoClassifiedsText"> +		Вы не сделали никакой рекламы. Нажмите кнопку Создать, чтобы сделать рекламу. +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		У жителя нет подборки или рекламы  	</string> +	<string name="NoAvatarPicksText"> +		У пользователя нет подборки +	</string> +	<string name="NoAvatarClassifiedsText"> +		У пользователя нет объявлений +	</string>  	<string name="PicksClassifiedsLoadingText">  		Загрузка...  	</string> @@ -4553,6 +4580,9 @@ support@secondlife.com.  	<string name="share_alert">  		Перетаскивайте вещи из инвентаря сюда  	</string> +	<string name="facebook_post_success"> +		Вы опубликовали сообщение в Facebook. +	</string>  	<string name="flickr_post_success">  		Вы опубликовали сообщение в Flickr.  	</string> diff --git a/indra/newview/skins/default/xui/tr/floater_facebook.xml b/indra/newview/skins/default/xui/tr/floater_facebook.xml index 656a4a81c9..d8cbd84ed1 100644 --- a/indra/newview/skins/default/xui/tr/floater_facebook.xml +++ b/indra/newview/skins/default/xui/tr/floater_facebook.xml @@ -3,7 +3,7 @@  	<tab_container name="tabs">  		<panel label="DURUM" name="panel_facebook_status"/>  		<panel label="FOTOĞRAF" name="panel_facebook_photo"/> -		<panel label="KONUMA GİRİŞ YAPIN" name="panel_facebook_place"/> +		<panel label="GİRİŞ YAP" name="panel_facebook_place"/>  		<panel label="ARKADAŞLAR" name="panel_facebook_friends"/>  	</tab_container>  	<text name="connection_error_text"> diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml index accb1ed71c..caa8497d3a 100644 --- a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml @@ -6,7 +6,7 @@  	<check_box label="Mimikler" name="check_gesture"/>  	<check_box label="Yer İmleri" name="check_landmark"/>  	<check_box label="Not Kartları" name="check_notecard"/> -	<check_box label="Örgüler" name="check_mesh"/> +	<check_box label="Ağlar" name="check_mesh"/>  	<check_box label="Nesneler" name="check_object"/>  	<check_box label="Komut Dosyaları" name="check_script"/>  	<check_box label="Sesler" name="check_sound"/> diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml deleted file mode 100644 index 5aee6ae091..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_picks.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="Seçimler"/> diff --git a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml index 8302c62070..8ba9123545 100644 --- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		Envantere Kopyala  	</floater.string> -	<text name="desc txt"> -		Açıklama: -	</text> -	<text name="dimensions"> -		[WIDTH] pks x [HEIGHT] pks -	</text> -	<text name="aspect_ratio"> -		En boy oranını önizle -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle"> -		<combo_item name="Unconstrained"> -			Kısıtsız -		</combo_item> -		<combo_item name="1:1" tool_tip="Grup işaretleri veya Real World profili"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="[SECOND_LIFE] profili"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="İlanlar ve arama listeleri, yer imleri"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="Arazi hakkında"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="Profil seçmeleri"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="Tamam" name="Keep"/> -	<button label="At" name="Discard"/> -	<button label="Farklı Kaydet" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				Açıklama: +			</text> +			<text name="dimensions"> +				[WIDTH]pks x [HEIGHT]pks +			</text> +			<text name="aspect_ratio"> +				En boy oranını önizle +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="Tamam" name="Keep"/> +			<button label="At" name="Discard"/> +			<button label="Farklı Kaydet" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_profile.xml b/indra/newview/skins/default/xui/tr/floater_profile.xml new file mode 100644 index 0000000000..bb158ddf66 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="Profil"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="Second Life" name="panel_profile_secondlife"/> +			<panel label="Web" name="panel_profile_web"/> +			<panel label="İlgi alanları" name="panel_profile_interests"/> +			<panel label="Favoriler" name="panel_profile_picks"/> +			<panel label="İlan" name="panel_profile_classifieds"/> +			<panel label="Gerçek Hayat" name="panel_profile_firstlife"/> +			<panel label="Notlar" name="panel_profile_notes"/> +		</tab_container> +		<button label="Tamam" name="ok_btn" tool_tip="Değişiklikleri profile kaydet ve kapat"/> +		<button label="İptal Et" label_selected="İptal Et" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml index be6c58e8cf..8496194700 100644 --- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		E-posta Gönderiliyor  	</string> +	<string name="facebook_progress_str"> +		Facebook'ta yayınlanıyor +	</string>  	<string name="profile_progress_str">  		Yayınlanıyor  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		Bilgisayara Kaydediliyor  	</string> +	<string name="facebook_succeeded_str"> +		Görüntü yüklendi +	</string>  	<string name="profile_succeeded_str">  		Görüntü yüklendi  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		Bilgisayara Kaydedildi!  	</string> +	<string name="facebook_failed_str"> +		Görüntü Facebook zaman tünelinize yüklenemedi. +	</string>  	<string name="profile_failed_str">  		Görüntü Profil Akışınıza yüklenemedi.  	</string> diff --git a/indra/newview/skins/default/xui/tr/menu_name_field.xml b/indra/newview/skins/default/xui/tr/menu_name_field.xml new file mode 100644 index 0000000000..b1afd737c3 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="Görünen Adı Kopyala" name="copy_display"/> +	<menu_item_call label="Aracı Adını Kopyala" name="copy_name"/> +	<menu_item_call label="Aracı Kimliğini Kopyala" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index 5403a78f22..17d2969d19 100644 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -2682,6 +2682,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin.  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml index fc444f21f6..78c34a3ac0 100644 --- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="İptal Et" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml index 8184d6d7cf..edbe87d74c 100644 --- a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml +++ b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml @@ -1,12 +1,12 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_friends"> -	<string name="facebook_friends_empty" value="Şu an için aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızı bugün Second Life'a katılmaya davet edin!"/> +	<string name="facebook_friends_empty" value="Şu anda aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızdan bugün Second Life'a katılmalarını isteyin!"/>  	<string name="facebook_friends_no_connected" value="Şu anda Facebook'a bağlı değilsiniz. Bağlanmak ve bu özelliği etkinleştirmek için lütfen Durum sekmesine gidin."/>  	<accordion name="friends_accordion">  		<accordion_tab name="tab_second_life_friends" title="SL arkadaşları"/>  		<accordion_tab name="tab_suggested_friends" title="Bu kişileri SL arkadaşları olarak ekle"/>  	</accordion>  	<text name="facebook_friends_status"> -		Facebook'a bağlanılmadı. +		Facebook'a bağlanılamadı.  	</text>  </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml index d772aff937..e3150f258d 100644 --- a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_photo">  	<combo_box name="resolution_combobox" tool_tip="Görüntü çözünürlüğü"> -		<combo_box.item label="Mevcut Pencere" name="CurrentWindow"/> +		<combo_box.item label="Geçerli Pencere" name="CurrentWindow"/>  		<combo_box.item label="640x480" name="640x480"/>  		<combo_box.item label="800x600" name="800x600"/>  		<combo_box.item label="1024x768" name="1024x768"/> @@ -11,10 +11,10 @@  		<combo_box.item label="Filtre Yok" name="NoFilter"/>  	</combo_box>  	<button label="Yenile" name="new_snapshot_btn" tool_tip="Yenilemek için tıklayın"/> -	<button label="Önizleme" name="big_preview_btn" tool_tip="Önizleme ayarları arasında geçiş yapmak için tıklayın"/> +	<button label="Önizleme" name="big_preview_btn" tool_tip="Önizlemeye geçmek için tıklayın"/>  	<text name="caption_label">  		Yorum (isteğe bağlı):  	</text>  	<button label="Yayınla" name="post_photo_btn"/> -	<button label="İptal" name="cancel_photo_btn"/> +	<button label="İptal Et" name="cancel_photo_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml index 85b401a1a0..96c34d03d0 100644 --- a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml +++ b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml @@ -5,5 +5,5 @@  	</text>  	<check_box initial_value="false" label="Konumun üstten görünümünü ekle" name="add_place_view_cb"/>  	<button label="Yayınla" name="post_place_btn"/> -	<button label="İptal" name="cancel_place_btn"/> +	<button label="İptal Et" name="cancel_place_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml index e6feff5949..f5dba088de 100644 --- a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml +++ b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml @@ -1,9 +1,9 @@  <?xml version="1.0" encoding="utf-8"?>  <panel name="panel_facebook_status">  	<string name="facebook_connected" value="Facebook'a şu kimlikle bağlandınız:"/> -	<string name="facebook_disconnected" value="Facebook'a bağlanılmadı"/> +	<string name="facebook_disconnected" value="Facebook'a bağlanılamadı"/>  	<text name="account_caption_label"> -		Facebook'a bağlanılmadı. +		Facebook'a bağlanılamadı.  	</text>  	<panel name="panel_buttons">  		<button label="Bağlan..." name="connect_btn"/> @@ -13,8 +13,8 @@  		</text>  	</panel>  	<text name="status_caption_label"> -		Ne düşünüyorsunuz? +		Aklınızdan ne geçiyor?  	</text>  	<button label="Yayınla" name="post_status_btn"/> -	<button label="İptal" name="cancel_status_btn"/> +	<button label="İptal Et" name="cancel_status_btn"/>  </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_group_general.xml b/indra/newview/skins/default/xui/tr/panel_group_general.xml index c666778c69..5578b36f3f 100644 --- a/indra/newview/skins/default/xui/tr/panel_group_general.xml +++ b/indra/newview/skins/default/xui/tr/panel_group_general.xml @@ -45,7 +45,7 @@ Daha fazla yardım edinmek için farenizi seçeneklerin üzerine getirin.  		<check_box label="Herkes katılabilir" name="open_enrollement" tool_tip="Bu grubun davet edilmeden yeni üyelerin katılmasına imkan tanıyıp tanımayacağını belirler."/>  		<check_box label="Katılma ücreti" name="check_enrollment_fee" tool_tip="Bu gruba katılmak için bir kayıt ücretinin gerekip gerekmeyeceğini belirler"/>  		<spinner label="L$" name="spin_enrollment_fee" tool_tip="Kayıt Ücreti işaretlendiğinde yeni üyeler gruba katılmak için bu ücreti ödemelidir."/> -		<combo_box name="group_mature_check" tool_tip="Erişkinlik dereceleri bir grupta izin verilen içerik ve davranış türlerini belirler"> +		<combo_box name="group_mature_check" tool_tip="Grubunuzun Orta olarak sınıflandırılmış bilgiler içerip içermeyeceğini belirler">  			<combo_item name="select_mature">  				- Erişkinlik seviyesini seçin -  			</combo_item> diff --git a/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml new file mode 100644 index 0000000000..0ed905ed35 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="Bilinmiyor"/> +	<button name="info_btn" tool_tip="Ek bilgi"/> +	<button name="profile_btn" tool_tip="Profili görüntüle"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml deleted file mode 100644 index d9e79d171c..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profilim" name="panel_me"> -	<panel label="SEÇTİKLERİM" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml index 25d29fcbb5..acbcd2a544 100644 --- a/indra/newview/skins/default/xui/tr/panel_people.xml +++ b/indra/newview/skins/default/xui/tr/panel_people.xml @@ -40,6 +40,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="Çevrimiçi"/>  				<accordion_tab name="tab_all" title="Tümü"/> +				<accordion_tab name="tab_suggested_friends" title="Arkadaş olmak isteyebileceğiniz kişiler"/>  			</accordion>  		</panel>  		<panel label="GRUPLAR" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classified.xml b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml new file mode 100644 index 0000000000..805de24c11 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		Orta +	</panel.string> +	<panel.string name="type_pg"> +		Genel İçerik +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] ışınlanma, [MAP] harita, [PROFILE] profil +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		Etkin +	</panel.string> +	<panel.string name="auto_renew_off"> +		Devre dışı +	</panel.string> +	<panel.string name="location_notice"> +		(kaydedildikten sonra güncellenir) +	</panel.string> +	<string name="publish_label"> +		Yayınla +	</string> +	<string name="save_label"> +		Kaydet +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="Bir görüntü seçmek için tıklayın"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="Konum:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="İçerik Türü:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="Kategori:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="Oluşturma tarihi:"/> +					<text_editor name="creation_date" tool_tip="Oluşturma tarihi" value="[date]"/> +					<text name="price_for_listing_label" value="İlan fiyatı:"/> +					<text_editor name="price_for_listing" tool_tip="İlan fiyatı."> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="Tıklama sayısı:"/> +					<text_editor name="click_through_text" tool_tip="Tıklama verileri" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="Otomatik yenileme:"/> +					<text name="auto_renew" value="Etkin"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="Açıklama:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					Başlık: +				</text> +				<text name="description_label"> +					Açıklama: +				</text> +				<text name="location_label"> +					Konum: +				</text> +				<text name="classified_location_edit"> +					yükleniyor... +				</text> +				<button label="Geçerli Konuma Ayarla" name="set_to_curr_location_btn"/> +				<text name="category_label" value="Kategori:"/> +				<text name="content_type_label" value="İçerik türü:"/> +				<icons_combo_box label="Genel İçerik" name="content_type_edit"> +					<icons_combo_box.item label="Orta İçerik" name="mature_ci" value="Yetişkin"/> +					<icons_combo_box.item label="Genel İçerik" name="pg_ci" value="PG"/> +				</icons_combo_box> +				<check_box label="Her hafta otomatik yenile" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="İlan fiyatı:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="İlan fiyatı." value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="Işınlanma" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="Harita" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="Düzenle" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="İptal Et" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml new file mode 100644 index 0000000000..0edae1ab2a --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="İlan" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="İlan Yok"/> +	<button label="Yeni..." name="new_btn"/> +	<button label="Sil..." name="delete_btn"/> +	<text name="classifieds_panel_text"> +		Yükleniyor... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml new file mode 100644 index 0000000000..0f65090209 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profil" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_interests.xml b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml new file mode 100644 index 0000000000..b068aa3dad --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="İlgi alanları" name="panel_profile_interests"> +	<text name="I Want To:"> +		Şunu Yapmak İstiyorum: +	</text> +	<check_box label="İnşa Et" name="chk0"/> +	<check_box label="Keşfet" name="chk1"/> +	<check_box label="Tanış" name="chk2"/> +	<check_box label="İşe Gir" name="chk6"/> +	<check_box label="Gruplandır" name="chk3"/> +	<check_box label="Satın Al" name="chk4"/> +	<check_box label="Sat" name="chk5"/> +	<check_box label="İşe Al" name="chk7"/> +	<line_editor name="want_to_edit"> +		(yükleniyor...) +	</line_editor> +	<text name="Skills:"> +		Beceriler: +	</text> +	<check_box label="Dokular" name="schk0"/> +	<check_box label="Mimari" name="schk1"/> +	<check_box label="Modelleme" name="schk3"/> +	<check_box label="Etkinlik Planlama" name="schk2"/> +	<check_box label="Kodlama" name="schk4"/> +	<check_box label="Özel Karakterler" name="schk5"/> +	<line_editor name="skills_edit"> +		(yükleniyor...) +	</line_editor> +	<text name="Languages:"> +		Diller: +	</text> +	<line_editor name="languages_edit"> +		(yükleniyor...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_notes.xml b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml new file mode 100644 index 0000000000..fff75dd685 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Notlar ve Gizlilik" name="panel_notes"> +	<text name="status_message" value="Bu avatar ile ilgili özel notlar:"/> +	<text name="status_message2" value="Bu avatar için şunlara izin ver:"/> +	<check_box label="Çevrimiçi olduğumu görme" name="status_check"/> +	<check_box label="Beni dünya haritasında bulma" name="map_check"/> +	<check_box label="Nesnelerimi düzenleme, silme veya alma" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_pick.xml b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml new file mode 100644 index 0000000000..d42c1eff7f --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(kaydedildikten sonra güncellenir) +	</panel.string> +	<line_editor name="pick_location"> +		Yükleniyor... +	</line_editor> +	<button label="Işınlanma" name="teleport_btn"/> +	<button label="Haritada Göster" name="show_on_map_btn"/> +	<button label="Konumu Ayarla" name="set_to_curr_location_btn" tool_tip="Geçerli Konuma Ayarla"/> +	<button label="Favoriyi Kaydet" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml new file mode 100644 index 0000000000..7222a2fc2e --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Favoriler" name="panel_picks"> +	<string name="no_picks" value="Favori Yok"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		Second Life'ta favori yerlerinizi herkese anlatın! +	</text> +	<button label="Yeni..." name="new_btn"/> +	<button label="Sil..." name="delete_btn"/> +	<text name="picks_panel_text"> +		Yükleniyor... +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml new file mode 100644 index 0000000000..00e81d005e --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profil" name="panel_profile"> +	<string name="status_online"> +		Şu Anda Çevrimiçi +	</string> +	<string name="status_offline"> +		Şu Anda Çevrimdışı +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="Yok"/> +	<string name="no_group_text" value="Yok"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="Geliştirici"/> +	<string name="FSSupp" value="Destek"/> +	<string name="FSQualityAssurance" value="Böcek bilimci"/> +	<string name="FSGW" value="Ağ geçidi"/> +	<text name="name_label" value="Ad:"/> +	<button label="Ad:" name="set_name" tool_tip="Görünen Adı Ayarla"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(yükleniyor...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="Durum Bilinmiyor"/> +			<text name="label" value="Second Life Doğum Tarihi:"/> +			<text name="label2" value="Hesap:"/> +			<text name="partner_label" value="Ortak:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="Gruplar:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="Gruba Davet Et"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="Hakkında:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="Öğe ver:"/> +			<text name="Give inventory" tool_tip="Envanter öğelerini bu kişiye vermek için buraya bırakın."> +				Envanter öğesini buraya bırakın. +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="Haritada Bul" label_selected="Haritada Bul" name="show_on_map_btn" tool_tip="Sakini haritada bul"/> +			<button label="Öde" label_selected="Öde" name="pay" tool_tip="Sakine para öde"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="Işınlanma Teklif Et" label_selected="Işınlanma Teklif Et" name="teleport" tool_tip="Sakine ışınlanma teklif et"/> +			<button label="Anlık İleti" label_selected="Anlık İleti" name="im" tool_tip="Anlık ileti oturumu aç"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="Arkadaş Ekle" label_selected="Arkadaş Ekle" name="add_friend" tool_tip="Sakine arkadaşlık teklif et"/> +			<button label="Engelle" name="block" tool_tip="Bu Sakini engelle"/> +			<button label="Engellemeyi Kaldır" name="unblock" tool_tip="Bu Sakinin engellemesini kaldır"/> +		</layout_panel> +	</layout_stack> +	<check_box label="Aramada göster" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_web.xml b/indra/newview/skins/default/xui/tr/panel_profile_web.xml new file mode 100644 index 0000000000..265b1fee7e --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Web" name="panel_profile_web"> +	<panel.string name="LoadTime" value="Yükleme Süresi: [TIME] saniye"/> +	<line_editor name="url_edit"> +		(yükleniyor..) +	</line_editor> +	<flyout_button label="Yükle" name="load" tool_tip="Bu profil sayfasını tümleşik web tarayıcı ile yükleyin."> +		<flyout_button.item label="Görüntüleyici içindeki tarayıcıda aç" name="open_item"/> +		<flyout_button.item label="Dış tarayıcıda aç" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="Açılır web profili"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml index 3226ee008e..e25047301d 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml @@ -10,8 +10,8 @@  	<spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/>  	<spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir) -	</text> +    Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir) +  </text>  	<text name="height_text_lbl">  		1 (Düşük)  	</text> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index 74a6b3cac3..e709a4c5d6 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -357,6 +357,24 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.  	<string name="TestingDisconnect">  		Görüntüleyici bağlantısının kesilmesi test ediliyor  	</string> +	<string name="SocialFacebookConnecting"> +		Facebook ile bağlantı kuruluyor... +	</string> +	<string name="SocialFacebookPosting"> +		Yayınlanıyor... +	</string> +	<string name="SocialFacebookDisconnecting"> +		Facebook bağlantısı kesiliyor... +	</string> +	<string name="SocialFacebookErrorConnecting"> +		Facebook ile bağlantı kurulurken sorun oluştu +	</string> +	<string name="SocialFacebookErrorPosting"> +		Facebook'ta yayınlarken sorun oluştu +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		Facebook bağlantısı kesilirken sorun oluştu +	</string>  	<string name="SocialFlickrConnecting">  		Flickr bağlantısı kuruluyor...  	</string> @@ -671,9 +689,6 @@ kartlarına eklenebilir.  	<string name="GroupNameNone">  		(hiçbiri)  	</string> -	<string name="AvalineCaller"> -		Avaline Arayanı [ORDER] -	</string>  	<string name="AssetErrorNone">  		Hata yok  	</string> @@ -2576,9 +2591,21 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin  	<string name="NoPicksClassifiedsText">  		Herhangi bir Seçme veya İlan oluşturmadınız. Bir Seçme veya İlan oluşturmak için aşağıdaki Artı düğmesine tıklayın.  	</string> +	<string name="NoPicksText"> +		Herhangi bir Favori oluşturmadınız. Bir Favori oluşturmak için Yeni düğmesine tıklayın. +	</string> +	<string name="NoClassifiedsText"> +		Herhangi bir İlan oluşturmadınız. Bir İlan oluşturmak için Yeni düğmesine tıklayın. +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		Kullanıcının herhangi bir seçmesi veya ilanı yok  	</string> +	<string name="NoAvatarPicksText"> +		Kullanıcının favorisi yok +	</string> +	<string name="NoAvatarClassifiedsText"> +		Kullanıcının ilanı yok +	</string>  	<string name="PicksClassifiedsLoadingText">  		Yükleniyor...  	</string> @@ -4556,6 +4583,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.  	<string name="share_alert">  		Envanterinizden buraya öğeler sürükleyin  	</string> +	<string name="facebook_post_success"> +		Facebook'ta yayınladınız. +	</string>  	<string name="flickr_post_success">  		Flickr'da yayınladınız.  	</string> diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml deleted file mode 100644 index a8bfcd99e3..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_picks.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_picks" title="精選地點"/> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml index 2b6eac48b3..9213cc212d 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml @@ -6,42 +6,23 @@  	<floater.string name="Copy">  		覆製到收納區  	</floater.string> -	<text name="desc txt"> -		描述: -	</text> -	<text name="dimensions"> -		[WIDTH]像素 x [HEIGHT]像素 -	</text> -	<text name="aspect_ratio"> -		預覽長寬比 -	</text> -	<combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"> -		<combo_item name="Unconstrained"> -			不受限 -		</combo_item> -		<combo_item name="1:1" tool_tip="群組徽章或現實世界小檔案"> -			1:1 -		</combo_item> -		<combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案"> -			4:3 -		</combo_item> -		<combo_item name="10:7" tool_tip="個人廣告和搜索刊登廣告、地標"> -			10:7 -		</combo_item> -		<combo_item name="3:2" tool_tip="土地資料"> -			3:2 -		</combo_item> -		<combo_item name="16:10"> -			16:10 -		</combo_item> -		<combo_item name="16:9" tool_tip="個人檔案精選"> -			16:9 -		</combo_item> -		<combo_item name="2:1"> -			2:1 -		</combo_item> -	</combo_box> -	<button label="確定" name="Keep"/> -	<button label="丟棄" name="Discard"/> -	<button label="另存為" name="save_tex_btn"/> +	<layout_stack name="preview_stack"> +		<layout_panel name="texture_panel"> +			<text name="desc txt"> +				描述: +			</text> +			<text name="dimensions"> +				[WIDTH]像素 x [HEIGHT]像素 +			</text> +			<text name="aspect_ratio"> +				預覽長寬比 +			</text> +			<combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"/> +		</layout_panel> +		<layout_panel name="buttons_panel"> +			<button label="確定" name="Keep"/> +			<button label="丟棄" name="Discard"/> +			<button label="另存為" name="save_tex_btn"/> +		</layout_panel> +	</layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_profile.xml b/indra/newview/skins/default/xui/zh/floater_profile.xml new file mode 100644 index 0000000000..0f73f527a9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_profile.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarinfo" title="簡覽"> +	<panel name="panel_profile_view"> +		<tab_container name="panel_profile_tabs"> +			<panel label="第二人生" name="panel_profile_secondlife"/> +			<panel label="網頁" name="panel_profile_web"/> +			<panel label="興趣" name="panel_profile_interests"/> +			<panel label="精選地點" name="panel_profile_picks"/> +			<panel label="分類廣告" name="panel_profile_classifieds"/> +			<panel label="真實世界" name="panel_profile_firstlife"/> +			<panel label="筆記" name="panel_profile_notes"/> +		</tab_container> +		<button label="確定" name="ok_btn" tool_tip="儲存變更到個人檔案後關閉"/> +		<button label="取消" label_selected="取消" name="cancel_btn"/> +	</panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml index 4090248083..6e1a156762 100644 --- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml @@ -6,6 +6,9 @@  	<string name="postcard_progress_str">  		正在發送電郵  	</string> +	<string name="facebook_progress_str"> +		發佈到臉書 +	</string>  	<string name="profile_progress_str">  		發佈  	</string> @@ -15,6 +18,9 @@  	<string name="local_progress_str">  		正在存到電腦  	</string> +	<string name="facebook_succeeded_str"> +		圖像已上傳 +	</string>  	<string name="profile_succeeded_str">  		圖像已上傳  	</string> @@ -27,6 +33,9 @@  	<string name="local_succeeded_str">  		成功存入電腦!  	</string> +	<string name="facebook_failed_str"> +		上傳圖像到你的臉書時間線時失敗。 +	</string>  	<string name="profile_failed_str">  		上傳圖像到你的檔案訊息發佈時出錯。  	</string> diff --git a/indra/newview/skins/default/xui/zh/menu_name_field.xml b/indra/newview/skins/default/xui/zh/menu_name_field.xml new file mode 100644 index 0000000000..5eaf3461cd --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_name_field.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="CopyMenu"> +	<menu_item_call label="複製顯示名稱" name="copy_display"/> +	<menu_item_call label="複製代理名稱" name="copy_name"/> +	<menu_item_call label="複製代理ID" name="copy_id"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index cfde824349..4d0f1cb85b 100644 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -2666,6 +2666,9 @@ SHA1 指紋:[MD5_DIGEST]  	<notification name="SystemMessage">  		[MESSAGE]  	</notification> +	<notification name="FacebookConnect"> +		[MESSAGE] +	</notification>  	<notification name="FlickrConnect">  		[MESSAGE]  	</notification> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml index b06ece02ad..4d3248db46 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml @@ -46,7 +46,7 @@  			<layout_panel name="save_changes_btn_lp">  				<button label="[LABEL]" name="save_changes_btn"/>  			</layout_panel> -			<layout_panel name="show_on_map_btn_lp"> +			<layout_panel name="cancel_btn_lp">  				<button label="取消" name="cancel_btn"/>  			</layout_panel>  		</layout_stack> diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml new file mode 100644 index 0000000000..fec4bb572a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> +	<text name="group_name" value="未知"/> +	<button name="info_btn" tool_tip="詳情"/> +	<button name="profile_btn" tool_tip="察看檔案"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml deleted file mode 100644 index aad1348e46..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_me.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="我的個人檔案" name="panel_me"> -	<panel label="我的精選地點" name="panel_picks"/> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml index b0e60218cf..b95dd96026 100644 --- a/indra/newview/skins/default/xui/zh/panel_people.xml +++ b/indra/newview/skins/default/xui/zh/panel_people.xml @@ -40,6 +40,7 @@  			<accordion name="friends_accordion">  				<accordion_tab name="tab_online" title="上線"/>  				<accordion_tab name="tab_all" title="全部"/> +				<accordion_tab name="tab_suggested_friends" title="你可能想要加為好友的人"/>  			</accordion>  		</panel>  		<panel label="群組" name="groups_panel"> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classified.xml b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml new file mode 100644 index 0000000000..4eee4e8855 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_profile_classified"> +	<panel.string name="type_mature"> +		適度成人 +	</panel.string> +	<panel.string name="type_pg"> +		一般普級內容 +	</panel.string> +	<panel.string name="l$_price"> +		L$[PRICE] +	</panel.string> +	<panel.string name="click_through_text_fmt"> +		[TELEPORT] 瞬間傳送,[MAP] 地圖,[PROFILE] 檔案 +	</panel.string> +	<panel.string name="date_fmt"> +		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] +	</panel.string> +	<panel.string name="auto_renew_on"> +		已啟用 +	</panel.string> +	<panel.string name="auto_renew_off"> +		已停用 +	</panel.string> +	<panel.string name="location_notice"> +		(儲存後將會更新) +	</panel.string> +	<string name="publish_label"> +		發布 +	</string> +	<string name="save_label"> +		儲存 +	</string> +	<scroll_container name="profile_scroll"> +		<panel name="info_scroll_content_panel"> +			<icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/> +			<layout_stack name="info_panel"> +				<layout_panel name="main_info_panel"> +					<text_editor name="classified_name"> +						[name] +					</text_editor> +					<text name="classified_location_label" value="位置:"/> +					<text_editor name="classified_location" value="[loading...]"/> +					<text name="content_type_label" value="內容類型:"/> +					<text_editor name="content_type" value="[content type]"/> +					<text name="category_label" value="分類:"/> +					<text_editor name="category" value="[category]"/> +					<text name="creation_date_label" value="建立日期:"/> +					<text_editor name="creation_date" tool_tip="建立日期" value="[date]"/> +					<text name="price_for_listing_label" value="刊登費:"/> +					<text_editor name="price_for_listing" tool_tip="刊登費。"> +						[PRICE] +					</text_editor> +				</layout_panel> +				<layout_panel name="clickthrough_layout_panel"> +					<text name="click_through_label" value="點按狀況:"/> +					<text_editor name="click_through_text" tool_tip="點按資料" value="[clicks]"/> +				</layout_panel> +				<layout_panel name="auto_renew_layout_panel"> +					<text name="auto_renew_label" value="自動續訂:"/> +					<text name="auto_renew" value="已啟用"/> +				</layout_panel> +				<layout_panel name="descr_layout_panel"> +					<text name="classified_desc_label" value="描述:"/> +					<text_editor name="classified_desc" value="[description]"/> +				</layout_panel> +			</layout_stack> +			<panel name="edit_panel"> +				<text name="Name:"> +					標題: +				</text> +				<text name="description_label"> +					描述: +				</text> +				<text name="location_label"> +					位置: +				</text> +				<text name="classified_location_edit"> +					載入中... +				</text> +				<button label="設定為目前位置" name="set_to_curr_location_btn"/> +				<text name="category_label" value="分類:"/> +				<text name="content_type_label" value="內容類型:"/> +				<icons_combo_box label="一般普級內容" name="content_type_edit"> +					<icons_combo_box.item label="適度成人內容" name="mature_ci" value="適度成人"/> +					<icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/> +				</icons_combo_box> +				<check_box label="每星期自動續訂" name="auto_renew_edit"/> +				<text name="price_for_listing_edit_label" value="刊登費:"/> +				<spinner label="L$" name="price_for_listing_edit" tool_tip="刊登費。" value="50"/> +			</panel> +		</panel> +	</scroll_container> +	<layout_stack name="edit_btns_pnl"> +		<layout_panel name="teleport_btn_lp"> +			<button label="瞬間傳送" name="teleport_btn"/> +		</layout_panel> +		<layout_panel name="map_btn_lp"> +			<button label="地圖" name="show_on_map_btn"/> +		</layout_panel> +		<layout_panel name="edit_btn_lp"> +			<button label="編輯" name="edit_btn"/> +		</layout_panel> +		<layout_panel name="save_btn_lp"> +			<button label="[LABEL]" name="save_changes_btn"/> +		</layout_panel> +		<layout_panel name="cancel_btn_lp"> +			<button label="取消" name="cancel_btn"/> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml new file mode 100644 index 0000000000..89b5cdf641 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="分類廣告" name="panel_profile_classifieds"> +	<string name="no_classifieds" value="禁止個人廣告"/> +	<button label="新增…" name="new_btn"/> +	<button label="刪除…" name="delete_btn"/> +	<text name="classifieds_panel_text"> +		載入中… +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml new file mode 100644 index 0000000000..9370661d7f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="簡覽" name="panel_profile_firstlife"/> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_interests.xml b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml new file mode 100644 index 0000000000..150f3cca4f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="興趣" name="panel_profile_interests"> +	<text name="I Want To:"> +		我想要: +	</text> +	<check_box label="建造" name="chk0"/> +	<check_box label="探索" name="chk1"/> +	<check_box label="見面" name="chk2"/> +	<check_box label="受雇" name="chk6"/> +	<check_box label="群組" name="chk3"/> +	<check_box label="購買" name="chk4"/> +	<check_box label="出售" name="chk5"/> +	<check_box label="招人" name="chk7"/> +	<line_editor name="want_to_edit"> +		(載入中...) +	</line_editor> +	<text name="Skills:"> +		技能: +	</text> +	<check_box label="材質" name="schk0"/> +	<check_box label="架構" name="schk1"/> +	<check_box label="建模" name="schk3"/> +	<check_box label="計畫活動" name="schk2"/> +	<check_box label="建腳本" name="schk4"/> +	<check_box label="定製角色" name="schk5"/> +	<line_editor name="skills_edit"> +		(載入中...) +	</line_editor> +	<text name="Languages:"> +		語言: +	</text> +	<line_editor name="languages_edit"> +		(載入中...) +	</line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_notes.xml b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml new file mode 100644 index 0000000000..17e1a997da --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="筆記和隱私" name="panel_notes"> +	<text name="status_message" value="關於這化身的私人筆記:"/> +	<text name="status_message2" value="允許這個化身:"/> +	<check_box label="看見我何時上線" name="status_check"/> +	<check_box label="在世界地圖上找到我" name="map_check"/> +	<check_box label="邊輯,刪除或取下我的物件" name="objects_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_pick.xml b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml new file mode 100644 index 0000000000..5f8d6a2ba5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> +	<panel.string name="location_notice"> +		(儲存後將會更新) +	</panel.string> +	<line_editor name="pick_location"> +		載入中… +	</line_editor> +	<button label="瞬間傳送" name="teleport_btn"/> +	<button label="顯示在地圖上" name="show_on_map_btn"/> +	<button label="設定位置" name="set_to_curr_location_btn" tool_tip="設定為目前位置"/> +	<button label="儲存精選地點" name="save_changes_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml new file mode 100644 index 0000000000..8f189d1308 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="精選地點" name="panel_picks"> +	<string name="no_picks" value="無精選地點"/> +	<text name="Tell everyone about your favorite places in Second Life."> +		告訴大家你在Second Life中最愛的去處。 +	</text> +	<button label="新增…" name="new_btn"/> +	<button label="刪除…" name="delete_btn"/> +	<text name="picks_panel_text"> +		載入中… +	</text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml new file mode 100644 index 0000000000..da4aafce55 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="簡覽" name="panel_profile"> +	<string name="status_online"> +		目前在線 +	</string> +	<string name="status_offline"> +		目前離線 +	</string> +	<string name="CaptionTextAcctInfo"> +		[ACCTTYPE] +[PAYMENTINFO] +	</string> +	<string name="payment_update_link_url"> +		http://www.secondlife.com/account/billing.php?lang=en +	</string> +	<string name="partner_edit_link_url"> +		http://www.secondlife.com/account/partners.php?lang=en +	</string> +	<string name="my_account_link_url" value="http://secondlife.com/account"/> +	<string name="no_partner_text" value="無"/> +	<string name="no_group_text" value="無"/> +	<string name="RegisterDateFormat"> +		[REG_DATE] +	</string> +	<string name="name_text_args"> +		[NAME] +	</string> +	<string name="display_name_text_args"> +		[DISPLAY_NAME] +	</string> +	<string name="FSDev" value="開發者"/> +	<string name="FSSupp" value="支援"/> +	<string name="FSQualityAssurance" value="除錯獵人"/> +	<string name="FSGW" value="網關"/> +	<text name="name_label" value="名稱:"/> +	<button label="名稱:" name="set_name" tool_tip="設定顯示名稱"/> +	<panel name="name_holder"> +		<text_editor name="complete_name" value="(載入中...)"/> +	</panel> +	<layout_stack name="imagepositioner"> +		<layout_panel name="label_stack"> +			<text name="status" value="狀態不明"/> +			<text name="label" value="Second Life生日:"/> +			<text name="label2" value="帳戶:"/> +			<text name="partner_label" value="伴侶:"/> +		</layout_panel> +	</layout_stack> +	<text name="Groups:" value="群組:"/> +	<button label="+" label_selected="+" name="group_invite" tool_tip="邀請加入群組"/> +	<layout_stack name="aboutpositioner"> +		<layout_panel name="about_stack"> +			<text name="About:" value="關於:"/> +		</layout_panel> +		<layout_panel name="give_stack"> +			<text name="Give item:" value="贈與物品:"/> +			<text name="Give inventory" tool_tip="把收納區物品放到這裡,送給此人。"> +				把收納區物品放到這裡。 +			</text> +		</layout_panel> +	</layout_stack> +	<layout_stack name="buttonstack"> +		<layout_panel name="left_buttonstack"> +			<button label="在地圖上查找" label_selected="在地圖上查找" name="show_on_map_btn" tool_tip="在地圖上找出這個居民"/> +			<button label="支付" label_selected="支付" name="pay" tool_tip="付款給這個居民"/> +		</layout_panel> +		<layout_panel name="middle_buttonstack"> +			<button label="發出瞬間傳送邀請" label_selected="發出瞬間傳送邀請" name="teleport" tool_tip="向這個居民發出瞬間傳送邀請"/> +			<button label="即時訊息" label_selected="即時訊息" name="im" tool_tip="開啟即時訊息會話"/> +		</layout_panel> +		<layout_panel name="right_buttonstack"> +			<button label="加為朋友" label_selected="加為朋友" name="add_friend" tool_tip="向這個居民發出交友邀請"/> +			<button label="封鎖" name="block" tool_tip="封鎖這位居民"/> +			<button label="解除封鎖" name="unblock" tool_tip="不再封鎖這位居民"/> +		</layout_panel> +	</layout_stack> +	<check_box label="在搜尋結果中顯示" name="show_in_search_checkbox"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_web.xml b/indra/newview/skins/default/xui/zh/panel_profile_web.xml new file mode 100644 index 0000000000..566651dceb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="網頁" name="panel_profile_web"> +	<panel.string name="LoadTime" value="載入時間:[TIME]秒"/> +	<line_editor name="url_edit"> +		(載入中…) +	</line_editor> +	<flyout_button label="載入" name="load" tool_tip="用內嵌瀏覽器載入此個人檔案頁面。"> +		<flyout_button.item label="開啓内部瀏覽器" name="open_item"/> +		<flyout_button.item label="開啓外部瀏覽器" name="home_item"/> +	</flyout_button> +	<button name="web_profile_popout_btn" tool_tip="彈出式個人檔案網頁"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml index 85e759e445..81bce46876 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml @@ -10,7 +10,7 @@  	<spinner label="地形提升限制" name="terrain_raise_spin"/>  	<spinner label="地形降低限制" name="terrain_lower_spin"/>  	<text name="detail_texture_text"> -		地形材質(須 512x512,24 位元 .tga 檔格式) +		地形材質(須 1024x1024,24 位元 .tga 檔格式)  	</text>  	<text name="height_text_lbl">  		1(低) diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index a8d5fd90bb..bdb16c9bf1 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -353,6 +353,24 @@ http://secondlife.com/viewer-access-faq  	<string name="TestingDisconnect">  		測試瀏覽器斷線  	</string> +	<string name="SocialFacebookConnecting"> +		連通臉書中… +	</string> +	<string name="SocialFacebookPosting"> +		發佈中… +	</string> +	<string name="SocialFacebookDisconnecting"> +		臉書連通中斷中… +	</string> +	<string name="SocialFacebookErrorConnecting"> +		連通臉書時出問題 +	</string> +	<string name="SocialFacebookErrorPosting"> +		發佈到臉書時出問題 +	</string> +	<string name="SocialFacebookErrorDisconnecting"> +		試圖中斷臉書連通時出問題 +	</string>  	<string name="SocialFlickrConnecting">  		連通 Flickr 中…  	</string> @@ -667,9 +685,6 @@ http://secondlife.com/viewer-access-faq  	<string name="GroupNameNone">  		(無)  	</string> -	<string name="AvalineCaller"> -		Avaline 通話者 [ORDER] -	</string>  	<string name="AssetErrorNone">  		無錯誤  	</string> @@ -2569,9 +2584,21 @@ http://secondlife.com/support 求助解決問題。  	<string name="NoPicksClassifiedsText">  		你尚未建立任何精選地點或個人廣告。 點按下面的 + 按鈕建立精選地點或個人廣告。  	</string> +	<string name="NoPicksText"> +		你尚未建立任何精選地點。 點按「新增」按鈕建立精選地點。 +	</string> +	<string name="NoClassifiedsText"> +		你尚未建立任何分類廣告。 點按「新增」按鈕建立分類廣告。 +	</string>  	<string name="NoAvatarPicksClassifiedsText">  		使用者無精選地點或個人廣告  	</string> +	<string name="NoAvatarPicksText"> +		使用者沒有精選地點 +	</string> +	<string name="NoAvatarClassifiedsText"> +		使用者沒有分類廣告 +	</string>  	<string name="PicksClassifiedsLoadingText">  		載入中...  	</string> @@ -4549,6 +4576,9 @@ http://secondlife.com/support 求助解決問題。  	<string name="share_alert">  		將收納區物品拖曳到這裡  	</string> +	<string name="facebook_post_success"> +		成功發佈到臉書。 +	</string>  	<string name="flickr_post_success">  		成功發佈到 Flickr。  	</string> diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 8a7e6407ed..5d50d1e182 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -257,21 +257,25 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)                  if (printable_params["wait_for_updater"].asBoolean())                  {                      std::string reason_response = responses["data"]["reason"].asString(); -                    if (reason_response == "update") // No point waiting if not an update +                    // Timeout should produce the isUndefined() object passed here. +                    if (reason_response == "update")                      { -                        // Timeout should produce the isUndefined() object passed here.                          LL_INFOS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;                          updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD()); - -                        if (updater.isUndefined()) -                        { -                            LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login" -                                << LL_ENDL; -                        } -                        else -                        { -                            LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL; -                        } +                    } +                    else +                    { +                        LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL; +                        updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 3, LLSD()); +                    } +                    if (updater.isUndefined()) +                    { +                        LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login" +                                            << LL_ENDL; +                    } +                    else +                    { +                        LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;                      }                  }  | 
