diff options
| author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2010-06-11 10:09:02 -0400 | 
|---|---|---|
| committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2010-06-11 10:09:02 -0400 | 
| commit | 8a5c71ea1d278beee89da04036e7923129581baf (patch) | |
| tree | bdb7fd11e134fb2e17a6f2353ff9315672581777 | |
| parent | 17520c17b1eff7b26d264c8b6bd1f8ebbbde8d15 (diff) | |
| parent | 0c8164b8947eee7b43ba0452821a3ff6d9f9dd38 (diff) | |
merge
194 files changed, 3560 insertions, 3948 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 5667b69c28..a74cf32afa 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -25,6 +25,7 @@ Aimee Trescothick  	VWR-3903  	VWR-4083  	VWR-4106 +	VWR-5308  	VWR-6348  	VWR-6358  	VWR-6360 @@ -252,6 +253,7 @@ Gigs Taggart  	VWR-2491  	VWR-2502  	VWR-2331 +	VWR-5308  	VWR-8781  	VWR-8783  Ginko Bayliss diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index b92ccd1d77..9f4c108dff 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -548,12 +548,11 @@ void LLAudioEngine::enableWind(bool enable)  {  	if (enable && (!mEnableWind))  	{ -		initWind(); -		mEnableWind = enable; +		mEnableWind = initWind();  	}  	else if (mEnableWind && (!enable))  	{ -		mEnableWind = enable; +		mEnableWind = false;  		cleanupWind();  	}  } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index d287104204..5876cef4ea 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -195,7 +195,7 @@ protected:  	virtual LLAudioBuffer *createBuffer() = 0;  	virtual LLAudioChannel *createChannel() = 0; -	virtual void initWind() = 0; +	virtual bool initWind() = 0;  	virtual void cleanupWind() = 0;  	virtual void setInternalGain(F32 gain) = 0; diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index d7f58defca..7a8a04afa1 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -54,13 +54,12 @@ extern "C" {  	void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);  } -FSOUND_DSPUNIT *gWindDSP = NULL; -  LLAudioEngine_FMOD::LLAudioEngine_FMOD()  {  	mInited = false;  	mWindGen = NULL; +	mWindDSP = NULL;  } @@ -258,10 +257,10 @@ void LLAudioEngine_FMOD::allocateListener(void)  void LLAudioEngine_FMOD::shutdown()  { -	if (gWindDSP) +	if (mWindDSP)  	{ -		FSOUND_DSP_SetActive(gWindDSP,false); -		FSOUND_DSP_Free(gWindDSP); +		FSOUND_DSP_SetActive(mWindDSP,false); +		FSOUND_DSP_Free(mWindDSP);  	}  	stopInternetStream(); @@ -289,29 +288,66 @@ LLAudioChannel * LLAudioEngine_FMOD::createChannel()  } -void LLAudioEngine_FMOD::initWind() +bool LLAudioEngine_FMOD::initWind()  { -	mWindGen = new LLWindGen<MIXBUFFERFORMAT>; +	if (!mWindGen) +	{ +		bool enable; +		 +		switch (FSOUND_GetMixer()) +		{ +			case FSOUND_MIXER_MMXP5: +			case FSOUND_MIXER_MMXP6: +			case FSOUND_MIXER_QUALITY_MMXP5: +			case FSOUND_MIXER_QUALITY_MMXP6: +				enable = (typeid(MIXBUFFERFORMAT) == typeid(S16)); +				break; +			case FSOUND_MIXER_BLENDMODE: +				enable = (typeid(MIXBUFFERFORMAT) == typeid(S32)); +				break; +			case FSOUND_MIXER_QUALITY_FPU: +				enable = (typeid(MIXBUFFERFORMAT) == typeid(F32)); +				break; +			default: +				// FSOUND_GetMixer() does not return a valid mixer type on Darwin +				LL_INFOS("AppInit") << "Unknown FMOD mixer type, assuming default" << LL_ENDL; +				enable = true; +				break; +		} +		 +		if (enable) +		{ +			mWindGen = new LLWindGen<MIXBUFFERFORMAT>(FSOUND_GetOutputRate()); +		} +		else +		{ +			LL_WARNS("AppInit") << "Incompatible FMOD mixer type, wind noise disabled" << LL_ENDL; +		} +	} + +	mNextWindUpdate = 0.0; -	if (!gWindDSP) +	if (mWindGen && !mWindDSP)  	{ -		gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen); +		mWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);  	} -	if (gWindDSP) +	if (mWindDSP)  	{ -		FSOUND_DSP_SetActive(gWindDSP, true); +		FSOUND_DSP_SetActive(mWindDSP, true); +		return true;  	} -	mNextWindUpdate = 0.0; +	 +	return false;  }  void LLAudioEngine_FMOD::cleanupWind()  { -	if (gWindDSP) +	if (mWindDSP)  	{ -		FSOUND_DSP_SetActive(gWindDSP, false); -		FSOUND_DSP_Free(gWindDSP); -		gWindDSP = NULL; +		FSOUND_DSP_SetActive(mWindDSP, false); +		FSOUND_DSP_Free(mWindDSP); +		mWindDSP = NULL;  	}  	delete mWindGen; @@ -740,30 +776,12 @@ void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int len  	// originalbuffer = fmod's original mixbuffer.  	// newbuffer = the buffer passed from the previous DSP unit.  	// length = length in samples at this mix time. -	// param = user parameter passed through in FSOUND_DSP_Create. -	// -	// modify the buffer in some fashion +	// userdata = user parameter passed through in FSOUND_DSP_Create.  	LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =  		(LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata; -	U8 stride; - -#if LL_DARWIN -	stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT); -#else -	int mixertype = FSOUND_GetMixer(); -	if (mixertype == FSOUND_MIXER_BLENDMODE || -	    mixertype == FSOUND_MIXER_QUALITY_FPU) -	{ -		stride = 4; -	} -	else -	{ -		stride = 2; -	} -#endif - -	newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride); +	 +	newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length);  	return newbuffer;  } diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmod.h index 3968657cba..0e386a3884 100644 --- a/indra/llaudio/llaudioengine_fmod.h +++ b/indra/llaudio/llaudioengine_fmod.h @@ -55,15 +55,15 @@ public:  	virtual void shutdown(); -	/*virtual*/ void initWind(); +	/*virtual*/ bool initWind();  	/*virtual*/ void cleanupWind();  	/*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);  #if LL_DARWIN -        typedef S32 MIXBUFFERFORMAT; +	typedef S32 MIXBUFFERFORMAT;  #else -        typedef S16 MIXBUFFERFORMAT; +	typedef S16 MIXBUFFERFORMAT;  #endif  protected: @@ -83,6 +83,7 @@ protected:  	void* mUserData;  	LLWindGen<MIXBUFFERFORMAT> *mWindGen; +	FSOUND_DSPUNIT *mWindDSP;  }; diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index a5982ccbd6..887c791790 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -370,7 +370,7 @@ U32 LLAudioBufferOpenAL::getLength()  // ------------ -void LLAudioEngine_OpenAL::initWind() +bool LLAudioEngine_OpenAL::initWind()  {  	ALenum error;  	llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; @@ -397,10 +397,12 @@ void LLAudioEngine_OpenAL::initWind()  	if(mWindBuf==NULL)  	{  		llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl; -		mEnableWind=false; +		return false;  	}  	llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; + +	return true;  }  void LLAudioEngine_OpenAL::cleanupWind() @@ -508,14 +510,14 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)  		alGenBuffers(1,&buffer);  		if((error=alGetError()) != AL_NO_ERROR)  		{ -			llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; +			llwarns << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << error << llendl;  			break;  		}  		alBufferData(buffer,  			     AL_FORMAT_STEREO16,  			     mWindGen->windGenerate(mWindBuf, -						    mWindBufSamples, 2), +						    mWindBufSamples),  			     mWindBufBytes,  			     mWindBufFreq);  		error = alGetError(); diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 5aca03e195..16125b2476 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -57,23 +57,23 @@ class LLAudioEngine_OpenAL : public LLAudioEngine  		LLAudioBuffer* createBuffer();  		LLAudioChannel* createChannel(); -		/*virtual*/ void initWind(); +		/*virtual*/ bool initWind();  		/*virtual*/ void cleanupWind();  		/*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);  	private:  		void * windDSP(void *newbuffer, int length); -	        typedef S16 WIND_SAMPLE_T; -        	LLWindGen<WIND_SAMPLE_T> *mWindGen; -        	S16 *mWindBuf; -        	U32 mWindBufFreq; -        	U32 mWindBufSamples; -        	U32 mWindBufBytes; -        	ALuint mWindSource; -	        int mNumEmptyWindALBuffers; - -        	static const int MAX_NUM_WIND_BUFFERS = 80; -        	static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec +        typedef S16 WIND_SAMPLE_T; +    	LLWindGen<WIND_SAMPLE_T> *mWindGen; +    	S16 *mWindBuf; +    	U32 mWindBufFreq; +    	U32 mWindBufSamples; +    	U32 mWindBufBytes; +    	ALuint mWindSource; +        int mNumEmptyWindALBuffers; + +    	static const int MAX_NUM_WIND_BUFFERS = 80; +    	static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec  };  class LLAudioChannelOpenAL : public LLAudioChannel diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h index 847bfa6e9d..1908b2545f 100644 --- a/indra/llaudio/llwindgen.h +++ b/indra/llaudio/llwindgen.h @@ -33,104 +33,149 @@  #define WINDGEN_H  #include "llcommon.h" -#include "llrand.h"  template <class MIXBUFFERFORMAT_T>  class LLWindGen  {  public: -	LLWindGen() : +	LLWindGen(const U32 sample_rate = 44100) :  		mTargetGain(0.f),  		mTargetFreq(100.f),  		mTargetPanGainR(0.5f), -		mbuf0(0.0), -		mbuf1(0.0), -		mbuf2(0.0), -		mbuf3(0.0), -		mbuf4(0.0), -		mbuf5(0.0), -		mY0(0.0), -		mY1(0.0), +		mInputSamplingRate(sample_rate), +		mSubSamples(2), +		mFilterBandWidth(50.f), +		mBuf0(0.0f), +		mBuf1(0.0f), +		mBuf2(0.0f), +		mY0(0.0f), +		mY1(0.0f),  		mCurrentGain(0.f),  		mCurrentFreq(100.f), -		mCurrentPanGainR(0.5f) {}; - -	static const U32 getInputSamplingRate() {return mInputSamplingRate;} +		mCurrentPanGainR(0.5f) +	{ +		mSamplePeriod = (F32)mSubSamples / (F32)mInputSamplingRate; +		mB2 = expf(-F_TWO_PI * mFilterBandWidth * mSamplePeriod); +	} +	const U32 getInputSamplingRate() { return mInputSamplingRate; } +	  	// newbuffer = the buffer passed from the previous DSP unit.  	// numsamples = length in samples-per-channel at this mix time. -	// stride = number of bytes between start of each sample.  	// NOTE: generates L/R interleaved stereo -	MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride) +	MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples)  	{ -		U8 *cursamplep = (U8*)newbuffer; +		MIXBUFFERFORMAT_T *cursamplep = newbuffer; +		 +		// Filter coefficients +		F32 a0 = 0.0f, b1 = 0.0f; -		double bandwidth = 50.0F; -		double a0,b1,b2; +		// No need to clip at normal volumes +		bool clip = mCurrentGain > 2.0f; -		// calculate resonant filter coeffs -		b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate)); +		bool interp_freq = false;  -		while (numsamples--) +		//if the frequency isn't changing much, we don't need to interpolate in the inner loop +		if (llabs(mTargetFreq - mCurrentFreq) < (mCurrentFreq * 0.112))  		{ -			mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq)); -			mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain)); -			mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR)); -			b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate)); -			a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2)); -			double nextSample; +			// calculate resonant filter coefficients +			mCurrentFreq = mTargetFreq; +			b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod)); +			a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2)); +		} +		else +		{ +			interp_freq = true; +		} +		 +		while (numsamples) +		{ +			F32 next_sample; +			 +			// Start with white noise +			// This expression is fragile, rearrange it and it will break! +			next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8); -			// start with white noise -			nextSample = ll_frand(2.0f) - 1.0f; +			// Apply a pinking filter +			// Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/ +			mBuf0 = mBuf0 * 0.99765f + next_sample * 0.0990460f; +			mBuf1 = mBuf1 * 0.96300f + next_sample * 0.2965164f; +			mBuf2 = mBuf2 * 0.57000f + next_sample * 1.0526913f; -			// apply pinking filter -			mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample;  -			mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample; -			mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample; -			mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample; -			mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample; -			mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample; +			next_sample = mBuf0 + mBuf1 + mBuf2 + next_sample * 0.1848f; -			nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5; +			if (interp_freq) +			{ +				// calculate and interpolate resonant filter coefficients +				mCurrentFreq = (0.999f * mCurrentFreq) + (0.001f * mTargetFreq); +				b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod)); +				a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2)); +			} -			// do a resonant filter on the noise -			nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 ); +			// Apply a resonant low-pass filter on the pink noise +	        next_sample = a0 * next_sample - b1 * mY0 - mB2 * mY1;  			mY1 = mY0; -			mY0 = nextSample; +			mY0 = next_sample; -			nextSample *= mCurrentGain; +			mCurrentGain = (0.999f * mCurrentGain) + (0.001f * mTargetGain); +			mCurrentPanGainR = (0.999f * mCurrentPanGainR) + (0.001f * mTargetPanGainR); -			MIXBUFFERFORMAT_T	sample; +			// For a 3dB pan law use: +			// next_sample *= mCurrentGain * ((mCurrentPanGainR*(mCurrentPanGainR-1)*1.652+1.413); +		    next_sample *= mCurrentGain; -			sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f); -			*(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); -			cursamplep += stride; - -			sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f); -			*(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); -			cursamplep += stride; +			// delta is used to interpolate between synthesized samples +			F32 delta = (next_sample - mLastSample) / (F32)mSubSamples; +			 +			// Fill the audio buffer, clipping if necessary +			for (U8 i=mSubSamples; i && numsamples; --i, --numsamples)  +			{ +				mLastSample = mLastSample + delta; +				S32	sample_right = (S32)(mLastSample * mCurrentPanGainR); +				S32	sample_left = (S32)mLastSample - sample_right; +				 +				if (!clip) +				{ +					*cursamplep = (MIXBUFFERFORMAT_T)sample_left; +					++cursamplep; +					*cursamplep = (MIXBUFFERFORMAT_T)sample_right; +					++cursamplep; +				} +				else +				{ +					*cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_left, (S32)S16_MIN, (S32)S16_MAX); +					++cursamplep; +					*cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_right, (S32)S16_MIN, (S32)S16_MAX); +					++cursamplep; +				} +			}  		}  		return newbuffer;  	} - +	 +public:  	F32 mTargetGain;  	F32 mTargetFreq;  	F32 mTargetPanGainR; - +	  private: -	static const U32 mInputSamplingRate = 44100; -	F64 mbuf0; -	F64 mbuf1; -	F64 mbuf2; -	F64 mbuf3; -	F64 mbuf4; -	F64 mbuf5; -	F64 mY0; -	F64 mY1; +	U32 mInputSamplingRate; +	U8  mSubSamples; +	F32 mSamplePeriod; +	F32 mFilterBandWidth; +	F32 mB2; +	 +	F32 mBuf0; +	F32 mBuf1; +	F32 mBuf2; +	F32 mY0; +	F32 mY1; +	  	F32 mCurrentGain;  	F32 mCurrentFreq;  	F32 mCurrentPanGainR; +	F32 mLastSample;  };  #endif diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 3c689930b8..527ab42fc9 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -232,7 +232,6 @@ set(llcommon_HEADER_FILES      metaclasst.h      metaproperty.h      metapropertyt.h -    processor.h      reflective.h      reflectivet.h      roles_constants.h @@ -290,6 +289,7 @@ if (LL_TESTS)    LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}") +  LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}") diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index f39a4e6619..20727dd76e 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -238,7 +238,7 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  #else // windows or x86-mac or x86-linux or x86-solaris  U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  { -	static U64 sCPUClockFrequency = U64(CProcessor().GetCPUFrequency(50)); +	static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency());  	// we drop the low-order byte in our timers, so report a lower frequency  	return sCPUClockFrequency >> 8; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index f6ab55a6b5..d3ba215751 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -30,139 +30,389 @@   * $/LicenseInfo$   */ -// Filename: Processor.cpp -// ======================= -// Author: Benjamin Jurke -// File history: 27.02.2002  - File created. Support for Intel and AMD processors -//               05.03.2002  - Fixed the CPUID bug: On Pre-Pentium CPUs the CPUID -//                             command is not available -//                           - The CProcessor::WriteInfoTextFile function do not  -//                             longer use Win32 file functions (-> os independend) -//                           - Optional include of the windows.h header which is -//                             still need for CProcessor::GetCPUFrequency. -//               06.03.2002  - My birthday (18th :-)) -//                           - Replaced the '\r\n' line endings in function  -//                             CProcessor::CPUInfoToText by '\n' -//                           - Replaced unsigned __int64 by signed __int64 for -//                             solving some compiler conversion problems -//                           - Fixed a bug at family=6, model=6 (Celeron -> P2) -////////////////////////////////////////////////////////////////////////////////// -  #include "linden_common.h" +#include "llprocessor.h" -#include "processor.h" +#include "llerror.h" -#include <memory> +//#include <memory>  #if LL_WINDOWS  #	define WIN32_LEAN_AND_MEAN  #	include <winsock2.h>  #	include <windows.h> +#	define _interlockedbittestandset _renamed_interlockedbittestandset +#	define _interlockedbittestandreset _renamed_interlockedbittestandreset +#	include <intrin.h> +#	undef _interlockedbittestandset +#	undef _interlockedbittestandreset  #endif -#if LL_LINUX -#include "llsys.h" -#endif // LL_LINUX +#include "llsd.h" + +#if LL_MSVC && _M_X64 +#      define LL_X86_64 1 +#      define LL_X86 1 +#elif LL_MSVC && _M_IX86 +#      define LL_X86 1 +#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) +#      define LL_X86_64 1 +#      define LL_X86 1 +#elif LL_GNUC && ( defined(__i386__) ) +#      define LL_X86 1 +#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) +#      define LL_PPC 1 +#endif + +class LLProcessorInfoImpl; // foward declaration for the mImpl; + +namespace  +{ +	enum cpu_info +	{ +		eBrandName = 0, +		eFrequency, +		eVendor, +		eStepping, +		eFamily, +		eExtendedFamily, +		eModel, +		eExtendedModel, +		eType, +		eBrandID, +		eFamilyName +	}; +		 + +	const char* cpu_info_names[] =  +	{ +		"Processor Name", +		"Frequency", +		"Vendor", +		"Stepping", +		"Family", +		"Extended Family", +		"Model", +		"Extended Model", +		"Type", +		"Brand ID", +		"Family Name" +	}; + +	enum cpu_config +	{ +		eMaxID, +		eMaxExtID, +		eCLFLUSHCacheLineSize, +		eAPICPhysicalID, +		eCacheLineSize, +		eL2Associativity, +		eCacheSizeK, +		eFeatureBits, +		eExtFeatureBits +	}; + +	const char* cpu_config_names[] = +	{ +		"Max Supported CPUID level", +		"Max Supported Ext. CPUID level", +		"CLFLUSH cache line size", +		"APIC Physical ID", +		"Cache Line Size",  +		"L2 Associativity", +		"Cache Size", +		"Feature Bits", +		"Ext. Feature Bits" +	}; -#if !LL_DARWIN && !LL_SOLARIS -#ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE -// We need the QueryPerformanceCounter and Sleep functions -#define FORCEINLINE __forceinline -#else -#define FORCEINLINE  -#endif +	// *NOTE:Mani - this contains the elements we reference directly and extensions beyond the first 32. +	// The rest of the names are referenced by bit maks returned from cpuid. +	enum cpu_features  +	{ +		eSSE_Ext=25, +		eSSE2_Ext=26, + +		eSSE3_Features=32, +		eMONTIOR_MWAIT=33, +		eCPLDebugStore=34, +		eThermalMonitor2=35, +		eAltivec=36 +	}; -// Some macros we often need -//////////////////////////// -#define CheckBit(var, bit)   ((var & (1 << bit)) ? true : false) +	const char* cpu_feature_names[] = +	{ +		"x87 FPU On Chip", +		"Virtual-8086 Mode Enhancement", +		"Debugging Extensions", +		"Page Size Extensions", +		"Time Stamp Counter", +		"RDMSR and WRMSR Support", +		"Physical Address Extensions", +		"Machine Check Exception", +		"CMPXCHG8B Instruction", +		"APIC On Chip", +		"Unknown1", +		"SYSENTER and SYSEXIT", +		"Memory Type Range Registers", +		"PTE Global Bit", +		"Machine Check Architecture", +		"Conditional Move/Compare Instruction", +		"Page Attribute Table", +		"Page Size Extension", +		"Processor Serial Number", +		"CFLUSH Extension", +		"Unknown2", +		"Debug Store", +		"Thermal Monitor and Clock Ctrl", +		"MMX Technology", +		"FXSAVE/FXRSTOR", +		"SSE Extensions", +		"SSE2 Extensions", +		"Self Snoop", +		"Hyper-threading Technology", +		"Thermal Monitor", +		"Unknown4", +		"Pend. Brk. EN.", // 31 End of FeatureInfo bits + +		"SSE3 New Instructions", // 32 +		"MONITOR/MWAIT",  +		"CPL Qualified Debug Store", +		"Thermal Monitor 2", + +		"Altivec" +	}; + +	std::string intel_CPUFamilyName(int composed_family)  +	{ +		switch(composed_family) +		{ +		case 3: return "Intel i386"; +		case 4: return "Intel i486"; +		case 5: return "Intel Pentium"; +		case 6: return "Intel Pentium Pro/2/3, Core"; +		case 7: return "Intel Itanium (IA-64)"; +		case 0xF: return "Intel Pentium 4"; +		case 0x10: return "Intel Itanium 2 (IA-64)"; +		} +		return "Unknown"; +	} +	 +	std::string amd_CPUFamilyName(int composed_family)  +	{ +		switch(composed_family) +		{ +		case 4: return "AMD 80486/5x86"; +		case 5: return "AMD K5/K6"; +		case 6: return "AMD K7"; +		case 0xF: return "AMD K8"; +		case 0x10: return "AMD K8L"; +		} +   		return "Unknown"; +	} + +	std::string compute_CPUFamilyName(const char* cpu_vendor, int composed_family)  +	{ +		const char* intel_string = "GenuineIntel"; +		const char* amd_string = "AuthenticAMD"; +		if(!strncmp(cpu_vendor, intel_string, strlen(intel_string))) +		{ +			return intel_CPUFamilyName(composed_family); +		} +		else if(!strncmp(cpu_vendor, amd_string, strlen(amd_string))) +		{ +			return amd_CPUFamilyName(composed_family); +		} +		return "Unknown"; +	} + +	std::string compute_CPUFamilyName(const char* cpu_vendor, int family, int ext_family)  +	{ +		const char* intel_string = "GenuineIntel"; +		const char* amd_string = "AuthenticAMD"; +		if(!strncmp(cpu_vendor, intel_string, strlen(intel_string))) +		{ +			U32 composed_family = family + ext_family; +			return intel_CPUFamilyName(composed_family); +		} +		else if(!strncmp(cpu_vendor, amd_string, strlen(amd_string))) +		{ +			U32 composed_family = (family == 0xF)  +				? family + ext_family +				: family; +			return amd_CPUFamilyName(composed_family); +		} +		return "Unknown"; +	} + +} // end unnamed namespace + +// The base class for implementations. +// Each platform should override this class. +class LLProcessorInfoImpl +{ +public: +	LLProcessorInfoImpl()  +	{ +		mProcessorInfo["info"] = LLSD::emptyMap(); +		mProcessorInfo["config"] = LLSD::emptyMap(); +		mProcessorInfo["extension"] = LLSD::emptyMap();		 +	} +	virtual ~LLProcessorInfoImpl() {} + +	F64 getCPUFrequency() const  +	{  +		return getInfo(eFrequency, 0).asReal();  +	} + +	bool hasSSE() const  +	{  +		return hasExtension(cpu_feature_names[eSSE_Ext]); +	} + +	bool hasSSE2() const +	{  +		return hasExtension(cpu_feature_names[eSSE2_Ext]); +	} + +	bool hasAltivec() const  +	{ +		return hasExtension("Altivec");  +	} + +	std::string getCPUFamilyName() const { return getInfo(eFamilyName, "Unknown").asString(); } +	std::string getCPUBrandName() const { return getInfo(eBrandName, "Unknown").asString(); } + +	// This is virtual to support a different linux format. +	// *NOTE:Mani - I didn't want to screw up server use of this data... +	virtual std::string getCPUFeatureDescription() const  +	{ +		std::ostringstream out; +		out << std::endl << std::endl; +		out << "// CPU General Information" << std::endl; +		out << "//////////////////////////" << std::endl; +		out << "Processor Name:   " << getCPUBrandName() << std::endl; +		out << "Frequency:        " << getCPUFrequency() << " MHz" << std::endl; +		out << "Vendor:			  " << getInfo(eVendor, "Unknown").asString() << std::endl; +		out << "Family:           " << getCPUFamilyName() << " (" << getInfo(eFamily, 0) << ")" << std::endl; +		out << "Extended family:  " << getInfo(eExtendedFamily, 0) << std::endl; +		out << "Model:            " << getInfo(eModel, 0) << std::endl; +		out << "Extended model:   " << getInfo(eExtendedModel, 0) << std::endl; +		out << "Type:             " << getInfo(eType, 0) << std::endl; +		out << "Brand ID:         " << getInfo(eBrandID, 0) << std::endl; +		out << std::endl; +		out << "// CPU Configuration" << std::endl; +		out << "//////////////////////////" << std::endl; +		 +		// Iterate through the dictionary of configuration options. +		LLSD configs = mProcessorInfo["config"]; +		for(LLSD::map_const_iterator cfgItr = configs.beginMap(); cfgItr != configs.endMap(); ++cfgItr) +		{ +			out << cfgItr->first << " = " << cfgItr->second << std::endl; +		} +		out << std::endl; +		 +		out << "// CPU Extensions" << std::endl; +		out << "//////////////////////////" << std::endl; +		 +		for(LLSD::map_const_iterator itr = mProcessorInfo["extension"].beginMap(); itr != mProcessorInfo["extension"].endMap(); ++itr) +		{ +			out << "  " << itr->first << std::endl;			 +		} +		return out.str();  +	} + +protected: +	void setInfo(cpu_info info_type, const LLSD& value)  +	{ +		setInfo(cpu_info_names[info_type], value); +	} +    LLSD getInfo(cpu_info info_type, const LLSD& defaultVal) const +	{ +		return getInfo(cpu_info_names[info_type], defaultVal); +	} + +	void setConfig(cpu_config config_type, const LLSD& value)  +	{  +		setConfig(cpu_config_names[config_type], value); +	} +	LLSD getConfig(cpu_config config_type, const LLSD& defaultVal) const +	{  +		return getConfig(cpu_config_names[config_type], defaultVal); +	} + +	void setExtension(const std::string& name) { mProcessorInfo["extension"][name] = "true"; } +	bool hasExtension(const std::string& name) const +	{  +		return mProcessorInfo["extension"].has(name); +	} + +private: +	void setInfo(const std::string& name, const LLSD& value) { mProcessorInfo["info"][name]=value; } +	LLSD getInfo(const std::string& name, const LLSD& defaultVal) const +	{  +		if(mProcessorInfo["info"].has(name)) +		{ +			return mProcessorInfo["info"][name]; +		} +		return defaultVal; +	} +	void setConfig(const std::string& name, const LLSD& value) { mProcessorInfo["config"][name]=value; } +	LLSD getConfig(const std::string& name, const LLSD& defaultVal) const +	{  +		LLSD r = mProcessorInfo["config"].get(name); +		return r.isDefined() ? r : defaultVal; +	} + +private: + +	LLSD mProcessorInfo; +}; + + +#ifdef LL_MSVC +// LL_MSVC and not LLWINDOWS because some of the following code  +// uses the MSVC compiler intrinsics __cpuid() and __rdtsc(). -#ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE  // Delays for the specified amount of milliseconds -static	void	_Delay(unsigned int ms) +static void _Delay(unsigned int ms)  { -   LARGE_INTEGER	freq, c1, c2; -	__int64		x; +	LARGE_INTEGER freq, c1, c2; +	__int64 x; -   // Get High-Res Timer frequency +	// Get High-Res Timer frequency  	if (!QueryPerformanceFrequency(&freq))	  		return; -		 +  	// Convert ms to High-Res Timer value  	x = freq.QuadPart/1000*ms;		 -   // Get first snapshot of High-Res Timer value +	// Get first snapshot of High-Res Timer value  	QueryPerformanceCounter(&c1);		  	do  	{ -            // Get second snapshot -	    QueryPerformanceCounter(&c2);	 +		// Get second snapshot +		QueryPerformanceCounter(&c2);	  	}while(c2.QuadPart-c1.QuadPart < x);  	// Loop while (second-first < x)	  } -#endif - -// CProcessor::CProcessor -// ====================== -// Class constructor: -///////////////////////// -CProcessor::CProcessor() -{ -	uqwFrequency = 0; -	strCPUName[0] = 0; -	memset(&CPUInfo, 0, sizeof(CPUInfo)); -} -// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) -// ========================================================================= -// Function to measure the current CPU frequency -//////////////////////////////////////////////////////////////////////////// -F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) +static F64 calculate_cpu_frequency(U32 measure_msecs)  { -#if LL_LINUX -	// use the shinier LLCPUInfo interface -	return 1000000.0F * gSysCPU.getMHz(); -#endif - -#ifndef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE -	return 0; -#else -	// If there are invalid measure time parameters, zero msecs for example, -	// we've to exit the function -	if (uiMeasureMSecs < 1) +	if(measure_msecs == 0)  	{ -		// If theres already a measured frequency available, we return it -        if (uqwFrequency > 0) -			return uqwFrequency; -		else -			return 0; -	} - -	// Now we check if the CPUID command is available -	if (!CheckCPUIDPresence())  		return 0; - -	// First we get the CPUID standard level 0x00000001 -	unsigned long reg; -	__asm -	{ -		mov eax, 1 -        cpuid -		mov reg, edx  	} -	// Then we check, if the RDTSC (Real Date Time Stamp Counter) is available. -	// This function is necessary for our measure process. -	if (!(reg & (1 << 4))) -		return 0; -  	// After that we declare some vars and check the frequency of the high  	// resolution timer for the measure process. -	// If there's no high-res timer, we exit. -	__int64 starttime, endtime, timedif, freq, start, end, dif; +	// If there"s no high-res timer, we exit. +	unsigned __int64 starttime, endtime, timedif, freq, start, end, dif;  	if (!QueryPerformanceFrequency((LARGE_INTEGER *) &freq)) +	{  		return 0; +	}  	// Now we can init the measure process. We set the process and thread priority  	// to the highest available level (Realtime priority). Also we focus the @@ -178,35 +428,27 @@ F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs)  	SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);  	SetProcessAffinityMask(hProcess, dwNewMask); -	// Now we call a CPUID to ensure, that all other prior called functions are -	// completed now (serialization) -	__asm cpuid +	//// Now we call a CPUID to ensure, that all other prior called functions are +	//// completed now (serialization) +	//__asm cpuid +	int cpu_info[4] = {-1}; +	__cpuid(cpu_info, 0);  	// We ask the high-res timer for the start time  	QueryPerformanceCounter((LARGE_INTEGER *) &starttime);  	// Then we get the current cpu clock and store it -	__asm  -	{ -		rdtsc -		mov dword ptr [start+4], edx -		mov dword ptr [start], eax -	} +	start = __rdtsc();  	// Now we wart for some msecs -	_Delay(uiMeasureMSecs); -//	Sleep(uiMeasureMSecs); +	_Delay(measure_msecs); +	//	Sleep(uiMeasureMSecs);  	// We ask for the end time  	QueryPerformanceCounter((LARGE_INTEGER *) &endtime);  	// And also for the end cpu clock -	__asm  -	{ -		rdtsc -		mov dword ptr [end+4], edx -		mov dword ptr [end], eax -	} +	end = __rdtsc();  	// Now we can restore the default process and thread priorities  	SetProcessAffinityMask(hProcess, dwProcessMask); @@ -219,2075 +461,433 @@ F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs)  	// And finally the frequency is the clock difference divided by the time  	// difference.  -	uqwFrequency = (F64)dif / (((F64)timedif) / freq); +	F64 frequency = (F64)dif / (((F64)timedif) / freq);  	// At last we just return the frequency that is also stored in the call -	// member var uqwFrequency -	return uqwFrequency; -#endif +	// member var uqwFrequency - converted to MHz +	return frequency  / (F64)1000000;  } -// bool CProcessor::AnalyzeIntelProcessor() -// ======================================== -// Private class function for analyzing an Intel processor -////////////////////////////////////////////////////////// -bool CProcessor::AnalyzeIntelProcessor() +// Windows implementation +class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl  { -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, edxreg; - -	// First we check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return false; - -	// Now we get the CPUID standard level 0x00000001 -	__asm +public: +	LLProcessorInfoWindowsImpl()  	{ -		mov eax, 1 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -		mov edxreg, edx +		getCPUIDInfo(); +		setInfo(eFrequency, calculate_cpu_frequency(50));  	} -     -	// Then get the cpu model, family, type, stepping and brand id by masking -	// the eax and ebx register -	CPUInfo.uiStepping = eaxreg & 0xF; -	CPUInfo.uiModel    = (eaxreg >> 4) & 0xF; -	CPUInfo.uiFamily   = (eaxreg >> 8) & 0xF; -	CPUInfo.uiType     = (eaxreg >> 12) & 0x3; -	CPUInfo.uiBrandID  = ebxreg & 0xF; - -	static const char* INTEL_BRAND[] = -	{ -		/* 0x00 */ "", -		/* 0x01 */ "0.18 micron Intel Celeron", -		/* 0x02 */ "0.18 micron Intel Pentium III", -		/* 0x03 */ "0.13 micron Intel Celeron", -		/* 0x04 */ "0.13 micron Intel Pentium III", -		/* 0x05 */ "", -		/* 0x06 */ "0.13 micron Intel Pentium III Mobile", -		/* 0x07 */ "0.13 micron Intel Celeron Mobile", -		/* 0x08 */ "0.18 micron Intel Pentium 4", -		/* 0x09 */ "0.13 micron Intel Pentium 4", -		/* 0x0A */ "0.13 micron Intel Celeron", -		/* 0x0B */ "0.13 micron Intel Pentium 4 Xeon", -		/* 0x0C */ "Intel Xeon MP", -		/* 0x0D */ "", -		/* 0x0E */ "0.18 micron Intel Pentium 4 Xeon", -		/* 0x0F */ "Mobile Intel Celeron", -		/* 0x10 */ "", -		/* 0x11 */ "Mobile Genuine Intel", -		/* 0x12 */ "Intel Celeron M", -		/* 0x13 */ "Mobile Intel Celeron", -		/* 0x14 */ "Intel Celeron", -		/* 0x15 */ "Mobile Genuine Intel", -		/* 0x16 */ "Intel Pentium M", -		/* 0x17 */ "Mobile Intel Celeron", -	}; -	// Only override the brand if we have it in the lookup table.  We should -	// already have a string here from GetCPUInfo().  JC -	if ( CPUInfo.uiBrandID < LL_ARRAY_SIZE(INTEL_BRAND) ) +private: +	void getCPUIDInfo()  	{ -		strncpy(CPUInfo.strBrandID, INTEL_BRAND[CPUInfo.uiBrandID], sizeof(CPUInfo.strBrandID)-1); -		CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; +		// http://msdn.microsoft.com/en-us/library/hskdteyh(VS.80).aspx + +		// __cpuid with an InfoType argument of 0 returns the number of +		// valid Ids in cpu_info[0] and the CPU identification string in +		// the other three array elements. The CPU identification string is +		// not in linear order. The code below arranges the information  +		// in a human readable form. +		int cpu_info[4] = {-1}; +		__cpuid(cpu_info, 0); +		unsigned int ids = (unsigned int)cpu_info[0]; +		setConfig(eMaxID, (S32)ids); + +		char cpu_vendor[0x20]; +		memset(cpu_vendor, 0, sizeof(cpu_vendor)); +		*((int*)cpu_vendor) = cpu_info[1]; +		*((int*)(cpu_vendor+4)) = cpu_info[3]; +		*((int*)(cpu_vendor+8)) = cpu_info[2]; +		setInfo(eVendor, cpu_vendor); -		if (CPUInfo.uiBrandID == 3 && CPUInfo.uiModel == 6) +		// Get the information associated with each valid Id +		for(unsigned int i=0; i<=ids; ++i)  		{ -			strcpy(CPUInfo.strBrandID, "0.18 micron Intel Pentium III Xeon"); -		} -	} +			__cpuid(cpu_info, i); -	// Then we translate the cpu family -    switch (CPUInfo.uiFamily) -	{ -		case 3:			// Family = 3:  i386 (80386) processor family -			strcpy(CPUInfo.strFamily, "Intel i386");	/* Flawfinder: ignore */	 -			break; -		case 4:			// Family = 4:  i486 (80486) processor family -			strcpy(CPUInfo.strFamily, "Intel i486");	/* Flawfinder: ignore */	 -			break; -		case 5:			// Family = 5:  Pentium (80586) processor family -			strcpy(CPUInfo.strFamily, "Intel Pentium");	/* Flawfinder: ignore */	 -			break; -		case 6:			// Family = 6:  Pentium Pro (80686) processor family -			strcpy(CPUInfo.strFamily, "Intel Pentium Pro/2/3, Core");	/* Flawfinder: ignore */	 -			break; -		case 15:		// Family = 15:  Extended family specific -			// Masking the extended family -			CPUInfo.uiExtendedFamily = (eaxreg >> 20) & 0xFF; -			switch (CPUInfo.uiExtendedFamily) -			{ -				case 0:			// Family = 15, Ext. Family = 0:  Pentium 4 (80786 ??) processor family -					strcpy(CPUInfo.strFamily, "Intel Pentium 4");	/* Flawfinder: ignore */	 -					break; -				case 1:			// Family = 15, Ext. Family = 1:  McKinley (64-bit) processor family -					strcpy(CPUInfo.strFamily, "Intel McKinley (IA-64)");	/* Flawfinder: ignore */	 -					break; -				default:		// Sure is sure -					strcpy(CPUInfo.strFamily, "Unknown Intel Pentium 4+");	/* Flawfinder: ignore */	 -					break; -			} -			break; -		default:		// Failsave -			strcpy(CPUInfo.strFamily, "Unknown");	/* Flawfinder: ignore */ -			break; -    } - -	// Now we come to the big deal, the exact model name -	switch (CPUInfo.uiFamily) -	{ -		case 3:			// i386 (80386) processor family -			strcpy(CPUInfo.strModel, "Unknown Intel i386");	/* Flawfinder: ignore */ -			strncat(strCPUName, "Intel i386", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -			break; -		case 4:			// i486 (80486) processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  i486 DX-25/33 processor model -					strcpy(CPUInfo.strModel, "Intel i486 DX-25/33");	/* Flawfinder: ignore */			 -					strncat(strCPUName, "Intel i486 DX-25/33", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 1:			// Model = 1:  i486 DX-50 processor model -					strcpy(CPUInfo.strModel, "Intel i486 DX-50");	/* Flawfinder: ignore */		 -					strncat(strCPUName, "Intel i486 DX-50", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 2:			// Model = 2:  i486 SX processor model -					strcpy(CPUInfo.strModel, "Intel i486 SX");	/* Flawfinder: ignore */		 -					strncat(strCPUName, "Intel i486 SX", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 3:			// Model = 3:  i486 DX2 (with i487 numeric coprocessor) processor model -					strcpy(CPUInfo.strModel, "Intel i486 487/DX2");	/* Flawfinder: ignore */		 -					strncat(strCPUName, "Intel i486 DX2 with i487 numeric coprocessor", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 4:			// Model = 4:  i486 SL processor model (never heard ?!?) -					strcpy(CPUInfo.strModel, "Intel i486 SL");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 SL", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 5:			// Model = 5:  i486 SX2 processor model -					strcpy(CPUInfo.strModel, "Intel i486 SX2");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 SX2", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 7:			// Model = 7:  i486 write-back enhanced DX2 processor model -					strcpy(CPUInfo.strModel, "Intel i486 write-back enhanced DX2");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 write-back enhanced DX2", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 8:			// Model = 8:  i486 DX4 processor model -					strcpy(CPUInfo.strModel, "Intel i486 DX4");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 DX4", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 9:			// Model = 9:  i486 write-back enhanced DX4 processor model -					strcpy(CPUInfo.strModel, "Intel i486 write-back enhanced DX4");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 DX4", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown Intel i486");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 (Unknown model)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -			} -			break; -		case 5:			// Pentium (80586) processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  Pentium (P5 A-Step) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium (P5 A-Step)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium (P5 A-Step core)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break;		// Famous for the DIV bug, as far as I know -				case 1:			// Model = 1:  Pentium 60/66 processor model -					strcpy(CPUInfo.strModel, "Intel Pentium 60/66 (P5)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium 60/66 (P5 core)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 2:			// Model = 2:  Pentium 75-200 (P54C) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium 75-200 (P54C)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium 75-200 (P54C core)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 3:			// Model = 3:  Pentium overdrive for 486 systems processor model -					strcpy(CPUInfo.strModel, "Intel Pentium for 486 system (P24T Overdrive)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium for 486 (P24T overdrive core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 4:			// Model = 4:  Pentium MMX processor model -					strcpy(CPUInfo.strModel, "Intel Pentium MMX (P55C)");	/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium MMX (P55C core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 7:			// Model = 7:  Pentium processor model (don't know difference to Model=2) -					strcpy(CPUInfo.strModel, "Intel Pentium (P54C)");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium (P54C core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 8:			// Model = 8:  Pentium MMX (0.25 micron) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium MMX (P55C), 0.25 micron");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium MMX (P55C core), 0.25 micron", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown Intel Pentium");	/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium (Unknown P5-model)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -			} -			break; -		case 6:			// Pentium Pro (80686) processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  Pentium Pro (P6 A-Step) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium Pro (P6 A-Step)");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium Pro (P6 A-Step core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 1:			// Model = 1:  Pentium Pro -					strcpy(CPUInfo.strModel, "Intel Pentium Pro (P6)");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium Pro (P6 core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 3:			// Model = 3:  Pentium II (66 MHz FSB, I think) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium II Model 3, 0.28 micron");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium II (Model 3 core, 0.28 micron process)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 5:			// Model = 5:  Pentium II/Xeon/Celeron (0.25 micron) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium II Model 5/Xeon/Celeron, 0.25 micron");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium II/Xeon/Celeron (Model 5 core, 0.25 micron process)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 6:			// Model = 6:  Pentium II with internal L2 cache -					strcpy(CPUInfo.strModel, "Intel Pentium II - internal L2 cache");	/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium II with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 7:			// Model = 7:  Pentium III/Xeon (extern L2 cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Pentium III Xeon - external L2 cache, 0.25 micron");		 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium III/Pentium III Xeon (0.25 micron process) with external L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 8:			// Model = 8:  Pentium III/Xeon/Celeron (256 KB on-die L2 cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.18 micron");	 /*Flawfinder: ignore*/ -					// We want to know it exactly: -					switch (CPUInfo.uiBrandID) -					{ -						case 1:			// Model = 8, Brand id = 1:  Celeron (on-die L2 cache) processor model -							strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -                        case 2:			// Model = 8, Brand id = 2:  Pentium III (on-die L2 cache) processor model (my current cpu :-)) -							strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						case 3:			// Model = 8, Brand id = 3:  Pentium III Xeon (on-die L2 cache) processor model -                            strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						default:		// ... -							strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -					} -					break; -				case 9:		// Model = 9:  Intel Pentium M processor, Intel Celeron M processor, model 9 -					strcpy(CPUInfo.strModel, "Intel Pentium M Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium M Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 0xA:		// Model = 0xA:  Pentium III/Xeon/Celeron (1 or 2 MB on-die L2 cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.18 micron");	 /*Flawfinder: ignore*/ -					// Exact detection: -					switch (CPUInfo.uiBrandID) -					{ -						case 1:			// Model = 0xA, Brand id = 1:  Celeron (1 or 2 MB on-die L2 cache (does it exist??)) processor model -							strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -                        case 2:			// Model = 0xA, Brand id = 2:  Pentium III (1 or 2 MB on-die L2 cache (never seen...)) processor model -							strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						case 3:			// Model = 0xA, Brand id = 3:  Pentium III Xeon (1 or 2 MB on-die L2 cache) processor model -                            strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						default:		// Getting bored of this............ -							strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -					} -					break; -				case 0xB:		// Model = 0xB: Pentium III/Xeon/Celeron (Tualatin core, on-die cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.13 micron");	 /*Flawfinder: ignore*/ -					// Omniscient: ;-) -					switch (CPUInfo.uiBrandID) -					{ -						case 3:			// Model = 0xB, Brand id = 3:  Celeron (Tualatin core) processor model -							strncat(strCPUName, "Intel Celeron (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -                        case 4:			// Model = 0xB, Brand id = 4:  Pentium III (Tualatin core) processor model -							strncat(strCPUName, "Intel Pentium III (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						case 7:			// Model = 0xB, Brand id = 7:  Celeron mobile (Tualatin core) processor model -                            strncat(strCPUName, "Intel Celeron mobile (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						default:		// *bored* -							strncat(strCPUName, "Intel Pentium III Tualatin core (unknown model, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -					} -					break; -				case 0xD:		// Model = 0xD:  Intel Pentium M processor, Intel Celeron M processor, model D -					strcpy(CPUInfo.strModel, "Intel Pentium M Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium M Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 0xE:		// Model = 0xE:  Intel Core Duo processor, Intel Core Solo processor, model E -					strcpy(CPUInfo.strModel, "Intel Core Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Core Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break;	 -				case 0xF:		// Model = 0xF:  Intel Core 2 Duo processor, model F -					strcpy(CPUInfo.strModel, "Intel Core 2 Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Core 2 Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break;	 -				default:		// *more bored* -					strcpy(CPUInfo.strModel, "Unknown Intel Pentium Pro/2/3, Core"); /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium Pro/2/3, Core (Unknown model)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -			} -			break; -		case 15:		// Extended processor family -			// Masking the extended model -			CPUInfo.uiExtendedModel = (eaxreg >> 16) & 0xFF; -			switch (CPUInfo.uiModel) +			// Interpret CPU feature information. +			if  (i == 1)  			{ -				case 0:			// Model = 0:  Pentium 4 Willamette (A-Step) core -					if ((CPUInfo.uiBrandID) == 8)	// Brand id = 8:  P4 Willamette -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette (A-Step)"); /*Flawfinder: ignore*/ -						strncat(strCPUName, "Intel Pentium 4 Willamette (A-Step)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					} -					else							// else Xeon -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette Xeon (A-Step)");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Willamette Xeon (A-Step)", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */	 -					} -					break; -				case 1:			// Model = 1:  Pentium 4 Willamette core -					if ((CPUInfo.uiBrandID) == 8)	// Brand id = 8:  P4 Willamette +				setInfo(eStepping, cpu_info[0] & 0xf); +				setInfo(eModel, (cpu_info[0] >> 4) & 0xf); +				int family = (cpu_info[0] >> 8) & 0xf; +				setInfo(eFamily, family); +				setInfo(eType, (cpu_info[0] >> 12) & 0x3); +				setInfo(eExtendedModel, (cpu_info[0] >> 16) & 0xf); +				int ext_family = (cpu_info[0] >> 20) & 0xff; +				setInfo(eExtendedFamily, ext_family); +				setInfo(eBrandID, cpu_info[1] & 0xff); + +				setInfo(eFamilyName, compute_CPUFamilyName(cpu_vendor, family, ext_family)); + +				setConfig(eCLFLUSHCacheLineSize, ((cpu_info[1] >> 8) & 0xff) * 8); +				setConfig(eAPICPhysicalID, (cpu_info[1] >> 24) & 0xff); +				 +				if(cpu_info[2] & 0x1) +				{ +					setExtension(cpu_feature_names[eSSE3_Features]); +				} + +				if(cpu_info[2] & 0x8) +				{ +					setExtension(cpu_feature_names[eMONTIOR_MWAIT]); +				} +				 +				if(cpu_info[2] & 0x10) +				{ +					setExtension(cpu_feature_names[eCPLDebugStore]); +				} +				 +				if(cpu_info[2] & 0x100) +				{ +					setExtension(cpu_feature_names[eThermalMonitor2]); +				} +						 +				unsigned int feature_info = (unsigned int) cpu_info[3]; +				for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1) +				{ +					if(feature_info & bit)  					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Willamette", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ +						setExtension(cpu_feature_names[index]);  					} -					else							// else Xeon -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette Xeon");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Willamette Xeon", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					} -					break; -				case 2:			// Model = 2:  Pentium 4 Northwood core -					if (((CPUInfo.uiBrandID) == 9) || ((CPUInfo.uiBrandID) == 0xA))		// P4 Willamette -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Northwood");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Northwood", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					} -					else							// Xeon -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Northwood Xeon");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Northwood Xeon", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					} -					break; -				default:		// Silly stupid never used failsave option -					strcpy(CPUInfo.strModel, "Unknown Intel Pentium 4");		/* Flawfinder: ignore */ -					strncat(strCPUName, "Intel Pentium 4 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					break; +				}  			} -			break; -		default:		// *grmpf* -			strcpy(CPUInfo.strModel, "Unknown Intel model");		/* Flawfinder: ignore */ -			strncat(strCPUName, "Intel (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -			break; -    } - -	// After the long processor model block we now come to the processors serial -	// number. -	// First of all we check if the processor supports the serial number -	if (CPUInfo.MaxSupportedLevel >= 3) -	{ -		// If it supports the serial number CPUID level 0x00000003 we read the data -		unsigned long sig1, sig2, sig3; -		__asm -		{ -			mov eax, 1 -			cpuid -			mov sig1, eax -			mov eax, 3 -			cpuid -			mov sig2, ecx -			mov sig3, edx  		} -		// Then we convert the data to a readable string -		snprintf(	/* Flawfinder: ignore */ -			CPUInfo.strProcessorSerial, -			sizeof(CPUInfo.strProcessorSerial), -			"%04lX-%04lX-%04lX-%04lX-%04lX-%04lX", -			sig1 >> 16, -			sig1 & 0xFFFF, -			sig3 >> 16, -			sig3 & 0xFFFF, -			sig2 >> 16, sig2 & 0xFFFF); -	} -	else -	{ -		// If there's no serial number support we just put "No serial number" -		snprintf(	/* Flawfinder: ignore */ -			CPUInfo.strProcessorSerial, -			sizeof(CPUInfo.strProcessorSerial), -			"No Processor Serial Number");	 -	} - -	// Now we get the standard processor extensions -	GetStandardProcessorExtensions(); -	// And finally the processor configuration (caches, TLBs, ...) and translate -	// the data to readable strings -	GetStandardProcessorConfiguration(); -	TranslateProcessorConfiguration(); +		// Calling __cpuid with 0x80000000 as the InfoType argument +		// gets the number of valid extended IDs. +		__cpuid(cpu_info, 0x80000000); +		unsigned int ext_ids = cpu_info[0]; +		setConfig(eMaxExtID, 0); -	// At last... -	return true; -#else -	return FALSE; -#endif -} +		char cpu_brand_string[0x40]; +		memset(cpu_brand_string, 0, sizeof(cpu_brand_string)); -// bool CProcessor::AnalyzeAMDProcessor() -// ====================================== -// Private class function for analyzing an AMD processor -//////////////////////////////////////////////////////// -bool CProcessor::AnalyzeAMDProcessor() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, ecxreg, edxreg; - -	// First of all we check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return 0; - -	// Now we get the CPUID standard level 0x00000001 -	__asm -	{ -		mov eax, 1 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -		mov edxreg, edx -	} -     -	// Then we mask the model, family, stepping and type (AMD does not support brand id) -	CPUInfo.uiStepping = eaxreg & 0xF; -	CPUInfo.uiModel    = (eaxreg >> 4) & 0xF; -	CPUInfo.uiFamily   = (eaxreg >> 8) & 0xF; -	CPUInfo.uiType     = (eaxreg >> 12) & 0x3; - -	// Now we check if the processor supports the brand id string extended CPUID level -	if (CPUInfo.MaxSupportedExtendedLevel >= 0x80000004) -	{ -		// If it supports the extended CPUID level 0x80000004 we read the data -		char tmp[52];		/* Flawfinder: ignore */ -		memset(tmp, 0, sizeof(tmp)); -        __asm +		// Get the information associated with each extended ID. +		for(unsigned int i=0x80000000; i<=ext_ids; ++i)  		{ -			mov eax, 0x80000002 -			cpuid -			mov dword ptr [tmp], eax -			mov dword ptr [tmp+4], ebx -			mov dword ptr [tmp+8], ecx -			mov dword ptr [tmp+12], edx -			mov eax, 0x80000003 -			cpuid -			mov dword ptr [tmp+16], eax -			mov dword ptr [tmp+20], ebx -			mov dword ptr [tmp+24], ecx -			mov dword ptr [tmp+28], edx -			mov eax, 0x80000004 -			cpuid -			mov dword ptr [tmp+32], eax -			mov dword ptr [tmp+36], ebx -			mov dword ptr [tmp+40], ecx -			mov dword ptr [tmp+44], edx -		} -		// And copy it to the brand id string -		strncpy(CPUInfo.strBrandID, tmp,sizeof(CPUInfo.strBrandID)-1); -		CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; -	} -	else -	{ -		// Or just tell there is no brand id string support -		strcpy(CPUInfo.strBrandID, "");		/* Flawfinder: ignore */ -	} - -	// After that we translate the processor family -    switch(CPUInfo.uiFamily) -	{ -		case 4:			// Family = 4:  486 (80486) or 5x86 (80486) processor family -			switch (CPUInfo.uiModel) +			__cpuid(cpu_info, i); + +			// Interpret CPU brand string and cache information. +			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)  			{ -				case 3:			// Thanks to AMD for this nice form of family -				case 7:			// detection.... *grmpf* -				case 8: -				case 9: -					strcpy(CPUInfo.strFamily, "AMD 80486");		/* Flawfinder: ignore */ -					break; -				case 0xE: -				case 0xF: -					strcpy(CPUInfo.strFamily, "AMD 5x86");		/* Flawfinder: ignore */ -					break; -				default: -					strcpy(CPUInfo.strFamily, "Unknown family");		/* Flawfinder: ignore */ -					break; +				memcpy(cpu_brand_string + 32, cpu_info, sizeof(cpu_info)); +				setInfo(eBrandName, cpu_brand_string);  			} -			break; -		case 5:			// Family = 5:  K5 or K6 processor family -			switch (CPUInfo.uiModel) +			else if  (i == 0x80000006)  			{ -				case 0: -				case 1: -				case 2: -				case 3: -					strcpy(CPUInfo.strFamily, "AMD K5");		/* Flawfinder: ignore */ -					break; -				case 6: -				case 7: -				case 8: -				case 9: -					strcpy(CPUInfo.strFamily, "AMD K6");		/* Flawfinder: ignore */ -					break; -				default: -					strcpy(CPUInfo.strFamily, "Unknown family");		/* Flawfinder: ignore */ -					break; +				setConfig(eCacheLineSize, cpu_info[2] & 0xff); +				setConfig(eL2Associativity, (cpu_info[2] >> 12) & 0xf); +				setConfig(eCacheSizeK, (cpu_info[2] >> 16) & 0xffff);  			} -			break; -		case 6:			// Family = 6:  K7 (Athlon, ...) processor family -			strcpy(CPUInfo.strFamily, "AMD K7");		/* Flawfinder: ignore */ -			break; -		default:		// For security -			strcpy(CPUInfo.strFamily, "Unknown family");		/* Flawfinder: ignore */ -			break; +		}  	} +}; -	// After the family detection we come to the specific processor model -	// detection -	switch (CPUInfo.uiFamily) -	{ -		case 4:			// Family = 4:  486 (80486) or 5x85 (80486) processor family -			switch (CPUInfo.uiModel) -			{ -				case 3:			// Model = 3:  80486 DX2 -					strcpy(CPUInfo.strModel, "AMD 80486 DX2");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 DX2", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 7:			// Model = 7:  80486 write-back enhanced DX2 -					strcpy(CPUInfo.strModel, "AMD 80486 write-back enhanced DX2");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 write-back enhanced DX2", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 8:			// Model = 8:  80486 DX4 -					strcpy(CPUInfo.strModel, "AMD 80486 DX4");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 DX4", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 9:			// Model = 9:  80486 write-back enhanced DX4 -					strcpy(CPUInfo.strModel, "AMD 80486 write-back enhanced DX4");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 write-back enhanced DX4", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 0xE:		// Model = 0xE:  5x86 -					strcpy(CPUInfo.strModel, "AMD 5x86");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 5x86", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 0xF:		// Model = 0xF:  5x86 write-back enhanced (oh my god.....) -					strcpy(CPUInfo.strModel, "AMD 5x86 write-back enhanced");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 5x86 write-back enhanced", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown AMD 80486 or 5x86 model");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 or 5x86 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -			} -			break; -		case 5:			// Family = 5:  K5 / K6 processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  K5 SSA 5 (Pentium Rating *ggg* 75, 90 and 100 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 SSA5 (PR75, PR90, PR100)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 SSA5 (PR75, PR90, PR100)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 1:			// Model = 1:  K5 5k86 (PR 120 and 133 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 5k86 (PR120, PR133)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 5k86 (PR120, PR133)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 2:			// Model = 2:  K5 5k86 (PR 166 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 5k86 (PR166)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 5k86 (PR166)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 3:			// Model = 3:  K5 5k86 (PR 200 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 5k86 (PR200)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 5k86 (PR200)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 6:			// Model = 6:  K6 -					strcpy(CPUInfo.strModel, "AMD K6 (0.30 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6 (0.30 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 7:			// Model = 7:  K6 (0.25 micron) -					strcpy(CPUInfo.strModel, "AMD K6 (0.25 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6 (0.25 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 8:			// Model = 8:  K6-2 -					strcpy(CPUInfo.strModel, "AMD K6-2");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6-2", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 9:			// Model = 9:  K6-III -					strcpy(CPUInfo.strModel, "AMD K6-III");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6-III", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 0xD:		// Model = 0xD:  K6-2+ / K6-III+ -					strcpy(CPUInfo.strModel, "AMD K6-2+ or K6-III+ (0.18 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6-2+ or K6-III+ (0.18 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);	/* Flawfinder: ignore */ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown AMD K5 or K6 model");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 or K6 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -			} -			break; -		case 6:			// Family = 6:  K7 processor family (AMDs first good processors) -			switch (CPUInfo.uiModel) +#elif LL_DARWIN + +#include <mach/machine.h> +#include <sys/sysctl.h> + +class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl +{ +public: +	LLProcessorInfoDarwinImpl()  +	{ +		getCPUIDInfo(); +		uint64_t frequency = getSysctlInt64("hw.cpufrequency"); +		setInfo(eFrequency, (F64)frequency  / (F64)1000000); +	} + +	virtual ~LLProcessorInfoDarwinImpl() {} + +private: +	int getSysctlInt(const char* name) +   	{ +		int result = 0; +		size_t len = sizeof(int); +		int error = sysctlbyname(name, (void*)&result, &len, NULL, 0); +		return error == -1 ? 0 : result; +   	} + +	uint64_t getSysctlInt64(const char* name) +   	{ +		uint64_t value = 0; +		size_t size = sizeof(value); +		int result = sysctlbyname(name, (void*)&value, &size, NULL, 0); +		if ( result == 0 )  +		{  +			if ( size == sizeof( uint64_t ) )  +				;  +			else if ( size == sizeof( uint32_t ) )  +				value = (uint64_t)(( uint32_t *)&value);  +			else if ( size == sizeof( uint16_t ) )  +				value =  (uint64_t)(( uint16_t *)&value);  +			else if ( size == sizeof( uint8_t ) )  +				value =  (uint64_t)(( uint8_t *)&value);  +			else  			{ -				case 1:			// Athlon -					strcpy(CPUInfo.strModel, "AMD Athlon (0.25 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon (0.25 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 2:			// Athlon (0.18 micron) -					strcpy(CPUInfo.strModel, "AMD Athlon (0.18 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon (0.18 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 3:			// Duron (Spitfire core) -					strcpy(CPUInfo.strModel, "AMD Duron (Spitfire)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Duron (Spitfire core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 4:			// Athlon (Thunderbird core) -					strcpy(CPUInfo.strModel, "AMD Athlon (Thunderbird)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon (Thunderbird core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 6:			// Athlon MP / Mobile Athlon (Palomino core) -					strcpy(CPUInfo.strModel, "AMD Athlon MP/Mobile Athlon (Palomino)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon MP/Mobile Athlon (Palomino core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 7:			// Mobile Duron (Morgan core) -					strcpy(CPUInfo.strModel, "AMD Mobile Duron (Morgan)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Mobile Duron (Morgan core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown AMD K7 model");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K7 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; +				LL_WARNS("Unknown type returned from sysctl!") << LL_ENDL;  			} -			break; -		default:		// ... -			strcpy(CPUInfo.strModel, "Unknown AMD model");		/* Flawfinder: ignore */ -			strncat(strCPUName, "AMD (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -			break; -    } - -	// Now we read the standard processor extension that are stored in the same -	// way the Intel standard extensions are -	GetStandardProcessorExtensions(); - -	// Then we check if theres an extended CPUID level support -	if (CPUInfo.MaxSupportedExtendedLevel >= 0x80000001) -	{ -		// If we can access the extended CPUID level 0x80000001 we get the -		// edx register -		__asm -		{ -			mov eax, 0x80000001 -			cpuid -			mov edxreg, edx  		} - -		// Now we can mask some AMD specific cpu extensions -		CPUInfo._Ext.EMMX_MultimediaExtensions					= CheckBit(edxreg, 22); -		CPUInfo._Ext.AA64_AMD64BitArchitecture					= CheckBit(edxreg, 29); -		CPUInfo._Ext._E3DNOW_InstructionExtensions				= CheckBit(edxreg, 30); -		CPUInfo._Ext._3DNOW_InstructionExtensions				= CheckBit(edxreg, 31); -	} - -	// After that we check if the processor supports the ext. CPUID level -	// 0x80000006 -	if (CPUInfo.MaxSupportedExtendedLevel >= 0x80000006) +				 +		return result == -1 ? 0 : value; +   	} +	 +	void getCPUIDInfo()  	{ -		// If it's present, we read it out -        __asm -		{ -            mov eax, 0x80000005 -			cpuid -			mov eaxreg, eax -			mov ebxreg, ebx -			mov ecxreg, ecx -			mov edxreg, edx -		} +		size_t len = 0; -		// Then we mask the L1 Data TLB information -		if ((ebxreg >> 16) && (eaxreg >> 16)) -		{ -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 2 MB / 4MB"); 	/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = (eaxreg >> 24) & 0xFF; -			CPUInfo._Data.uiEntries = (eaxreg >> 16) & 0xFF; -		} -		else if (eaxreg >> 16) -		{ -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "2 MB / 4MB");		/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = (eaxreg >> 24) & 0xFF; -			CPUInfo._Data.uiEntries = (eaxreg >> 16) & 0xFF; -		} -		else if (ebxreg >> 16) -		{ -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB");		/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = (ebxreg >> 24) & 0xFF; -			CPUInfo._Data.uiEntries = (ebxreg >> 16) & 0xFF; -		} -		if (CPUInfo._Data.uiAssociativeWays == 0xFF) -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; - -		// Now the L1 Instruction/Code TLB information -		if ((ebxreg & 0xFFFF) && (eaxreg & 0xFFFF)) -		{ -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4MB");		/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = (eaxreg >> 8) & 0xFF; -			CPUInfo._Instruction.uiEntries = eaxreg & 0xFF; -		} -		else if (eaxreg & 0xFFFF) -		{ -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "2 MB / 4MB");		/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = (eaxreg >> 8) & 0xFF; -			CPUInfo._Instruction.uiEntries = eaxreg & 0xFF; -		} -		else if (ebxreg & 0xFFFF) -		{ -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB");	/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = (ebxreg >> 8) & 0xFF; -			CPUInfo._Instruction.uiEntries = ebxreg & 0xFF; -		} -		if (CPUInfo._Instruction.uiAssociativeWays == 0xFF) -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; +		char cpu_brand_string[0x40]; +		len = sizeof(cpu_brand_string); +		memset(cpu_brand_string, 0, len); +		sysctlbyname("machdep.cpu.brand_string", (void*)cpu_brand_string, &len, NULL, 0); +		cpu_brand_string[0x3f] = 0; +		setInfo(eBrandName, cpu_brand_string); -		// Then we read the L1 data cache information -		if ((ecxreg >> 24) > 0) -		{ -			CPUInfo._L1.Data.bPresent = true; -			snprintf(CPUInfo._L1.Data.strSize, sizeof(CPUInfo._L1.Data.strSize), "%d KB", ecxreg >> 24);		/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = (ecxreg >> 15) & 0xFF; -			CPUInfo._L1.Data.uiLineSize = ecxreg & 0xFF; -		} -		// After that we read the L2 instruction/code cache information -		if ((edxreg >> 24) > 0) -		{ -			CPUInfo._L1.Instruction.bPresent = true; -			snprintf(CPUInfo._L1.Instruction.strSize, sizeof(CPUInfo._L1.Instruction.strSize), "%d KB", edxreg >> 24); 	/* Flawfinder: ignore */ -			CPUInfo._L1.Instruction.uiAssociativeWays = (edxreg >> 15) & 0xFF; -			CPUInfo._L1.Instruction.uiLineSize = edxreg & 0xFF; -		} - -		// Note: I'm not absolutely sure that the L1 page size code (the -		// 'if/else if/else if' structs above) really detects the real page -		// size for the TLB. Somebody should check it.... - -		// Now we read the ext. CPUID level 0x80000006 -        __asm -		{ -			mov eax, 0x80000006 -			cpuid -			mov eaxreg, eax -			mov ebxreg, ebx -			mov ecxreg, ecx -		} +		char cpu_vendor[0x20]; +		len = sizeof(cpu_vendor); +		memset(cpu_vendor, 0, len); +		sysctlbyname("machdep.cpu.vendor", (void*)cpu_vendor, &len, NULL, 0); +		cpu_vendor[0x1f] = 0; +		setInfo(eVendor, cpu_vendor); + +		setInfo(eStepping, getSysctlInt("machdep.cpu.stepping")); +		setInfo(eModel, getSysctlInt("machdep.cpu.model")); +		int family = getSysctlInt("machdep.cpu.family"); +		int ext_family = getSysctlInt("machdep.cpu.extfamily"); +		setInfo(eFamily, family); +		setInfo(eExtendedFamily, ext_family); +		setInfo(eFamilyName, compute_CPUFamilyName(cpu_vendor, family, ext_family)); +		setInfo(eExtendedModel, getSysctlInt("machdep.cpu.extmodel")); +		setInfo(eBrandID, getSysctlInt("machdep.cpu.brand")); +		setInfo(eType, 0); // ? where to find this? + +		//setConfig(eCLFLUSHCacheLineSize, ((cpu_info[1] >> 8) & 0xff) * 8); +		//setConfig(eAPICPhysicalID, (cpu_info[1] >> 24) & 0xff); +		setConfig(eCacheLineSize, getSysctlInt("machdep.cpu.cache.linesize")); +		setConfig(eL2Associativity, getSysctlInt("machdep.cpu.cache.L2_associativity")); +		setConfig(eCacheSizeK, getSysctlInt("machdep.cpu.cache.size")); +		 +		uint64_t feature_info = getSysctlInt64("machdep.cpu.feature_bits"); +		S32 *feature_infos = (S32*)(&feature_info); +		 +		setConfig(eFeatureBits, feature_infos[0]); -		// We only mask the unified L2 cache masks (never heard of an -		// L2 cache that is divided in data and code parts) -		if (((ecxreg >> 12) & 0xF) > 0) +		for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)  		{ -			CPUInfo._L2.bPresent = true; -			snprintf(CPUInfo._L2.strSize, sizeof(CPUInfo._L2.strSize), "%d KB", ecxreg >> 16);		/* Flawfinder: ignore */ -			switch ((ecxreg >> 12) & 0xF) +			if(feature_info & bit)  			{ -				case 1: -					CPUInfo._L2.uiAssociativeWays = 1; -					break; -				case 2: -					CPUInfo._L2.uiAssociativeWays = 2; -					break; -				case 4: -					CPUInfo._L2.uiAssociativeWays = 4; -					break; -				case 6: -					CPUInfo._L2.uiAssociativeWays = 8; -					break; -				case 8: -					CPUInfo._L2.uiAssociativeWays = 16; -					break; -				case 0xF: -					CPUInfo._L2.uiAssociativeWays = (unsigned int) -1; -					break; -				default: -					CPUInfo._L2.uiAssociativeWays = 0; -					break; +				setExtension(cpu_feature_names[index]);  			} -			CPUInfo._L2.uiLineSize = ecxreg & 0xFF;  		} -	} -	else -	{ -		// If we could not detect the ext. CPUID level 0x80000006 we -		// try to read the standard processor configuration. -		GetStandardProcessorConfiguration(); -	} -	// After reading we translate the configuration to strings -	TranslateProcessorConfiguration(); - -	// And finally exit -	return true; -#else -	return FALSE; -#endif -} - -// bool CProcessor::AnalyzeUnknownProcessor() -// ========================================== -// Private class function to analyze an unknown (No Intel or AMD) processor -/////////////////////////////////////////////////////////////////////////// -bool CProcessor::AnalyzeUnknownProcessor() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg; - -	// We check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return false; - -	// First of all we read the standard CPUID level 0x00000001 -	// This level should be available on every x86-processor clone -	__asm -	{ -        mov eax, 1 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -	} -	// Then we mask the processor model, family, type and stepping -	CPUInfo.uiStepping = eaxreg & 0xF; -	CPUInfo.uiModel    = (eaxreg >> 4) & 0xF; -	CPUInfo.uiFamily   = (eaxreg >> 8) & 0xF; -	CPUInfo.uiType     = (eaxreg >> 12) & 0x3; - -	// To have complete information we also mask the brand id -	CPUInfo.uiBrandID  = ebxreg & 0xF; - -	// Then we get the standard processor extensions -	GetStandardProcessorExtensions(); - -	// Now we mark everything we do not know as unknown -	strcpy(strCPUName, "Unknown");		/*Flawfinder: ignore*/ - -	strcpy(CPUInfo._Data.strTLB, "Unknown");	/*Flawfinder: ignore*/ -	strcpy(CPUInfo._Instruction.strTLB, "Unknown");		/*Flawfinder: ignore*/ -	 -	strcpy(CPUInfo._Trace.strCache, "Unknown");		/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L1.Data.strCache, "Unknown");		/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L1.Instruction.strCache, "Unknown");	/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L2.strCache, "Unknown");		/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L3.strCache, "Unknown");		/*Flawfinder: ignore*/ - -	strcpy(CPUInfo.strProcessorSerial, "Unknown / Not supported");	/*Flawfinder: ignore*/ - -	// For the family, model and brand id we can only print the numeric value -	snprintf(CPUInfo.strBrandID, sizeof(CPUInfo.strBrandID), "Brand-ID number %d", CPUInfo.uiBrandID);		/* Flawfinder: ignore */ -	snprintf(CPUInfo.strFamily, sizeof(CPUInfo.strFamily), "Family number %d", CPUInfo.uiFamily);		/* Flawfinder: ignore */ -	snprintf(CPUInfo.strModel, sizeof(CPUInfo.strModel), "Model number %d", CPUInfo.uiModel);		/* Flawfinder: ignore */ - -	// And thats it -	return true; -#else -	return FALSE; -#endif -} - -// bool CProcessor::CheckCPUIDPresence() -// ===================================== -// This function checks if the CPUID command is available on the current -// processor -//////////////////////////////////////////////////////////////////////// -bool CProcessor::CheckCPUIDPresence() -{ -#if LL_WINDOWS -	unsigned long BitChanged; -	 -	// We've to check if we can toggle the flag register bit 21 -	// If we can't the processor does not support the CPUID command -	__asm -	{ -		pushfd -		pop eax -		mov ebx, eax -		xor eax, 0x00200000  -		push eax -		popfd -		pushfd -		pop eax -		xor eax,ebx  -		mov BitChanged, eax -	} -	return ((BitChanged) ? true : false); -#else -	return FALSE; -#endif -} +		// *NOTE:Mani - I didn't find any docs that assure me that machdep.cpu.feature_bits will always be +		// The feature bits I think it is. Here's a test: +#ifndef LL_RELEASE_FOR_DOWNLOAD +	#if defined(__i386__) && defined(__PIC__) +			/* %ebx may be the PIC register.  */ +		#define __cpuid(level, a, b, c, d)			\ +		__asm__ ("xchgl\t%%ebx, %1\n\t"			\ +				"cpuid\n\t"					\ +				"xchgl\t%%ebx, %1\n\t"			\ +				: "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\ +				: "0" (level)) +	#else +		#define __cpuid(level, a, b, c, d)			\ +		__asm__ ("cpuid\n\t"					\ +				 : "=a" (a), "=b" (b), "=c" (c), "=d" (d)	\ +				 : "0" (level)) +	#endif + +		unsigned int eax, ebx, ecx, edx; +		__cpuid(0x1, eax, ebx, ecx, edx); +		if(feature_infos[0] != (S32)edx) +		{ +			llerrs << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << llendl; +		}  +#endif // LL_RELEASE_FOR_DOWNLOAD 	 -// void CProcessor::DecodeProcessorConfiguration(unsigned int cfg) -// =============================================================== -// This function (or switch ?!) just translates a one-byte processor configuration -// byte to understandable values -////////////////////////////////////////////////////////////////////////////////// -void CProcessor::DecodeProcessorConfiguration(unsigned int cfg) -{ -	// First we ensure that there's only one single byte -	cfg &= 0xFF; -	// Then we do a big switch -	switch(cfg) -	{ -		case 0:			// cfg = 0:  Unused -			break; -		case 0x1:		// cfg = 0x1:  code TLB present, 4 KB pages, 4 ways, 32 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB");	/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = 4; -			CPUInfo._Instruction.uiEntries = 32; -			break; -		case 0x2:		// cfg = 0x2:  code TLB present, 4 MB pages, fully associative, 2 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 MB");	/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = 4; -			CPUInfo._Instruction.uiEntries = 2; -			break; -		case 0x3:		// cfg = 0x3:  data TLB present, 4 KB pages, 4 ways, 64 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB");		/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = 4; -			CPUInfo._Data.uiEntries = 64; -			break; -		case 0x4:		// cfg = 0x4:  data TLB present, 4 MB pages, 4 ways, 8 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 MB");	/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = 4; -			CPUInfo._Data.uiEntries = 8; -			break; -		case 0x6:		// cfg = 0x6:  code L1 cache present, 8 KB, 4 ways, 32 byte lines -			CPUInfo._L1.Instruction.bPresent = true; -			strcpy(CPUInfo._L1.Instruction.strSize, "8 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Instruction.uiAssociativeWays = 4; -			CPUInfo._L1.Instruction.uiLineSize = 32; -			break; -		case 0x8:		// cfg = 0x8:  code L1 cache present, 16 KB, 4 ways, 32 byte lines -			CPUInfo._L1.Instruction.bPresent = true; -			strcpy(CPUInfo._L1.Instruction.strSize, "16 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Instruction.uiAssociativeWays = 4; -			CPUInfo._L1.Instruction.uiLineSize = 32; -			break; -		case 0xA:		// cfg = 0xA:  data L1 cache present, 8 KB, 2 ways, 32 byte lines -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "8 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Data.uiAssociativeWays = 2; -			CPUInfo._L1.Data.uiLineSize = 32; -			break; -		case 0xC:		// cfg = 0xC:  data L1 cache present, 16 KB, 4 ways, 32 byte lines -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "16 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 32; -			break; -		case 0x22:		// cfg = 0x22:  code and data L3 cache present, 512 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "512 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 4; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x23:		// cfg = 0x23:  code and data L3 cache present, 1024 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "1024 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 8; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x25:		// cfg = 0x25:  code and data L3 cache present, 2048 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "2048 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 8; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x29:		// cfg = 0x29:  code and data L3 cache present, 4096 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "4096 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 8; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x40:		// cfg = 0x40:  no integrated L2 cache (P6 core) or L3 cache (P4 core) -			break; -		case 0x41:		// cfg = 0x41:  code and data L2 cache present, 128 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "128 KB");		/*Flawfinder: ignore*/ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x42:		// cfg = 0x42:  code and data L2 cache present, 256 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "256 KB");		/*Flawfinder: ignore*/ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x43:		// cfg = 0x43:  code and data L2 cache present, 512 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "512 KB");		/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x44:		// cfg = 0x44:  code and data L2 cache present, 1024 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "1 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x45:		// cfg = 0x45:  code and data L2 cache present, 2048 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "2 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x50:		// cfg = 0x50:  code TLB present, 4 KB / 4 MB / 2 MB pages, fully associative, 64 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Instruction.uiEntries = 64; -			break; -		case 0x51:		// cfg = 0x51:  code TLB present, 4 KB / 4 MB / 2 MB pages, fully associative, 128 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Instruction.uiEntries = 128; -			break; -		case 0x52:		// cfg = 0x52:  code TLB present, 4 KB / 4 MB / 2 MB pages, fully associative, 256 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Instruction.uiEntries = 256; -			break; -		case 0x5B:		// cfg = 0x5B:  data TLB present, 4 KB / 4 MB pages, fully associative, 64 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Data.uiEntries = 64; -			break; -		case 0x5C:		// cfg = 0x5C:  data TLB present, 4 KB / 4 MB pages, fully associative, 128 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Data.uiEntries = 128; -			break; -		case 0x5d:		// cfg = 0x5D:  data TLB present, 4 KB / 4 MB pages, fully associative, 256 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Data.uiEntries = 256; -			break; -		case 0x66:		// cfg = 0x66:  data L1 cache present, 8 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "8 KB");	/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 64; -			break; -		case 0x67:		// cfg = 0x67:  data L1 cache present, 16 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "16 KB");	/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 64; -			break; -		case 0x68:		// cfg = 0x68:  data L1 cache present, 32 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "32 KB");	/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 64; -			break; -		case 0x70:		// cfg = 0x70:  trace L1 cache present, 12 KuOPs, 4 ways -			CPUInfo._Trace.bPresent = true; -			strcpy(CPUInfo._Trace.strSize, "12 K-micro-ops");	/* Flawfinder: ignore */ -			CPUInfo._Trace.uiAssociativeWays = 4; -			break; -		case 0x71:		// cfg = 0x71:  trace L1 cache present, 16 KuOPs, 4 ways -			CPUInfo._Trace.bPresent = true; -			strcpy(CPUInfo._Trace.strSize, "16 K-micro-ops");	/* Flawfinder: ignore */ -			CPUInfo._Trace.uiAssociativeWays = 4; -			break; -		case 0x72:		// cfg = 0x72:  trace L1 cache present, 32 KuOPs, 4 ways -			CPUInfo._Trace.bPresent = true; -			strcpy(CPUInfo._Trace.strSize, "32 K-micro-ops");	/* Flawfinder: ignore */ -			CPUInfo._Trace.uiAssociativeWays = 4; -			break; -		case 0x79:		// cfg = 0x79:  code and data L2 cache present, 128 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "128 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x7A:		// cfg = 0x7A:  code and data L2 cache present, 256 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "256 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x7B:		// cfg = 0x7B:  code and data L2 cache present, 512 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "512 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x7C:		// cfg = 0x7C:  code and data L2 cache present, 1024 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "1 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x81:		// cfg = 0x81:  code and data L2 cache present, 128 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "128 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x82:		// cfg = 0x82:  code and data L2 cache present, 256 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "256 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x83:		// cfg = 0x83:  code and data L2 cache present, 512 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "512 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x84:		// cfg = 0x84:  code and data L2 cache present, 1024 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "1 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x85:		// cfg = 0x85:  code and data L2 cache present, 2048 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "2 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; +		uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits"); +		S32 *ext_feature_infos = (S32*)(&ext_feature_info); +		setConfig(eExtFeatureBits, ext_feature_infos[0]);  	} -} +}; -FORCEINLINE static char *TranslateAssociativeWays(unsigned int uiWays, char *buf) -{ -	// We define 0xFFFFFFFF (= -1) as fully associative -    if (uiWays == ((unsigned int) -1)) -		strcpy(buf, "fully associative");	/* Flawfinder: ignore */ -	else -	{ -		if (uiWays == 1)			// A one way associative cache is just direct mapped -			strcpy(buf, "direct mapped");	/* Flawfinder: ignore */ -		else if (uiWays == 0)		// This should not happen... -			strcpy(buf, "unknown associative ways");	/* Flawfinder: ignore */ -		else						// The x-way associative cache -			sprintf(buf, "%d ways associative", uiWays);	/* Flawfinder: ignore */ -	} -	// To ease the function use we return the buffer -	return buf; -} -FORCEINLINE static void TranslateTLB(ProcessorTLB *tlb) -{ -	char buf[64];	/* Flawfinder: ignore */ +#elif LL_LINUX +const char CPUINFO_FILE[] = "/proc/cpuinfo"; -	// We just check if the TLB is present -	if (tlb->bPresent) -        snprintf(tlb->strTLB,sizeof(tlb->strTLB), "%s page size, %s, %d entries", tlb->strPageSize, TranslateAssociativeWays(tlb->uiAssociativeWays, buf), tlb->uiEntries);	/* Flawfinder: ignore */ -	else -        strcpy(tlb->strTLB, "Not present");	/* Flawfinder: ignore */ -} -FORCEINLINE static void TranslateCache(ProcessorCache *cache) +class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl  { -	char buf[64];	/* Flawfinder: ignore */ - -	// We just check if the cache is present -    if (cache->bPresent) -	{ -		// If present we construct the string -		snprintf(cache->strCache, sizeof(cache->strCache), "%s cache size, %s, %d bytes line size", cache->strSize, TranslateAssociativeWays(cache->uiAssociativeWays, buf), cache->uiLineSize);	/* Flawfinder: ignore */ -		if (cache->bSectored) -			strncat(cache->strCache, ", sectored", sizeof(cache->strCache)-strlen(cache->strCache)-1);	/* Flawfinder: ignore */ -	} -	else +public: +	LLProcessorInfoLinuxImpl()   	{ -		// Else we just say "Not present" -		strcpy(cache->strCache, "Not present");	/* Flawfinder: ignore */ +		get_proc_cpuinfo();  	} -} - -// void CProcessor::TranslateProcessorConfiguration() -// ================================================== -// Private class function to translate the processor configuration values -// to strings -///////////////////////////////////////////////////////////////////////// -void CProcessor::TranslateProcessorConfiguration() -{ -	// We just call the small functions defined above -	TranslateTLB(&CPUInfo._Data); -	TranslateTLB(&CPUInfo._Instruction); -	TranslateCache(&CPUInfo._Trace); +	virtual ~LLProcessorInfoLinuxImpl() {} +private: -	TranslateCache(&CPUInfo._L1.Instruction); -	TranslateCache(&CPUInfo._L1.Data); -	TranslateCache(&CPUInfo._L2); -	TranslateCache(&CPUInfo._L3); -} - -// void CProcessor::GetStandardProcessorConfiguration() -// ==================================================== -// Private class function to read the standard processor configuration -////////////////////////////////////////////////////////////////////// -void CProcessor::GetStandardProcessorConfiguration() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, ecxreg, edxreg; - -	// We check if the CPUID function is available -	if (!CheckCPUIDPresence()) -		return; - -	// First we check if the processor supports the standard -	// CPUID level 0x00000002 -	if (CPUInfo.MaxSupportedLevel >= 2) +	void get_proc_cpuinfo()  	{ -		// Now we go read the std. CPUID level 0x00000002 the first time -		unsigned long count, num = 255; -		for (count = 0; count < num; count++) +		std::map< std::string, std::string > cpuinfo; +		LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb"); +		if(cpuinfo_fp)  		{ -			__asm -			{ -				mov eax, 2 -				cpuid -				mov eaxreg, eax -				mov ebxreg, ebx -				mov ecxreg, ecx -				mov edxreg, edx -			} -			// We have to repeat this reading for 'num' times -			num = eaxreg & 0xFF; - -			// Then we call the big decode switch function -			DecodeProcessorConfiguration(eaxreg >> 8); -			DecodeProcessorConfiguration(eaxreg >> 16); -			DecodeProcessorConfiguration(eaxreg >> 24); - -			// If ebx contains additional data we also decode it -			if ((ebxreg & 0x80000000) == 0) +			char line[MAX_STRING]; +			memset(line, 0, MAX_STRING); +			while(fgets(line, MAX_STRING, cpuinfo_fp))  			{ -				DecodeProcessorConfiguration(ebxreg); -				DecodeProcessorConfiguration(ebxreg >> 8); -				DecodeProcessorConfiguration(ebxreg >> 16); -				DecodeProcessorConfiguration(ebxreg >> 24); -			} -			// And also the ecx register -			if ((ecxreg & 0x80000000) == 0) -			{ -				DecodeProcessorConfiguration(ecxreg); -				DecodeProcessorConfiguration(ecxreg >> 8); -				DecodeProcessorConfiguration(ecxreg >> 16); -				DecodeProcessorConfiguration(ecxreg >> 24); -			} -			// At last the edx processor register -			if ((edxreg & 0x80000000) == 0) -			{ -				DecodeProcessorConfiguration(edxreg); -				DecodeProcessorConfiguration(edxreg >> 8); -				DecodeProcessorConfiguration(edxreg >> 16); -				DecodeProcessorConfiguration(edxreg >> 24); +				// /proc/cpuinfo on Linux looks like: +				// name\t*: value\n +				char* tabspot = strchr( line, '\t' ); +				if (tabspot == NULL) +					continue; +				char* colspot = strchr( tabspot, ':' ); +				if (colspot == NULL) +					continue; +				char* spacespot = strchr( colspot, ' ' ); +				if (spacespot == NULL) +					continue; +				char* nlspot = strchr( line, '\n' ); +				if (nlspot == NULL) +					nlspot = line + strlen( line ); // Fallback to terminating NUL +				std::string linename( line, tabspot ); +				std::string llinename(linename); +				LLStringUtil::toLower(llinename); +				std::string lineval( spacespot + 1, nlspot ); +				cpuinfo[ llinename ] = lineval;  			} +			fclose(cpuinfo_fp); +		} +# if LL_X86 + +// *NOTE:Mani - eww, macros! srry. +#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \ +		if (!cpuinfo[cpuinfo_id].empty()) \ +		{ setInfo(llpi_id, cpuinfo[cpuinfo_id]);} + +#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \ +		{\ +			S32 result; \ +			if (!cpuinfo[cpuinfo_id].empty() \ +				&& LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result))	\ +		    { setInfo(llpi_id, result);} \ +		} +		 +		F64 mhz; +		if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) +			&& 200.0 < mhz && mhz < 10000.0) +		{ +		    setInfo(eFrequency,(F64)(mhz));  		} -	} -#endif -} -// void CProcessor::GetStandardProcessorExtensions() -// ================================================= -// Private class function to read the standard processor extensions -/////////////////////////////////////////////////////////////////// -void CProcessor::GetStandardProcessorExtensions() -{ -#if LL_WINDOWS -	unsigned long ebxreg, edxreg; +		LLPI_SET_INFO_STRING(eBrandName, "model name");		 +		LLPI_SET_INFO_STRING(eVendor, "vendor_id"); -	// We check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return; -	// We just get the standard CPUID level 0x00000001 which should be -	// available on every x86 processor -	__asm -	{ -		mov eax, 1 -		cpuid -		mov ebxreg, ebx -		mov edxreg, edx -	} -     -	// Then we mask some bits -	CPUInfo._Ext.FPU_FloatingPointUnit							= CheckBit(edxreg, 0); -	CPUInfo._Ext.VME_Virtual8086ModeEnhancements				= CheckBit(edxreg, 1); -	CPUInfo._Ext.DE_DebuggingExtensions							= CheckBit(edxreg, 2); -	CPUInfo._Ext.PSE_PageSizeExtensions							= CheckBit(edxreg, 3); -	CPUInfo._Ext.TSC_TimeStampCounter							= CheckBit(edxreg, 4); -	CPUInfo._Ext.MSR_ModelSpecificRegisters						= CheckBit(edxreg, 5); -	CPUInfo._Ext.PAE_PhysicalAddressExtension					= CheckBit(edxreg, 6); -	CPUInfo._Ext.MCE_MachineCheckException						= CheckBit(edxreg, 7); -	CPUInfo._Ext.CX8_COMPXCHG8B_Instruction						= CheckBit(edxreg, 8); -	CPUInfo._Ext.APIC_AdvancedProgrammableInterruptController	= CheckBit(edxreg, 9); -	CPUInfo._Ext.APIC_ID = (ebxreg >> 24) & 0xFF; -	CPUInfo._Ext.SEP_FastSystemCall								= CheckBit(edxreg, 11); -	CPUInfo._Ext.MTRR_MemoryTypeRangeRegisters					= CheckBit(edxreg, 12); -	CPUInfo._Ext.PGE_PTE_GlobalFlag								= CheckBit(edxreg, 13); -	CPUInfo._Ext.MCA_MachineCheckArchitecture					= CheckBit(edxreg, 14); -	CPUInfo._Ext.CMOV_ConditionalMoveAndCompareInstructions		= CheckBit(edxreg, 15); -	CPUInfo._Ext.FGPAT_PageAttributeTable						= CheckBit(edxreg, 16); -	CPUInfo._Ext.PSE36_36bitPageSizeExtension					= CheckBit(edxreg, 17); -	CPUInfo._Ext.PN_ProcessorSerialNumber						= CheckBit(edxreg, 18); -	CPUInfo._Ext.CLFSH_CFLUSH_Instruction						= CheckBit(edxreg, 19); -	CPUInfo._Ext.CLFLUSH_InstructionCacheLineSize = (ebxreg >> 8) & 0xFF; -	CPUInfo._Ext.DS_DebugStore									= CheckBit(edxreg, 21); -	CPUInfo._Ext.ACPI_ThermalMonitorAndClockControl				= CheckBit(edxreg, 22); -	CPUInfo._Ext.MMX_MultimediaExtensions						= CheckBit(edxreg, 23); -	CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore	= CheckBit(edxreg, 24); -	CPUInfo._Ext.SSE_StreamingSIMD_Extensions					= CheckBit(edxreg, 25); -	CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions					= CheckBit(edxreg, 26); -	CPUInfo._Ext.Altivec_Extensions = false; -	CPUInfo._Ext.SS_SelfSnoop									= CheckBit(edxreg, 27); -	CPUInfo._Ext.HT_HyperThreading								= CheckBit(edxreg, 28); -	CPUInfo._Ext.HT_HyterThreadingSiblings = (ebxreg >> 16) & 0xFF; -	CPUInfo._Ext.TM_ThermalMonitor								= CheckBit(edxreg, 29); -	CPUInfo._Ext.IA64_Intel64BitArchitecture					= CheckBit(edxreg, 30); -#endif -} +		LLPI_SET_INFO_INT(eStepping, "stepping"); +		LLPI_SET_INFO_INT(eModel, "model"); -// const ProcessorInfo *CProcessor::GetCPUInfo() -// ============================================= -// Calls all the other detection function to create an detailed -// processor information -/////////////////////////////////////////////////////////////// -const ProcessorInfo *CProcessor::GetCPUInfo() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, ecxreg, edxreg; +		 +		S32 family;							  +		if (!cpuinfo["cpu family"].empty()  +			&& LLStringUtil::convertToS32(cpuinfo["cpu family"], family))	 +		{  +			setInfo(eFamily, family); +		} -	// First of all we check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return NULL; +		setInfo(eFamilyName, compute_CPUFamilyName(cpuinfo["vendor_id"].c_str(), family)); -	// We read the standard CPUID level 0x00000000 which should -	// be available on every x86 processor -	__asm -	{ -		mov eax, 0 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -		mov edxreg, edx -		mov ecxreg, ecx -	} -	// Then we connect the single register values to the vendor string -	*((unsigned long *) CPUInfo.strVendor) = ebxreg; -	*((unsigned long *) (CPUInfo.strVendor+4)) = edxreg; -	*((unsigned long *) (CPUInfo.strVendor+8)) = ecxreg; -	// Null terminate for string comparisons below. -	CPUInfo.strVendor[12] = 0; - -	// We can also read the max. supported standard CPUID level -	CPUInfo.MaxSupportedLevel = eaxreg & 0xFFFF; - -	// Then we read the ext. CPUID level 0x80000000 -	__asm -	{ -        mov eax, 0x80000000 -		cpuid -		mov eaxreg, eax -	} -	// ...to check the max. supportted extended CPUID level -	CPUInfo.MaxSupportedExtendedLevel = eaxreg; - -	// Then we switch to the specific processor vendors -	// See http://www.sandpile.org/ia32/cpuid.htm -	if (!strcmp(CPUInfo.strVendor, "GenuineIntel")) -	{ -		AnalyzeIntelProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "AuthenticAMD")) -	{ -		AnalyzeAMDProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "UMC UMC UMC")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "CyrixInstead")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "NexGenDriven")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "CentaurHauls")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "RiseRiseRise")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "SiS SiS SiS")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "GenuineTMx86")) -	{ -		// Transmeta -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "Geode by NSC")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else -	{ -		AnalyzeUnknownProcessor(); -	} -#endif -	// After all we return the class CPUInfo member var -	return (&CPUInfo); -} +		// setInfo(eExtendedModel, getSysctlInt("machdep.cpu.extmodel")); +		// setInfo(eBrandID, getSysctlInt("machdep.cpu.brand")); +		// setInfo(eType, 0); // ? where to find this? -#elif LL_SOLARIS -#include <kstat.h> - -#if defined(__i386) -#include <sys/auxv.h> -#endif - -// ====================== -// Class constructor: -///////////////////////// -CProcessor::CProcessor() -{ -	uqwFrequency = 0; -	strCPUName[0] = 0; -	memset(&CPUInfo, 0, sizeof(CPUInfo)); -} - -// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) -// ========================================================================= -// Function to query the current CPU frequency -//////////////////////////////////////////////////////////////////////////// -F64 CProcessor::GetCPUFrequency(unsigned int /*uiMeasureMSecs*/) -{ -	if(uqwFrequency == 0){ -		GetCPUInfo(); -	} - -	return uqwFrequency; -} - -// const ProcessorInfo *CProcessor::GetCPUInfo() -// ============================================= -// Calls all the other detection function to create an detailed -// processor information -/////////////////////////////////////////////////////////////// -const ProcessorInfo *CProcessor::GetCPUInfo() -{ -					// In Solaris the CPU info is in the kstats -					// try "psrinfo" or "kstat cpu_info" to see all -					// that's available -	int ncpus=0, i;  -	kstat_ctl_t	*kc; -	kstat_t 	*ks; -	kstat_named_t   *ksinfo, *ksi; -	kstat_t 	*CPU_stats_list; - -	kc = kstat_open(); - -	if((int)kc == -1){ -		llwarns << "kstat_open(0 failed!" << llendl; -		return (&CPUInfo); -	} - -	for (ks = kc->kc_chain; ks != NULL; ks = ks->ks_next) { -		if (strncmp(ks->ks_module, "cpu_info", 8) == 0 && -			strncmp(ks->ks_name, "cpu_info", 8) == 0) -			ncpus++; -	} -	 -	if(ncpus < 1){ -		llwarns << "No cpus found in kstats!" << llendl; -		return (&CPUInfo); -	} - -	for (ks = kc->kc_chain; ks; ks = ks->ks_next) { -		if (strncmp(ks->ks_module, "cpu_info", 8) == 0  -		&&  strncmp(ks->ks_name, "cpu_info", 8) == 0  -		&&  kstat_read(kc, ks, NULL) != -1){      -			CPU_stats_list = ks;	// only looking at the first CPU -			 -			break; -		} -	} - -	if(ncpus > 1) -        	snprintf(strCPUName, sizeof(strCPUName), "%d x ", ncpus);  - -	kstat_read(kc, CPU_stats_list, NULL); -	ksinfo = (kstat_named_t *)CPU_stats_list->ks_data; -	for(i=0; i < (int)(CPU_stats_list->ks_ndata); ++i){ // Walk the kstats for this cpu gathering what we need -		ksi = ksinfo++; -		if(!strcmp(ksi->name, "brand")){ -			strncat(strCPUName, (char *)KSTAT_NAMED_STR_PTR(ksi), -				sizeof(strCPUName)-strlen(strCPUName)-1); -			strncat(CPUInfo.strFamily, (char *)KSTAT_NAMED_STR_PTR(ksi), -				sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1); -			strncpy(CPUInfo.strBrandID, strCPUName,sizeof(CPUInfo.strBrandID)-1); -			CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; -			// DEBUG llinfos << "CPU brand: " << strCPUName << llendl; -			continue; -		} +		//setConfig(eCLFLUSHCacheLineSize, ((cpu_info[1] >> 8) & 0xff) * 8); +		//setConfig(eAPICPhysicalID, (cpu_info[1] >> 24) & 0xff); +		//setConfig(eCacheLineSize, getSysctlInt("machdep.cpu.cache.linesize")); +		//setConfig(eL2Associativity, getSysctlInt("machdep.cpu.cache.L2_associativity")); +		//setConfig(eCacheSizeK, getSysctlInt("machdep.cpu.cache.size")); +		 +		// Read extensions +		std::string flags = " " + cpuinfo["flags"] + " "; +		LLStringUtil::toLower(flags); -		if(!strcmp(ksi->name, "clock_MHz")){ -#if defined(__sparc) -			llinfos << "Raw kstat clock rate is: " << ksi->value.l << llendl; -			uqwFrequency = (F64)(ksi->value.l * 1000000); -#else -			uqwFrequency = (F64)(ksi->value.i64 * 1000000); -#endif -			//DEBUG llinfos << "CPU frequency: " << uqwFrequency << llendl; -			continue; +		if( flags.find( " sse " ) != std::string::npos ) +		{ +			setExtension(cpu_feature_names[eSSE_Ext]);   		} -#if defined(__i386) -		if(!strcmp(ksi->name, "vendor_id")){ -			strncpy(CPUInfo.strVendor, (char *)KSTAT_NAMED_STR_PTR(ksi), sizeof(CPUInfo.strVendor)-1); -			// DEBUG llinfos << "CPU vendor: " << CPUInfo.strVendor << llendl; -			continue; +		if( flags.find( " sse2 " ) != std::string::npos ) +		{ +			setExtension(cpu_feature_names[eSSE2_Ext]);  		} -#endif -	} - -	kstat_close(kc); - -#if defined(__sparc)		// SPARC does not define a vendor string in kstat -	strncpy(CPUInfo.strVendor, "Sun Microsystems, Inc.", sizeof(CPUInfo.strVendor)-1); -#endif - -	// DEBUG llinfo << "The system has " << ncpus << " CPUs with a clock rate of " <<  uqwFrequency << "MHz." << llendl; -	 -#if defined (__i386)  //  we really don't care about the CPU extensions on SPARC but on x86... - -	// Now get cpu extensions - -	uint_t ui; - -	(void) getisax(&ui, 1); -	if(ui & AV_386_FPU) -		CPUInfo._Ext.FPU_FloatingPointUnit = true; -	if(ui & AV_386_CX8) -		CPUInfo._Ext.CX8_COMPXCHG8B_Instruction = true; -	if(ui & AV_386_MMX) -		CPUInfo._Ext.MMX_MultimediaExtensions = true; -	if(ui & AV_386_AMD_MMX) -		CPUInfo._Ext.MMX_MultimediaExtensions = true; -	if(ui & AV_386_FXSR) -		CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore = true; -	if(ui & AV_386_SSE) -		 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = true; -	if(ui & AV_386_SSE2) -		CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = true; -/* Left these here since they may get used later -	if(ui & AV_386_SSE3) -		CPUInfo._Ext.... = true; -	if(ui & AV_386_AMD_3DNow) -		CPUInfo._Ext.... = true; -	if(ui & AV_386_AMD_3DNowx) -		CPUInfo._Ext.... = true; -*/ -#endif -	return (&CPUInfo); -} - -#else -// LL_DARWIN - -#include <mach/machine.h> -#include <sys/sysctl.h> - -static char *TranslateAssociativeWays(unsigned int uiWays, char *buf) -{ -	// We define 0xFFFFFFFF (= -1) as fully associative -    if (uiWays == ((unsigned int) -1)) -		strcpy(buf, "fully associative");	/* Flawfinder: ignore */ -	else -	{ -		if (uiWays == 1)			// A one way associative cache is just direct mapped -			strcpy(buf, "direct mapped");	/* Flawfinder: ignore */ -		else if (uiWays == 0)		// This should not happen... -			strcpy(buf, "unknown associative ways");	/* Flawfinder: ignore */ -		else						// The x-way associative cache -			sprintf(buf, "%d ways associative", uiWays);	/* Flawfinder: ignore */ +# endif // LL_X86  	} -	// To ease the function use we return the buffer -	return buf; -} -static void TranslateTLB(ProcessorTLB *tlb) -{ -	char buf[64];	/* Flawfinder: ignore */ - -	// We just check if the TLB is present -	if (tlb->bPresent) -        snprintf(tlb->strTLB, sizeof(tlb->strTLB), "%s page size, %s, %d entries", tlb->strPageSize, TranslateAssociativeWays(tlb->uiAssociativeWays, buf), tlb->uiEntries);	/* Flawfinder: ignore */ -	else -        strcpy(tlb->strTLB, "Not present");	/* Flawfinder: ignore */ -} -static void TranslateCache(ProcessorCache *cache) -{ -	char buf[64];	/* Flawfinder: ignore */ -	// We just check if the cache is present -    if (cache->bPresent) +	std::string getCPUFeatureDescription() const   	{ -		// If present we construct the string -		snprintf(cache->strCache,sizeof(cache->strCache), "%s cache size, %s, %d bytes line size", cache->strSize, TranslateAssociativeWays(cache->uiAssociativeWays, buf), cache->uiLineSize);	/* Flawfinder: ignore */ -		if (cache->bSectored) -			strncat(cache->strCache, ", sectored", sizeof(cache->strCache)-strlen(cache->strCache)-1);	/* Flawfinder: ignore */ -	} -	else -	{ -		// Else we just say "Not present" -		strcpy(cache->strCache, "Not present");	/* Flawfinder: ignore */ -	} -} - -// void CProcessor::TranslateProcessorConfiguration() -// ================================================== -// Private class function to translate the processor configuration values -// to strings -///////////////////////////////////////////////////////////////////////// -void CProcessor::TranslateProcessorConfiguration() -{ -	// We just call the small functions defined above -	TranslateTLB(&CPUInfo._Data); -	TranslateTLB(&CPUInfo._Instruction); - -	TranslateCache(&CPUInfo._Trace); +		std::ostringstream s; -	TranslateCache(&CPUInfo._L1.Instruction); -	TranslateCache(&CPUInfo._L1.Data); -	TranslateCache(&CPUInfo._L2); -	TranslateCache(&CPUInfo._L3); -} - -// CProcessor::CProcessor -// ====================== -// Class constructor: -///////////////////////// -CProcessor::CProcessor() -{ -	uqwFrequency = 0; -	strCPUName[0] = 0; -	memset(&CPUInfo, 0, sizeof(CPUInfo)); -} - -// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) -// ========================================================================= -// Function to query the current CPU frequency -//////////////////////////////////////////////////////////////////////////// -F64 CProcessor::GetCPUFrequency(unsigned int /*uiMeasureMSecs*/) -{ -	U64 frequency = 0; -	size_t len = sizeof(frequency); -	 -	if(sysctlbyname("hw.cpufrequency", &frequency, &len, NULL, 0) == 0) -	{ -		uqwFrequency = (F64)frequency; -	} -	 -	return uqwFrequency; -} - -static bool hasFeature(const char *name) -{ -	bool result = false; -	int val = 0; -	size_t len = sizeof(val); -	 -	if(sysctlbyname(name, &val, &len, NULL, 0) == 0) -	{ -		if(val != 0) -			result = true; -	} -	 -	return result; -} - -// const ProcessorInfo *CProcessor::GetCPUInfo() -// ============================================= -// Calls all the other detection function to create an detailed -// processor information -/////////////////////////////////////////////////////////////// -const ProcessorInfo *CProcessor::GetCPUInfo() -{ -	int pagesize = 0; -	int cachelinesize = 0; -	int l1icachesize = 0; -	int l1dcachesize = 0; -	int l2settings = 0; -	int l2cachesize = 0; -	int l3settings = 0; -	int l3cachesize = 0; -	int ncpu = 0; -	int cpusubtype = 0; -	 -	// sysctl knows all. -	int mib[2]; -	size_t len; -	mib[0] = CTL_HW; -	 -	mib[1] = HW_PAGESIZE; -	len = sizeof(pagesize); -	sysctl(mib, 2, &pagesize, &len, NULL, 0); - -	mib[1] = HW_CACHELINE; -	len = sizeof(cachelinesize); -	sysctl(mib, 2, &cachelinesize, &len, NULL, 0); -	 -	mib[1] = HW_L1ICACHESIZE; -	len = sizeof(l1icachesize); -	sysctl(mib, 2, &l1icachesize, &len, NULL, 0); -	 -	mib[1] = HW_L1DCACHESIZE; -	len = sizeof(l1dcachesize); -	sysctl(mib, 2, &l1dcachesize, &len, NULL, 0); -	 -	mib[1] = HW_L2SETTINGS; -	len = sizeof(l2settings); -	sysctl(mib, 2, &l2settings, &len, NULL, 0); -	 -	mib[1] = HW_L2CACHESIZE; -	len = sizeof(l2cachesize); -	sysctl(mib, 2, &l2cachesize, &len, NULL, 0); -	 -	mib[1] = HW_L3SETTINGS; -	len = sizeof(l3settings); -	sysctl(mib, 2, &l3settings, &len, NULL, 0); -	 -	mib[1] = HW_L3CACHESIZE; -	len = sizeof(l3cachesize); -	sysctl(mib, 2, &l3cachesize, &len, NULL, 0); -	 -	mib[1] = HW_NCPU; -	len = sizeof(ncpu); -	sysctl(mib, 2, &ncpu, &len, NULL, 0); -	 -	sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0); -	 -	strCPUName[0] = 0; -	 -	if((ncpu == 0) || (ncpu == 1)) -	{ -		// Uhhh... -	} -	else if(ncpu == 2) -	{ -		strncat(strCPUName, "Dual ", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -	} -	else -	{ -		snprintf(strCPUName, sizeof(strCPUName), "%d x ", ncpu);	/* Flawfinder: ignore */ -	} -	 -#if __ppc__ -	switch(cpusubtype) -	{ -		case CPU_SUBTYPE_POWERPC_601://         ((cpu_subtype_t) 1) -			strncat(strCPUName, "PowerPC 601", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -			 -		break; -		case CPU_SUBTYPE_POWERPC_602://         ((cpu_subtype_t) 2) -			strncat(strCPUName, "PowerPC 602", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_603://         ((cpu_subtype_t) 3) -			strncat(strCPUName, "PowerPC 603", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_603e://        ((cpu_subtype_t) 4) -			strncat(strCPUName, "PowerPC 603e", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_603ev://       ((cpu_subtype_t) 5) -			strncat(strCPUName, "PowerPC 603ev", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_604://         ((cpu_subtype_t) 6) -			strncat(strCPUName, "PowerPC 604", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_604e://        ((cpu_subtype_t) 7) -			strncat(strCPUName, "PowerPC 604e", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_620://			((cpu_subtype_t) 8) -			strncat(strCPUName, "PowerPC 620", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_750://         ((cpu_subtype_t) 9) -			strncat(strCPUName, "PowerPC 750", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G3", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_7400://        ((cpu_subtype_t) 10) -			strncat(strCPUName, "PowerPC 7400", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G4", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_7450://        ((cpu_subtype_t) 11) -			strncat(strCPUName, "PowerPC 7450", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G4", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_970://         ((cpu_subtype_t) 100) -			strncat(strCPUName, "PowerPC 970", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G5", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; - -		default: -			strncat(strCPUName, "PowerPC (Unknown)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -		break; -	} - -	CPUInfo._Ext.EMMX_MultimediaExtensions =  -	CPUInfo._Ext.MMX_MultimediaExtensions =  -	CPUInfo._Ext.SSE_StreamingSIMD_Extensions = -	CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = false; - -	CPUInfo._Ext.Altivec_Extensions = hasFeature("hw.optional.altivec"); - -#endif - -#if __i386__ -	// MBW -- XXX -- TODO -- make this call AnalyzeIntelProcessor()? -	switch(cpusubtype) -	{ -		default: -			strncat(strCPUName, "i386 (Unknown)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -		break; -	} - -	CPUInfo._Ext.EMMX_MultimediaExtensions = hasFeature("hw.optional.mmx");  // MBW -- XXX -- this may be wrong... -	CPUInfo._Ext.MMX_MultimediaExtensions = hasFeature("hw.optional.mmx"); -	CPUInfo._Ext.SSE_StreamingSIMD_Extensions = hasFeature("hw.optional.sse"); -	CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = hasFeature("hw.optional.sse2"); -	CPUInfo._Ext.Altivec_Extensions = false; -	CPUInfo._Ext.AA64_AMD64BitArchitecture = hasFeature("hw.optional.x86_64"); - -#endif - -	// Terse CPU info uses this string... -	strncpy(CPUInfo.strBrandID, strCPUName,sizeof(CPUInfo.strBrandID)-1);	/* Flawfinder: ignore */	 -	CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; -	 -	// Fun cache config stuff... -	 -	if(l1dcachesize != 0) -	{ -		CPUInfo._L1.Data.bPresent = true; -		snprintf(CPUInfo._L1.Data.strSize, sizeof(CPUInfo._L1.Data.strSize), "%d KB", l1dcachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L1.Data.uiAssociativeWays = ???; -		CPUInfo._L1.Data.uiLineSize = cachelinesize; +		// *NOTE:Mani - This is for linux only. +		LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb"); +		if(cpuinfo) +		{ +			char line[MAX_STRING]; +			memset(line, 0, MAX_STRING); +			while(fgets(line, MAX_STRING, cpuinfo)) +			{ +				line[strlen(line)-1] = ' '; +				s << line; +				s << std::endl; +			} +			fclose(cpuinfo); +			s << std::endl; +		} +		else +		{ +			s << "Unable to collect processor information" << std::endl; +		} +		return s.str();  	} +		 +}; -	if(l1icachesize != 0) -	{ -		CPUInfo._L1.Instruction.bPresent = true; -		snprintf(CPUInfo._L1.Instruction.strSize, sizeof(CPUInfo._L1.Instruction.strSize), "%d KB", l1icachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L1.Instruction.uiAssociativeWays = ???; -		CPUInfo._L1.Instruction.uiLineSize = cachelinesize; -	} -	if(l2cachesize != 0) -	{ -		CPUInfo._L2.bPresent = true; -		snprintf(CPUInfo._L2.strSize, sizeof(CPUInfo._L2.strSize), "%d KB", l2cachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L2.uiAssociativeWays = ???; -		CPUInfo._L2.uiLineSize = cachelinesize; -	} +#endif // LL_MSVC elif LL_DARWIN elif LL_LINUX -	if(l3cachesize != 0) -	{ -		CPUInfo._L2.bPresent = true; -		snprintf(CPUInfo._L2.strSize, sizeof(CPUInfo._L2.strSize), "%d KB", l3cachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L2.uiAssociativeWays = ???; -		CPUInfo._L2.uiLineSize = cachelinesize; +////////////////////////////////////////////////////// +// Interface definition +LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) +{ +	// *NOTE:Mani - not thread safe. +	if(!mImpl) +	{ +#ifdef LL_MSVC +		static LLProcessorInfoWindowsImpl the_impl;  +		mImpl = &the_impl; +#elif LL_DARWIN +		static LLProcessorInfoDarwinImpl the_impl;  +		mImpl = &the_impl; +#else +		static LLProcessorInfoLinuxImpl the_impl;  +		mImpl = &the_impl;		 +#endif // LL_MSVC  	} -	 -	CPUInfo._Ext.FPU_FloatingPointUnit = hasFeature("hw.optional.floatingpoint"); - -//	printf("pagesize = 0x%x\n", pagesize); -//	printf("cachelinesize = 0x%x\n", cachelinesize); -//	printf("l1icachesize = 0x%x\n", l1icachesize); -//	printf("l1dcachesize = 0x%x\n", l1dcachesize); -//	printf("l2settings = 0x%x\n", l2settings); -//	printf("l2cachesize = 0x%x\n", l2cachesize); -//	printf("l3settings = 0x%x\n", l3settings); -//	printf("l3cachesize = 0x%x\n", l3cachesize); -	 -	// After reading we translate the configuration to strings -	TranslateProcessorConfiguration(); - -	// After all we return the class CPUInfo member var -	return (&CPUInfo);  } -#endif // LL_DARWIN -// bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen) -// ====================================================================== -// Gets the frequency and processor information and writes it to a string -///////////////////////////////////////////////////////////////////////// -bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen) -{ -#define LENCHECK                len = (unsigned int) strlen(buf); if (len >= uiMaxLen) return false; strcpy(strBuffer, buf); strBuffer += len;     /*Flawfinder: ignore*/ -#define COPYADD(str)            strcpy(buf, str); LENCHECK;    /* Flawfinder: ignore */ -#define FORMATADD(format, var)  sprintf(buf, format, var); LENCHECK;    /* Flawfinder: ignore */ -#define BOOLADD(str, boolvar)   COPYADD(str); if (boolvar) { COPYADD(" Yes\n"); } else { COPYADD(" No\n"); } - -	char buf[1024];	/* Flawfinder: ignore */	 -	unsigned int len; - -	// First we have to get the frequency -    GetCPUFrequency(50); - -	// Then we get the processor information -	GetCPUInfo(); - -    // Now we construct the string (see the macros at function beginning) -	strBuffer[0] = 0; - -	COPYADD("// CPU General Information\n//////////////////////////\n"); -	FORMATADD("Processor name:   %s\n", strCPUName); -	FORMATADD("Frequency:        %.2f MHz\n\n", (float) uqwFrequency / 1000000.0f); -	FORMATADD("Vendor:           %s\n", CPUInfo.strVendor); -	FORMATADD("Family:           %s\n", CPUInfo.strFamily); -	FORMATADD("Extended family:  %d\n", CPUInfo.uiExtendedFamily); -	FORMATADD("Model:            %s\n", CPUInfo.strModel); -	FORMATADD("Extended model:   %d\n", CPUInfo.uiExtendedModel); -	FORMATADD("Type:             %s\n", CPUInfo.strType); -	FORMATADD("Brand ID:         %s\n", CPUInfo.strBrandID); -	if (CPUInfo._Ext.PN_ProcessorSerialNumber) -	{ -		FORMATADD("Processor Serial: %s\n", CPUInfo.strProcessorSerial); -	} -	else -	{ -	  COPYADD("Processor Serial: Disabled\n"); -	} -#if !LL_SOLARIS		//  NOTE: Why bother printing all this when it's irrelavent - -	COPYADD("\n\n// CPU Configuration\n////////////////////\n"); -	FORMATADD("L1 instruction cache:           %s\n", CPUInfo._L1.Instruction.strCache); -	FORMATADD("L1 data cache:                  %s\n", CPUInfo._L1.Data.strCache); -	FORMATADD("L2 cache:                       %s\n", CPUInfo._L2.strCache); -	FORMATADD("L3 cache:                       %s\n", CPUInfo._L3.strCache); -	FORMATADD("Trace cache:                    %s\n", CPUInfo._Trace.strCache); -	FORMATADD("Instruction TLB:                %s\n", CPUInfo._Instruction.strTLB); -	FORMATADD("Data TLB:                       %s\n", CPUInfo._Data.strTLB); -	FORMATADD("Max Supported CPUID-Level:      0x%08lX\n", CPUInfo.MaxSupportedLevel); -	FORMATADD("Max Supported Ext. CPUID-Level: 0x%08lX\n", CPUInfo.MaxSupportedExtendedLevel); - -	COPYADD("\n\n// CPU Extensions\n/////////////////\n"); -	BOOLADD("AA64   AMD 64-bit Architecture:                    ", CPUInfo._Ext.AA64_AMD64BitArchitecture); -	BOOLADD("ACPI   Thermal Monitor And Clock Control:          ", CPUInfo._Ext.ACPI_ThermalMonitorAndClockControl); -	BOOLADD("APIC   Advanced Programmable Interrupt Controller: ", CPUInfo._Ext.APIC_AdvancedProgrammableInterruptController); -	FORMATADD("       APIC-ID:                                     %d\n", CPUInfo._Ext.APIC_ID); -	BOOLADD("CLFSH  CLFLUSH Instruction Presence:               ", CPUInfo._Ext.CLFSH_CFLUSH_Instruction); -	FORMATADD("       CLFLUSH Instruction Cache Line Size:         %d\n", CPUInfo._Ext.CLFLUSH_InstructionCacheLineSize); -	BOOLADD("CMOV   Conditional Move And Compare Instructions:  ", CPUInfo._Ext.CMOV_ConditionalMoveAndCompareInstructions); -	BOOLADD("CX8    COMPXCHG8B Instruction:                     ", CPUInfo._Ext.CX8_COMPXCHG8B_Instruction); -	BOOLADD("DE     Debugging Extensions:                       ", CPUInfo._Ext.DE_DebuggingExtensions); -	BOOLADD("DS     Debug Store:                                ", CPUInfo._Ext.DS_DebugStore); -	BOOLADD("FGPAT  Page Attribute Table:                       ", CPUInfo._Ext.FGPAT_PageAttributeTable); -	BOOLADD("FPU    Floating Point Unit:                        ", CPUInfo._Ext.FPU_FloatingPointUnit); -	BOOLADD("FXSR   Fast Streaming SIMD Extensions Save/Restore:", CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore); -	BOOLADD("HT     Hyper Threading:                            ", CPUInfo._Ext.HT_HyperThreading); -	BOOLADD("IA64   Intel 64-Bit Architecture:                  ", CPUInfo._Ext.IA64_Intel64BitArchitecture); -	BOOLADD("MCA    Machine Check Architecture:                 ", CPUInfo._Ext.MCA_MachineCheckArchitecture); -	BOOLADD("MCE    Machine Check Exception:                    ", CPUInfo._Ext.MCE_MachineCheckException); -	BOOLADD("MMX    Multimedia Extensions:                      ", CPUInfo._Ext.MMX_MultimediaExtensions); -	BOOLADD("MMX+   Multimedia Extensions:                      ", CPUInfo._Ext.EMMX_MultimediaExtensions); -	BOOLADD("MSR    Model Specific Registers:                   ", CPUInfo._Ext.MSR_ModelSpecificRegisters); -	BOOLADD("MTRR   Memory Type Range Registers:                ", CPUInfo._Ext.MTRR_MemoryTypeRangeRegisters); -	BOOLADD("PAE    Physical Address Extension:                 ", CPUInfo._Ext.PAE_PhysicalAddressExtension); -	BOOLADD("PGE    PTE Global Flag:                            ", CPUInfo._Ext.PGE_PTE_GlobalFlag); -	if (CPUInfo._Ext.PN_ProcessorSerialNumber) -	{ -		FORMATADD("PN     Processor Serial Number:                     %s\n", CPUInfo.strProcessorSerial); -	} -	else -	{ -		COPYADD("PN     Processor Serial Number:                     Disabled\n"); -	} -	BOOLADD("PSE    Page Size Extensions:                       ", CPUInfo._Ext.PSE_PageSizeExtensions); -	BOOLADD("PSE36  36-bit Page Size Extension:                 ", CPUInfo._Ext.PSE36_36bitPageSizeExtension); -	BOOLADD("SEP    Fast System Call:                           ", CPUInfo._Ext.SEP_FastSystemCall); -	BOOLADD("SS     Self Snoop:                                 ", CPUInfo._Ext.SS_SelfSnoop); -	BOOLADD("SSE    Streaming SIMD Extensions:                  ", CPUInfo._Ext.SSE_StreamingSIMD_Extensions); -	BOOLADD("SSE2   Streaming SIMD 2 Extensions:                ", CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions); -	BOOLADD("ALTVEC Altivec Extensions:                         ", CPUInfo._Ext.Altivec_Extensions); -	BOOLADD("TM     Thermal Monitor:                            ", CPUInfo._Ext.TM_ThermalMonitor); -	BOOLADD("TSC    Time Stamp Counter:                         ", CPUInfo._Ext.TSC_TimeStampCounter); -	BOOLADD("VME    Virtual 8086 Mode Enhancements:             ", CPUInfo._Ext.VME_Virtual8086ModeEnhancements); -	BOOLADD("3DNow! Instructions:                               ", CPUInfo._Ext._3DNOW_InstructionExtensions); -	BOOLADD("Enhanced 3DNow! Instructions:                      ", CPUInfo._Ext._E3DNOW_InstructionExtensions); -#endif -	// Yippie!!! -	return true; -} +LLProcessorInfo::~LLProcessorInfo() {} +F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } +bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } +bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } +std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); } +std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); } +std::string LLProcessorInfo::getCPUFeatureDescription() const { return mImpl->getCPUFeatureDescription(); } -// bool CProcessor::WriteInfoTextFile(const std::string& strFilename) -// =========================================================== -// Takes use of CProcessor::CPUInfoToText and saves the string to a -// file -/////////////////////////////////////////////////////////////////// -bool CProcessor::WriteInfoTextFile(const std::string& strFilename) -{ -	char buf[16384];	/* Flawfinder: ignore */	 - -	// First we get the string -	if (!CPUInfoToText(buf, 16383)) -		return false; - -	// Then we create a new file (CREATE_ALWAYS) -	LLFILE *file = LLFile::fopen(strFilename, "w");	/* Flawfinder: ignore */	 -	if (!file) -		return false; - -	// After that we write the string to the file -	unsigned long dwBytesToWrite, dwBytesWritten; -	dwBytesToWrite = (unsigned long) strlen(buf);	 /*Flawfinder: ignore*/ -	dwBytesWritten = (unsigned long) fwrite(buf, 1, dwBytesToWrite, file); -	fclose(file); -	if (dwBytesToWrite != dwBytesWritten) -		return false; - -	// Done -	return true; -} diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 746d007a7f..fc2c8dacfb 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -30,167 +30,26 @@   * $/LicenseInfo$   */ -// Author: Benjamin Jurke -// File history: 27.02.2002   File created. -/////////////////////////////////////////// -  #ifndef LLPROCESSOR_H  #define LLPROCESSOR_H +class LLProcessorInfoImpl; -// Options: -/////////// -#if LL_WINDOWS -#define PROCESSOR_FREQUENCY_MEASURE_AVAILABLE -#endif - -#if LL_MSVC && _M_X64 -#      define LL_X86_64 1 -#      define LL_X86 1 -#elif LL_MSVC && _M_IX86 -#      define LL_X86 1 -#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) -#      define LL_X86_64 1 -#      define LL_X86 1 -#elif LL_GNUC && ( defined(__i386__) ) -#      define LL_X86 1 -#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) -#      define LL_PPC 1 -#endif - - -struct ProcessorExtensions -{ -	bool FPU_FloatingPointUnit; -	bool VME_Virtual8086ModeEnhancements; -	bool DE_DebuggingExtensions; -	bool PSE_PageSizeExtensions; -	bool TSC_TimeStampCounter; -	bool MSR_ModelSpecificRegisters; -	bool PAE_PhysicalAddressExtension; -	bool MCE_MachineCheckException; -	bool CX8_COMPXCHG8B_Instruction; -	bool APIC_AdvancedProgrammableInterruptController; -	unsigned int APIC_ID; -	bool SEP_FastSystemCall; -	bool MTRR_MemoryTypeRangeRegisters; -	bool PGE_PTE_GlobalFlag; -	bool MCA_MachineCheckArchitecture; -	bool CMOV_ConditionalMoveAndCompareInstructions; -	bool FGPAT_PageAttributeTable; -	bool PSE36_36bitPageSizeExtension; -	bool PN_ProcessorSerialNumber; -	bool CLFSH_CFLUSH_Instruction; -	unsigned int CLFLUSH_InstructionCacheLineSize; -	bool DS_DebugStore; -	bool ACPI_ThermalMonitorAndClockControl; -	bool EMMX_MultimediaExtensions; -	bool MMX_MultimediaExtensions; -	bool FXSR_FastStreamingSIMD_ExtensionsSaveRestore; -	bool SSE_StreamingSIMD_Extensions; -	bool SSE2_StreamingSIMD2_Extensions; -	bool Altivec_Extensions; -	bool SS_SelfSnoop; -	bool HT_HyperThreading; -	unsigned int HT_HyterThreadingSiblings; -	bool TM_ThermalMonitor; -	bool IA64_Intel64BitArchitecture; -	bool _3DNOW_InstructionExtensions; -	bool _E3DNOW_InstructionExtensions; -	bool AA64_AMD64BitArchitecture; -}; - -struct ProcessorCache -{ -	bool bPresent; -	char strSize[32];	/* Flawfinder: ignore */	 -	unsigned int uiAssociativeWays; -	unsigned int uiLineSize; -	bool bSectored; -	char strCache[128];	/* Flawfinder: ignore */	 -}; - -struct ProcessorL1Cache -{ -    ProcessorCache Instruction; -	ProcessorCache Data; -}; - -struct ProcessorTLB +class LL_COMMON_API LLProcessorInfo  { -	bool bPresent; -	char strPageSize[32];	/* Flawfinder: ignore */	 -	unsigned int uiAssociativeWays; -	unsigned int uiEntries; -	char strTLB[128];	/* Flawfinder: ignore */	 -}; - -struct ProcessorInfo -{ -	char strVendor[16];	/* Flawfinder: ignore */	 -	unsigned int uiFamily; -	unsigned int uiExtendedFamily; -	char strFamily[64];	/* Flawfinder: ignore */	 -	unsigned int uiModel; -	unsigned int uiExtendedModel; -	char strModel[128];	/* Flawfinder: ignore */	 -	unsigned int uiStepping; -	unsigned int uiType; -	char strType[64];	/* Flawfinder: ignore */	 -	unsigned int uiBrandID; -	char strBrandID[64];	/* Flawfinder: ignore */	 -	char strProcessorSerial[64];	/* Flawfinder: ignore */	 -	unsigned long MaxSupportedLevel; -	unsigned long MaxSupportedExtendedLevel; -	ProcessorExtensions _Ext; -	ProcessorL1Cache _L1; -	ProcessorCache _L2; -	ProcessorCache _L3; -	ProcessorCache _Trace; -	ProcessorTLB _Instruction; -	ProcessorTLB _Data; -}; - - -// CProcessor -// ========== -// Class for detecting the processor name, type and available -// extensions as long as it's speed. -///////////////////////////////////////////////////////////// -class CProcessor -{ -// Constructor / Destructor: -////////////////////////////  public: -	CProcessor(); - -// Private vars: -//////////////// -public: -	F64 uqwFrequency; -	char strCPUName[128];	/* Flawfinder: ignore */	 -	ProcessorInfo CPUInfo; - -// Private functions: -///////////////////// +	LLProcessorInfo();  + 	~LLProcessorInfo(); + +	F64 getCPUFrequency() const; +	bool hasSSE() const; +	bool hasSSE2() const; +	bool hasAltivec() const; +	std::string getCPUFamilyName() const; +	std::string getCPUBrandName() const; +	std::string getCPUFeatureDescription() const;  private: -	bool AnalyzeIntelProcessor(); -	bool AnalyzeAMDProcessor(); -	bool AnalyzeUnknownProcessor(); -	bool CheckCPUIDPresence(); -	void DecodeProcessorConfiguration(unsigned int cfg); -	void TranslateProcessorConfiguration(); -	void GetStandardProcessorConfiguration(); -	void GetStandardProcessorExtensions(); - -// Public functions: -//////////////////// -public: -	F64 GetCPUFrequency(unsigned int uiMeasureMSecs); -	const ProcessorInfo *GetCPUInfo(); -	bool CPUInfoToText(char *strBuffer, unsigned int uiMaxLen); -	bool WriteInfoTextFile(const std::string& strFilename); +	LLProcessorInfoImpl* mImpl;  }; - -#endif +#endif // LLPROCESSOR_H diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 52b1b63209..d41d0c8a3f 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -58,7 +58,6 @@  #	include <unistd.h>  #	include <sys/sysinfo.h>  const char MEMINFO_FILE[] = "/proc/meminfo"; -const char CPUINFO_FILE[] = "/proc/cpuinfo";  #elif LL_SOLARIS  #	include <stdio.h>  #	include <unistd.h> @@ -513,71 +512,21 @@ U32 LLOSInfo::getProcessResidentSizeKB()  LLCPUInfo::LLCPUInfo()  {  	std::ostringstream out; -	CProcessor proc; -	const ProcessorInfo* info = proc.GetCPUInfo(); +	LLProcessorInfo proc;  	// proc.WriteInfoTextFile("procInfo.txt"); -	mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions; -	mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions; -	mHasAltivec = info->_Ext.Altivec_Extensions; -	mCPUMHz = (F64)(proc.GetCPUFrequency(50)/1000000.0F); -	mFamily.assign( info->strFamily ); +	mHasSSE = proc.hasSSE(); +	mHasSSE2 = proc.hasSSE2(); +	mHasAltivec = proc.hasAltivec(); +	mCPUMHz = (F64)proc.getCPUFrequency(); +	mFamily = proc.getCPUFamilyName();  	mCPUString = "Unknown"; -#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS -	out << proc.strCPUName; +	out << proc.getCPUBrandName();  	if (200 < mCPUMHz && mCPUMHz < 10000)           // *NOTE: cpu speed is often way wrong, do a sanity check  	{  		out << " (" << mCPUMHz << " MHz)";  	}  	mCPUString = out.str(); -	 -#elif LL_LINUX -	std::map< std::string, std::string > cpuinfo; -	LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb"); -	if(cpuinfo_fp) -	{ -		char line[MAX_STRING]; -		memset(line, 0, MAX_STRING); -		while(fgets(line, MAX_STRING, cpuinfo_fp)) -		{ -			// /proc/cpuinfo on Linux looks like: -			// name\t*: value\n -			char* tabspot = strchr( line, '\t' ); -			if (tabspot == NULL) -				continue; -			char* colspot = strchr( tabspot, ':' ); -			if (colspot == NULL) -				continue; -			char* spacespot = strchr( colspot, ' ' ); -			if (spacespot == NULL) -				continue; -			char* nlspot = strchr( line, '\n' ); -			if (nlspot == NULL) -				nlspot = line + strlen( line ); // Fallback to terminating NUL -			std::string linename( line, tabspot ); -			std::string llinename(linename); -			LLStringUtil::toLower(llinename); -			std::string lineval( spacespot + 1, nlspot ); -			cpuinfo[ llinename ] = lineval; -		} -		fclose(cpuinfo_fp); -	} -# if LL_X86 -	std::string flags = " " + cpuinfo["flags"] + " "; -	LLStringUtil::toLower(flags); -	mHasSSE = ( flags.find( " sse " ) != std::string::npos ); -	mHasSSE2 = ( flags.find( " sse2 " ) != std::string::npos ); -	 -	F64 mhz; -	if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) -	    && 200.0 < mhz && mhz < 10000.0) -	{ -		mCPUMHz = (F64)(mhz); -	} -	if (!cpuinfo["model name"].empty()) -		mCPUString = cpuinfo["model name"]; -# endif // LL_X86 -#endif // LL_LINUX  }  bool LLCPUInfo::hasAltivec() const @@ -607,38 +556,9 @@ std::string LLCPUInfo::getCPUString() const  void LLCPUInfo::stream(std::ostream& s) const  { -#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS  	// gather machine information. -	char proc_buf[CPUINFO_BUFFER_SIZE];		/* Flawfinder: ignore */ -	CProcessor proc; -	if(proc.CPUInfoToText(proc_buf, CPUINFO_BUFFER_SIZE)) -	{ -		s << proc_buf; -	} -	else -	{ -		s << "Unable to collect processor information" << std::endl; -	} -#else -	// *NOTE: This works on linux. What will it do on other systems? -	LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb"); -	if(cpuinfo) -	{ -		char line[MAX_STRING]; -		memset(line, 0, MAX_STRING); -		while(fgets(line, MAX_STRING, cpuinfo)) -		{ -			line[strlen(line)-1] = ' '; -			s << line; -		} -		fclose(cpuinfo); -		s << std::endl; -	} -	else -	{ -		s << "Unable to collect processor information" << std::endl; -	} -#endif +	s << LLProcessorInfo().getCPUFeatureDescription(); +  	// These are interesting as they reflect our internal view of the  	// CPU's attributes regardless of platform  	s << "->mHasSSE:     " << (U32)mHasSSE << std::endl; diff --git a/indra/llcommon/tests/llprocessor_test.cpp b/indra/llcommon/tests/llprocessor_test.cpp new file mode 100644 index 0000000000..a9e312b70b --- /dev/null +++ b/indra/llcommon/tests/llprocessor_test.cpp @@ -0,0 +1,67 @@ +/**  + * @file llprocessor_test.cpp + * @date 2010-06-01 + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2010, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../llprocessor.h" + + +namespace tut +{ +	struct processor +	{ +	}; + +	typedef test_group<processor> processor_t; +	typedef processor_t::object processor_object_t; +	tut::processor_t tut_processor("processor"); + +	template<> template<> +	void processor_object_t::test<1>() +	{ +		set_test_name("LLProcessorInfo regression test"); + +		LLProcessorInfo pi; +		F64 freq =  pi.getCPUFrequency(); +		//bool sse =  pi.hasSSE(); +		//bool sse2 = pi.hasSSE2(); +		//bool alitvec = pi.hasAltivec(); +		std::string family = pi.getCPUFamilyName(); +		std::string brand =  pi.getCPUBrandName(); +		//std::string steam =  pi.getCPUFeatureDescription(); + +		ensure_not_equals("Unknown Brand name", brand, "Unknown");  +		ensure_not_equals("Unknown Family name", family, "Unknown");  +		ensure("Reasonable CPU Frequency > 100 && < 10000", freq > 100 && freq < 10000); +	} +} diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 2c767a4857..53830b1a14 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -85,10 +85,7 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,  	mType(type),  	mName(name)  { -	LLStringUtil::replaceNonstandardASCII(mName, ' '); -	LLStringUtil::replaceChar(mName, '|', ' '); -	LLStringUtil::trim(mName); -	LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN); +	correctInventoryName(mName);  }  LLInventoryObject::LLInventoryObject() : @@ -155,12 +152,8 @@ void LLInventoryObject::setUUID(const LLUUID& new_uuid)  void LLInventoryObject::rename(const std::string& n)  {  	std::string new_name(n); -	LLStringUtil::replaceNonstandardASCII(new_name, ' '); -	LLStringUtil::replaceChar(new_name, '|', ' '); -	LLStringUtil::trim(new_name); -	LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); - -	if( new_name != mName ) +	correctInventoryName(new_name); +	if( !new_name.empty() && new_name != mName )  	{  		mName = new_name;  	} @@ -221,10 +214,7 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)  				" %254s %254[^|]",  				keyword, valuestr);  			mName.assign(valuestr); -			LLStringUtil::replaceNonstandardASCII(mName, ' '); -			LLStringUtil::replaceChar(mName, '|', ' '); -			LLStringUtil::trim(mName); -			LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN); +			correctInventoryName(mName);  		}  		else  		{ @@ -284,6 +274,15 @@ void LLInventoryObject::updateServer(BOOL) const  	llwarns << "LLInventoryObject::updateServer() called.  Doesn't do anything." << llendl;  } +inline +void LLInventoryObject::correctInventoryName(std::string& name) +{ +	LLStringUtil::replaceNonstandardASCII(name, ' '); +	LLStringUtil::replaceChar(name, '|', ' '); +	LLStringUtil::trim(name); +	LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN); +} +  ///----------------------------------------------------------------------------  /// Class LLInventoryItem diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index b083e305b1..4c6ac83ab8 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -92,9 +92,13 @@ public:  	void setParent(const LLUUID& new_parent);  	void setType(LLAssetType::EType type); +private: +	// in place correction for inventory name string +	void correctInventoryName(std::string& name); +  	//--------------------------------------------------------------------  	// File Support -	//   Implemented here so that a minimal information set can be transmitted  +	//   Implemented here so that a minimal information set can be transmitted  	//   between simulator and viewer.  	//--------------------------------------------------------------------  public: diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 209b506c30..c3c15e1374 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -61,11 +61,11 @@  #endif  // Single Precision Floating Point Routines -#ifndef fsqrtf -#define fsqrtf(x)		((F32)sqrt((F64)(x))) -#endif  #ifndef sqrtf -#define sqrtf(x)		((F32)sqrt((F64)(x))) +#define sqrtf(x)	((F32)sqrt((F64)(x))) +#endif +#ifndef fsqrtf +#define fsqrtf(x)	sqrtf(x)  #endif  #ifndef cosf @@ -78,11 +78,14 @@  #define tanf(x)		((F32)tan((F64)(x)))  #endif  #ifndef acosf -#define acosf(x)		((F32)acos((F64)(x))) +#define acosf(x)	((F32)acos((F64)(x)))  #endif  #ifndef powf -#define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) +#define powf(x,y)	((F32)pow((F64)(x),(F64)(y))) +#endif +#ifndef expf +#define expf(x)		((F32)exp((F64)(x)))  #endif  const F32	GRAVITY			= -9.8f; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bf5eda21eb..76cd68e246 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -813,7 +813,7 @@ BOOL LLVertexBuffer::useVBOs() const  		return FALSE;  	}  #endif -	return sEnableVBOs; +	return TRUE;  }  //---------------------------------------------------------------------------- @@ -1177,7 +1177,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  	{		  		if (mGLBuffer)  		{ -			if (sEnableVBOs && sVBOActive) +			if (useVBOs() && sVBOActive)  			{  				glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);  				sBindCount++; @@ -1189,7 +1189,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  				setup = TRUE; // ... or a client memory pointer changed  			}  		} -		if (sEnableVBOs && mGLIndices && sIBOActive) +		if (useVBOs() && mGLIndices && sIBOActive)  		{  			/*if (sMapped)  			{ diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 8e0245c451..cd23d5cd33 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -66,8 +66,12 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)   , mAutoScrolling( false )   , mAutoScrollRate( 0.f )   , mSelectedTab( NULL ) + , mTabComparator( NULL ) + , mNoVisibleTabsHelpText(NULL)  { -  mSingleExpansion = params.single_expansion; +	initNoTabsWidget(params.empty_accordion_text); + +	mSingleExpansion = params.single_expansion;  	if(mFitParent && !mSingleExpansion)  	{  		llinfos << "fit_parent works best when combined with single_expansion" << llendl; @@ -78,7 +82,10 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel()   , mAutoScrolling( false )   , mAutoScrollRate( 0.f )   , mSelectedTab( NULL ) + , mNoVisibleTabsHelpText(NULL)  { +	initNoTabsWidget(LLTextBox::Params()); +  	mSingleExpansion = false;  	mFitParent = false;  	LLUICtrlFactory::getInstance()->buildPanel(this, "accordion_parent.xml");	 @@ -168,6 +175,8 @@ BOOL LLAccordionCtrl::postBuild()  		}  	} +	updateNoTabsHelpTextVisibility(); +  	return TRUE;  } @@ -187,8 +196,15 @@ void LLAccordionCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  	rcLocal.mRight = rcLocal.mLeft + width;  	rcLocal.mTop = rcLocal.mBottom + height; +	// get textbox a chance to reshape its content +	mNoVisibleTabsHelpText->reshape(width, height, called_from_parent); +  	setRect(rcLocal); +	// assume that help text is always fit accordion. +	// necessary text paddings can be set via h_pad and v_pad +	mNoVisibleTabsHelpText->setRect(getLocalRect()); +  	arrange();  } @@ -336,7 +352,7 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view)  	mAccordionTabs.push_back(accordion_tab);  	accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLAccordionCtrl::onCollapseCtrlCloseOpen, this, mAccordionTabs.size() - 1) ); - +	arrange();	  }  void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view) @@ -359,6 +375,31 @@ void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view)  	}  } +void	LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params) +{ +	LLTextBox::Params tp = tb_params; +	tp.rect(getLocalRect()); +	mNoVisibleTabsOrigString = tp.initial_value().asString(); +	mNoVisibleTabsHelpText = LLUICtrlFactory::create<LLTextBox>(tp, this); +} + +void	LLAccordionCtrl::updateNoTabsHelpTextVisibility() +{ +	bool visible_exists = false; +	std::vector<LLAccordionCtrlTab*>::const_iterator it = mAccordionTabs.begin(); +	const std::vector<LLAccordionCtrlTab*>::const_iterator it_end = mAccordionTabs.end(); +	for (; it != it_end; ++it) +	{ +		if ((*it)->getVisible()) +		{ +			visible_exists = true; +			break; +		} +	} + +	mNoVisibleTabsHelpText->setVisible(!visible_exists); +} +  void	LLAccordionCtrl::arrangeSinge()  {  	S32 panel_left = BORDER_MARGIN;	  // Margin from left side of Splitter @@ -500,6 +541,8 @@ void LLAccordionCtrl::arrange()  		S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN; +		if (accordion_tab->getFitParent()) +			panel_height = accordion_tab->getRect().getHeight();  		ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height);  		show_hide_scrollbar(getRect().getWidth(),getRect().getHeight()); @@ -737,6 +780,20 @@ S32	LLAccordionCtrl::notifyParent(const LLSD& info)  		}  		return 1;  	} +	else if (info.has("child_visibility_change")) +	{ +		BOOL new_visibility = info["child_visibility_change"]; +		if (new_visibility) +		{ +			// there is at least one visible tab +			mNoVisibleTabsHelpText->setVisible(FALSE); +		} +		else +		{ +			// it could be the latest visible tab, check all of them +			updateNoTabsHelpTextVisibility(); +		} +	}  	return LLPanel::notifyParent(info);  }  void	LLAccordionCtrl::reset		() @@ -745,6 +802,28 @@ void	LLAccordionCtrl::reset		()  		mScrollbar->setDocPos(0);  } +void LLAccordionCtrl::sort() +{ +	if (!mTabComparator) +	{ +		llwarns << "No comparator specified for sorting accordion tabs." << llendl; +		return; +	} + +	std::sort(mAccordionTabs.begin(), mAccordionTabs.end(), LLComparatorAdaptor(*mTabComparator)); +	arrange(); +} + +void	LLAccordionCtrl::setFilterSubString(const std::string& filter_string) +{ +	LLStringUtil::format_map_t args; +	args["[SEARCH_TERM]"] = LLURI::escape(filter_string); +	std::string text = mNoVisibleTabsOrigString; +	LLStringUtil::format(text, args); + +	mNoVisibleTabsHelpText->setValue(text); +} +  S32 LLAccordionCtrl::calcExpandedTabHeight(S32 tab_index /* = 0 */, S32 available_height /* = 0 */)  {  	if(tab_index < 0) diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index a029201c90..fc6f2d896c 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -34,6 +34,7 @@  #define LL_ACCORDIONCTRL_H  #include "llpanel.h" +#include "lltextbox.h"  #include "llscrollbar.h"  #include <vector> @@ -56,6 +57,19 @@ private:  public: +	/** +	 * Abstract comparator for accordion tabs. +	 */ +	class LLTabComparator +	{ +	public: +		LLTabComparator() {}; +		virtual ~LLTabComparator() {}; + +		/** Returns true if tab1 < tab2, false otherwise */ +		virtual bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const = 0; +	}; +  	struct Params   		: public LLInitParam::Block<Params, LLPanel::Params>  	{ @@ -64,10 +78,12 @@ public:  								accordion tabs are responsible for scrolling their content.  								*NOTE fit_parent works best when combined with single_expansion.  								Accordion view should implement getRequiredRect() and provide valid height*/ +		Optional<LLTextBox::Params>	empty_accordion_text;  		Params()  			: single_expansion("single_expansion",false)  			, fit_parent("fit_parent", false) +			, empty_accordion_text("empty_accordion_text")  		{};  	}; @@ -105,7 +121,18 @@ public:  	void	reset		(); +	void	setComparator(const LLTabComparator* comp) { mTabComparator = comp; } +	void	sort(); + +	/** +	 * Sets filter substring as a search_term for help text when there are no any visible tabs. +	 */ +	void	setFilterSubString(const std::string& filter_string); +  private: +	void	initNoTabsWidget(const LLTextBox::Params& tb_params); +	void	updateNoTabsHelpTextVisibility(); +  	void	arrangeSinge();  	void	arrangeMultiple(); @@ -123,6 +150,21 @@ private:  	BOOL	autoScroll				(S32 x, S32 y); +	/** +	 * An adaptor for LLTabComparator +	 */ +	struct LLComparatorAdaptor +	{ +		LLComparatorAdaptor(const LLTabComparator& comparator) : mComparator(comparator) {}; + +		bool operator()(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) +		{ +			return mComparator.compare(tab1, tab2); +		} + +		const LLTabComparator& mComparator; +	}; +  private:  	LLRect			mInnerRect;  	LLScrollbar*	mScrollbar; @@ -130,7 +172,11 @@ private:  	bool			mFitParent;  	bool			mAutoScrolling;  	F32				mAutoScrollRate; -	LLAccordionCtrlTab* mSelectedTab; +	LLTextBox*		mNoVisibleTabsHelpText; +	std::string		mNoVisibleTabsOrigString; + +	LLAccordionCtrlTab*		mSelectedTab; +	const LLTabComparator*	mTabComparator;  }; diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 83e67980a3..1bc8086a27 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -409,6 +409,13 @@ void LLAccordionCtrlTab::changeOpenClose(bool is_open)  	}  } +void LLAccordionCtrlTab::handleVisibilityChange(BOOL new_visibility) +{ +	LLUICtrl::handleVisibilityChange(new_visibility); + +	notifyParent(LLSD().with("child_visibility_change", new_visibility)); +} +  BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask)  {  	if(mCollapsible && mHeaderVisible && mCanOpenClose) @@ -466,7 +473,7 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)  	addChild(panel,0);  } -std::string LLAccordionCtrlTab::getTitle() +std::string LLAccordionCtrlTab::getTitle() const  {  	LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);  	if (header) diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 83a9024a74..480b26e130 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -115,7 +115,7 @@ public:  	void		setAccordionView(LLView* panel);  	LLView*		getAccordionView() { return mContainerPanel; }; -	std::string getTitle(); +	std::string getTitle() const;  	// Set text and highlight substring in LLAccordionCtrlTabHeader  	void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null); @@ -154,6 +154,11 @@ public:  	// Call reshape after changing size  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); +	/** +	 * Raises notifyParent event with "child_visibility_change" = new_visibility +	 */ +	void handleVisibilityChange(BOOL new_visibility); +  	// Changes expand/collapse state and triggers expand/collapse callbacks  	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -185,6 +190,7 @@ public:  	void showAndFocusHeader();  	void setFitPanel( bool fit ) { mFitPanel = true; } +	bool getFitParent() const { return mFitPanel; }  protected:  	void adjustContainerPanel	(const LLRect& child_rect); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index fad98e553f..341debc9a8 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -810,6 +810,11 @@ void LLFloater::applyTitle()  	{  		mDragHandle->setTitle ( mTitle );  	} + +	if (getHost()) +	{ +		getHost()->updateFloaterTitle(this);	 +	}  }  std::string LLFloater::getCurrentTitle() const diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 75342afbe2..e9614ea660 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -339,6 +339,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  		{  			if( *cur == '\n' )  			{ +				LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(cur-base); +				text_segment->setToken( 0 ); +				insertSegment( *seg_list, text_segment, text_len, defaultColor, editor);  				cur++;  				if( !*cur || *cur == '\n' )  				{ @@ -378,9 +381,8 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  						}  						S32 seg_end = cur - base; -						LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor ); -						text_segment->setToken( cur_token ); -						insertSegment( seg_list, text_segment, text_len, defaultColor, editor); +						//create segments from seg_start to seg_end +						insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);  						line_done = TRUE; // to break out of second loop.  						break;  					} @@ -486,11 +488,12 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  						seg_end = seg_start + between_delimiters + cur_delimiter->getLength();  					} - +					insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor); +					/*  					LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor );  					text_segment->setToken( cur_delimiter );  					insertSegment( seg_list, text_segment, text_len, defaultColor, editor); - +					*/  					// Note: we don't increment cur, since the end of one delimited seg may be immediately  					// followed by the start of another one.  					continue; @@ -519,10 +522,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  						// llinfos << "Seg: [" << word.c_str() << "]" << llendl; - -						LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor ); -						text_segment->setToken( cur_token ); -						insertSegment( seg_list, text_segment, text_len, defaultColor, editor); +						insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);  					}  					cur += seg_len;   					continue; @@ -537,24 +537,50 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  	}  } -void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>* seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor ) +void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor ) +{ +	std::string::size_type pos = wtext.find('\n',seg_start); +	 +	while (pos!=-1 && pos < (std::string::size_type)seg_end) +	{ +		if (pos!=seg_start) +		{ +			LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, pos, editor ); +			text_segment->setToken( cur_token ); +			insertSegment( seg_list, text_segment, text_len, defaultColor, editor); +		} + +		LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(pos); +		text_segment->setToken( cur_token ); +		insertSegment( seg_list, text_segment, text_len, defaultColor, editor); + +		seg_start = pos+1; +		pos = wtext.find('\n',seg_start); +	} + +	LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor ); +	text_segment->setToken( cur_token ); +	insertSegment( seg_list, text_segment, text_len, defaultColor, editor); +} + +void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )  { -	LLTextSegmentPtr last = seg_list->back(); +	LLTextSegmentPtr last = seg_list.back();  	S32 new_seg_end = new_segment->getEnd();  	if( new_segment->getStart() == last->getStart() )  	{ -		seg_list->pop_back(); +		seg_list.pop_back();  	}  	else  	{  		last->setEnd( new_segment->getStart() );  	} -	seg_list->push_back( new_segment ); +	seg_list.push_back( new_segment );  	if( new_seg_end < text_len )  	{ -		seg_list->push_back( new LLNormalTextSegment( defaultColor, new_seg_end, text_len, editor ) ); +		seg_list.push_back( new LLNormalTextSegment( defaultColor, new_seg_end, text_len, editor ) );  	}  } diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index e5b66dfa56..09378e408b 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -129,7 +129,8 @@ public:  private:  	LLColor3	readColor(const std::string& s); -	void		insertSegment(std::vector<LLTextSegmentPtr> *seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor); +	void		insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor); +	void		insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor);  	BOOL		mLoaded;  	word_token_map_t mWordTokenMap; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 45f9de8e8d..c93ca1af88 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -377,7 +377,10 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)  	setCursor(llmin((S32)mText.length(), getCursor()));  	// Set current history line to end of history. -	mCurrentHistoryLine = mLineHistory.end() - 1; +	if(mLineHistory.end() != mLineHistory.begin()) +	{ +		mCurrentHistoryLine = mLineHistory.end() - 1; +	}  	mPrevText = mText;  } diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index 3aea648562..b1dbce0000 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -238,6 +238,16 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,  	moveResizeHandlesToFront();  } +void LLMultiFloater::updateFloaterTitle(LLFloater* floaterp) +{ +	S32 index = mTabContainer->getIndexForPanel(floaterp); +	if (index != -1) +	{ +		mTabContainer->setPanelTitle(index, floaterp->getShortTitle()); +	} +} + +  /**  	BOOL selectFloater(LLFloater* floaterp) diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index bbf2c56fe7..24a841f64e 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -80,6 +80,7 @@ public:  	void onTabSelected();  	virtual void updateResizeLimits(); +	virtual void updateFloaterTitle(LLFloater* floaterp);  protected:  	struct LLFloaterData diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index d86709c448..72f3a14822 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2743,6 +2743,12 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)  	editor->addDocumentChild(mView);  } +LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1) +{ +	LLStyleSP s( new LLStyle(LLStyle::Params().visible(true))); + +	mFontHeight = llceil(s->getFont()->getLineHeight()); +}  LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)  {  	mFontHeight = llceil(style->getFont()->getLineHeight()); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 176308c61a..89ce5cdc8e 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -519,6 +519,7 @@ class LLLineBreakTextSegment : public LLTextSegment  public:  	LLLineBreakTextSegment(LLStyleConstSP style,S32 pos); +	LLLineBreakTextSegment(S32 pos);  	~LLLineBreakTextSegment();  	bool		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;  	S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 035e9ddd9c..3c98cd5b85 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -307,6 +307,7 @@ set(viewer_SOURCE_FILES      llnotificationstorage.cpp      llnotificationtiphandler.cpp      lloutfitslist.cpp +    lloutfitobserver.cpp      lloutputmonitorctrl.cpp      llpanelavatar.cpp      llpanelavatartag.cpp @@ -825,6 +826,7 @@ set(viewer_HEADER_FILES      llnotificationmanager.h      llnotificationstorage.h      lloutfitslist.h +    lloutfitobserver.h      lloutputmonitorctrl.h      llpanelavatar.h      llpanelavatartag.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eb443e0e70..b4e6713d7c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -583,7 +583,7 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>180</integer> +      <integer>120</integer>      </map>      <key>AvatarSex</key>      <map> @@ -11439,5 +11439,27 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>OutfitOperationsTimeout</key> +    <map> +      <key>Comment</key> +      <string>Timeout for outfit related operations.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>180</integer> +    </map> +    <key>HeightUnits</key> +    <map> +      <key>Comment</key> +      <string>Determines which metric units are used: 1(TRUE) for meter and 0(FALSE) for foot.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index d4000e9253..dc76a4e518 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -1,26 +1,26 @@  <llsd>      <map> -    <key>BusyModeResponse</key> +    <key>BusyResponseChanged</key>          <map>          <key>Comment</key> -            <string>Auto response to instant messages while in busy mode.</string> +            <string>Does user's busy mode message differ from default?</string>          <key>Persist</key>              <integer>1</integer>          <key>Type</key> -            <string>String</string> +            <string>Boolean</string>          <key>Value</key> -            <string>The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string> +            <integer>0</integer>          </map> -    <key>BusyModeResponse2</key> +    <key>BusyModeResponse</key>          <map>          <key>Comment</key> -            <string>Auto response to instant messages while in busy mode, clean (unencoded) version of BusyModeResponse</string> +            <string>Auto response to instant messages while in busy mode.</string>          <key>Persist</key>              <integer>1</integer>          <key>Type</key>              <string>String</string>          <key>Value</key> -            <string>|TOKEN COPY BusyModeResponse|</string> +            <string>The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>          </map>      <key>InstantMessageLogPath</key>          <map> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index f49b8d24f2..03efcadc98 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3589,7 +3589,7 @@ void LLAgent::sendAgentSetAppearance()  			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))  			{  				generate_valid_hash = FALSE; -				llinfos << "Not caching baked texture upload for " << baked_index << " due to being uploaded at low resolution." << llendl; +				llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl;  			}  			const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash); diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 644363826a..c3f075fd49 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2360,6 +2360,7 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came  				mAnimationDuration = gSavedSettings.getF32("ZoomTime");  			}  		} +		gAgentAvatarp->updateMeshTextures();  	}  	else  	{ diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index d823a3cbbb..342f9a5d80 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -64,6 +64,25 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;  using namespace LLVOAvatarDefines; +/////////////////////////////////////////////////////////////////////////////// + +// Callback to wear and start editing an item that has just been created. +class LLWearAndEditCallback : public LLInventoryCallback +{ +	void fire(const LLUUID& inv_item) +	{ +		if (inv_item.isNull()) return; + +		// Request editing the item after it gets worn. +		gAgentWearables.requestEditingWearable(inv_item); + +		// Wear it. +		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); +	} +}; + +/////////////////////////////////////////////////////////////////////////////// +  // HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look"  // Some db items are corrupted, have inventory flags = 0, implying wearable type = shape, even though  // wearable type stored in asset is some other value. @@ -732,7 +751,7 @@ U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable  void LLAgentWearables::wearableUpdated(LLWearable *wearable)  { -	gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); +	gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);  	wearable->refreshName();  	wearable->setLabelUpdated(); @@ -776,7 +795,7 @@ void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)  	if (wearable)  	{  		mWearableDatas[type].erase(mWearableDatas[type].begin() + index); -		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); +		gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);  		wearable->setLabelUpdated();  	}  } @@ -1987,10 +2006,12 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos  // static  void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id)  { +	if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; +  	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);  	LLAssetType::EType asset_type = wearable->getAssetType();  	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; -	LLPointer<LLInventoryCallback> cb = wear ? new WearOnAvatarCallback : NULL; +	LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL;  	LLUUID folder_id;  	if (parent_id.notNull()) @@ -2013,17 +2034,44 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con  // static  void LLAgentWearables::editWearable(const LLUUID& item_id)  { -	LLViewerInventoryItem* item; -	LLWearable* wearable; +	LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); +	if (!item) +	{ +		llwarns << "Failed to get linked item" << llendl; +		return; +	} -	if ((item = gInventory.getLinkedItem(item_id)) && -		(wearable = gAgentWearables.getWearableFromAssetID(item->getAssetUUID())) && -		gAgentWearables.isWearableModifiable(item->getUUID()) && -		item->isFinished()) +	LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); +	if (!wearable) +	{ +		llwarns << "Cannot get wearable" << llendl; +		return; +	} + +	if (!gAgentWearables.isWearableModifiable(item->getUUID())) +	{ +		llwarns << "Cannot modify wearable" << llendl; +		return; +	} + +	LLPanel* panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance"); +	LLSidepanelAppearance::editWearable(wearable, panel); +} + +// Request editing the item after it gets worn. +void LLAgentWearables::requestEditingWearable(const LLUUID& item_id) +{ +	mItemToEdit = gInventory.getLinkedItemID(item_id); +} + +// Start editing the item if previously requested. +void LLAgentWearables::editWearableIfRequested(const LLUUID& item_id) +{ +	if (mItemToEdit.notNull() && +		mItemToEdit == gInventory.getLinkedItemID(item_id))  	{ -		LLPanel* panel = LLSideTray::getInstance()->showPanel("panel_outfit_edit", LLSD()); -		// copied from LLPanelOutfitEdit::onEditWearableClicked() -		LLSidepanelAppearance::editWearable(wearable, panel->getParent()); +		LLAgentWearables::editWearable(item_id); +		mItemToEdit.setNull();  	}  } diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 679ecefa6f..a41b949be6 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -148,6 +148,12 @@ public:  	static void		editWearable(const LLUUID& item_id);  	bool			moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); +	void			requestEditingWearable(const LLUUID& item_id); +	void			editWearableIfRequested(const LLUUID& item_id); + +private: +	LLUUID			mItemToEdit; +  	//--------------------------------------------------------------------  	// Removing wearables  	//-------------------------------------------------------------------- diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 28a0ba8817..1c2bdf07df 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -38,11 +38,13 @@  #include "llagentwearables.h"  #include "llappearancemgr.h"  #include "llcommandhandler.h" +#include "lleventtimer.h"  #include "llgesturemgr.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h"  #include "llinventoryobserver.h"  #include "llnotificationsutil.h" +#include "lloutfitobserver.h"  #include "llpaneloutfitsinventory.h"  #include "llselectmgr.h"  #include "llsidepanelappearance.h" @@ -55,6 +57,34 @@  char ORDER_NUMBER_SEPARATOR('@'); +class LLOutfitUnLockTimer: public LLEventTimer +{ +public: +	LLOutfitUnLockTimer(F32 period) : LLEventTimer(period) +	{ +		// restart timer on BOF changed event +		LLOutfitObserver::instance().addBOFChangedCallback(boost::bind( +				&LLOutfitUnLockTimer::reset, this)); +		stop(); +	} + +	/*virtual*/ +	BOOL tick() +	{ +		if(mEventTimer.hasExpired()) +		{ +			LLAppearanceMgr::instance().setOutfitLocked(false); +		} +		return FALSE; +	} +	void stop() { mEventTimer.stop(); } +	void start() { mEventTimer.start(); } +	void reset() { mEventTimer.reset(); } +	BOOL getStarted() { return mEventTimer.getStarted(); } + +	LLTimer&  getEventTimer() { return mEventTimer;} +}; +  // support for secondlife:///app/appearance SLapps  class LLAppearanceHandler : public LLCommandHandler  { @@ -841,6 +871,27 @@ void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& respo  	}  } +void LLAppearanceMgr::setOutfitLocked(bool locked) +{ +	if (mOutfitLocked == locked) +	{ +		return; +	} + +	mOutfitLocked = locked; +	if (locked) +	{ +		mUnlockOutfitTimer->reset(); +		mUnlockOutfitTimer->start(); +	} +	else +	{ +		mUnlockOutfitTimer->stop(); +	} + +	LLOutfitObserver::instance().notifyOutfitLockChanged(); +} +  void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id)  {  	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); @@ -1889,6 +1940,14 @@ void LLAppearanceMgr::onFirstFullyVisible()  bool LLAppearanceMgr::updateBaseOutfit()  { +	if (isOutfitLocked()) +	{ +		// don't allow modify locked outfit +		llassert(!isOutfitLocked()); +		return false; +	} +	setOutfitLocked(true); +  	const LLUUID base_outfit_id = getBaseOutfitUUID();  	if (base_outfit_id.isNull()) return false; @@ -2159,7 +2218,7 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b  	bool result = false;  	if (result = gAgentWearables.moveWearable(item, closer_to_body))  	{ -		gAgentAvatarp->wearableUpdated(item->getWearableType(), TRUE); +		gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE);  	}  	setOutfitDirty(true); @@ -2217,6 +2276,14 @@ LLAppearanceMgr::LLAppearanceMgr():  	mAttachmentInvLinkEnabled(false),  	mOutfitIsDirty(false)  { +	LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); + +	// unlock outfit on save operation completed +	outfit_observer.addCOFSavedCallback(boost::bind( +			&LLAppearanceMgr::setOutfitLocked, this, false)); + +	mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32( +			"OutfitOperationsTimeout")));  }  LLAppearanceMgr::~LLAppearanceMgr() diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index f1beef5857..2227a43cd8 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -42,10 +42,12 @@  class LLWearable;  class LLWearableHoldingPattern;  class LLInventoryCallback; +class LLOutfitUnLockTimer;  class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>  {  	friend class LLSingleton<LLAppearanceMgr>; +	friend class LLOutfitUnLockTimer;  public:  	typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t; @@ -162,6 +164,8 @@ public:  	// COF is processed if cat_id is not specified  	void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null); +	bool isOutfitLocked() { return mOutfitLocked; } +  protected:  	LLAppearanceMgr();  	~LLAppearanceMgr(); @@ -186,10 +190,20 @@ private:  	static void onOutfitRename(const LLSD& notification, const LLSD& response); +	void setOutfitLocked(bool locked); +  	std::set<LLUUID> mRegisteredAttachments;  	bool mAttachmentInvLinkEnabled;  	bool mOutfitIsDirty; +	/** +	 * Lock for blocking operations on outfit until server reply or timeout exceed +	 * to avoid unsynchronized outfit state or performing duplicate operations. +	 */ +	bool mOutfitLocked; + +	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; +  	//////////////////////////////////////////////////////////////////////////////////  	// Item-specific convenience functions   public: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 95084666bb..82bd59d25c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -331,10 +331,6 @@ const char *VFS_INDEX_FILE_BASE = "index.db2.x.";  static std::string gWindowTitle; -std::string gLoginPage; -std::vector<std::string> gLoginURIs; -static std::string gHelperURI; -  LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;  void idle_afk_check() diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 01d6c3a8d5..2dafe295fe 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -656,6 +656,8 @@ void LLAvatarActions::shareWithAvatars()  	LLFloaterAvatarPicker* picker =  		LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);  	picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); +	picker->openFriendsTab(); +	LLNotificationsUtil::add("ShareNotification");  }  // static diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 7a3eddf7a6..41f5fe64a1 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -203,7 +203,9 @@ LLBottomTray::~LLBottomTray()  	// override effect of save_visibility=true.  	// this attribute is necessary to button.initial_callback=Button.SetFloaterToggle works properly:  	//		i.g when floater changes its visibility - button changes its toggle state. +	getChild<LLUICtrl>("build_btn")->setControlValue(false);  	getChild<LLUICtrl>("search_btn")->setControlValue(false); +	getChild<LLUICtrl>("world_map_btn")->setControlValue(false);  }  // *TODO Vadim: why void* ? diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 0bd03571da..961969a5c5 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -667,7 +667,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  				// (don't let object names with hyperlinks override our objectim Url)  				LLStyle::Params link_params(style_params);  				link_params.color.control = "HTMLLinkColor"; -				link_params.link_href = url; +				link_params.link_href = LLURI::escape(url);  				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>"  + delimiter,  									false, link_params);  			} diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 7ac3d14c72..611396b0e5 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -58,13 +58,19 @@ static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;  class CofContextMenu : public LLListContextMenu  {  protected: -	static void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id) +	CofContextMenu(LLCOFWearables* cof_wearables) +	:	mCOFWearables(cof_wearables) +	{ +		llassert(mCOFWearables); +	} + +	void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id)  	{  		LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); +		LLWearableType::EType w_type = getWearableType(item_id);  		// Hide the "Create new <WEARABLE_TYPE>" if it's irrelevant. -		LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); -		if (!item || !item->isWearableType()) +		if (w_type == LLWearableType::WT_NONE)  		{  			menu_item->setVisible(FALSE);  			return; @@ -72,25 +78,67 @@ protected:  		// Set proper label for the "Create new <WEARABLE_TYPE>" menu item.  		LLStringUtil::format_map_t args; -		LLWearableType::EType w_type = item->getWearableType();  		args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type);  		std::string new_label = LLTrans::getString("CreateNewWearable", args);  		menu_item->setLabel(new_label);  	} -	static void createNew(const LLUUID& item_id) +	void createNew(const LLUUID& item_id)  	{ -		LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); -		if (!item || !item->isWearableType()) return; +		LLAgentWearables::createWearable(getWearableType(item_id), true); +	} + +	// Get wearable type of the given item. +	// +	// There is a special case: so-called "dummy items" +	// (i.e. the ones that are there just to indicate that you're not wearing +	// any wearables of the corresponding type. They are currently grayed out +	// and suffixed with "not worn"). +	// Those items don't have an UUID, but they do have an associated wearable type. +	// If the user has invoked context menu for such item, +	// we ignore the passed item_id and retrieve wearable type from the item. +	LLWearableType::EType getWearableType(const LLUUID& item_id) +	{ +		if (!isDummyItem(item_id)) +		{ +			LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); +			if (item && item->isWearableType()) +			{ +				return item->getWearableType(); +			} +		} +		else if (mCOFWearables) // dummy item selected +		{ +			LLPanelDummyClothingListItem* item; + +			item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()); +			if (item) +			{ +				return item->getWearableType(); +			} +		} -		LLAgentWearables::createWearable(item->getWearableType(), true); +		return LLWearableType::WT_NONE; +	} + +	static bool isDummyItem(const LLUUID& item_id) +	{ +		return item_id.isNull();  	} + +	LLCOFWearables* mCOFWearables;  };  ////////////////////////////////////////////////////////////////////////// -class CofAttachmentContextMenu : public LLListContextMenu +class CofAttachmentContextMenu : public CofContextMenu  { +public: +	CofAttachmentContextMenu(LLCOFWearables* cof_wearables) +	:	CofContextMenu(cof_wearables) +	{ +	} +  protected:  	/*virtual*/ LLContextMenu* createMenu() @@ -108,8 +156,13 @@ protected:  class CofClothingContextMenu : public CofContextMenu  { -protected: +public: +	CofClothingContextMenu(LLCOFWearables* cof_wearables) +	:	CofContextMenu(cof_wearables) +	{ +	} +protected:  	/*virtual*/ LLContextMenu* createMenu()  	{  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -121,7 +174,7 @@ protected:  		registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false));  		registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true));  		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); -		registrar.add("Clothing.Create", boost::bind(createNew, selected_id)); +		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));  		enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2)); @@ -171,8 +224,13 @@ protected:  class CofBodyPartContextMenu : public CofContextMenu  { -protected: +public: +	CofBodyPartContextMenu(LLCOFWearables* cof_wearables) +	:	CofContextMenu(cof_wearables) +	{ +	} +protected:  	/*virtual*/ LLContextMenu* createMenu()  	{  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -184,7 +242,7 @@ protected:  		LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit"));  		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));  		registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); -		registrar.add("BodyPart.Create", boost::bind(createNew, selected_id)); +		registrar.add("BodyPart.Create", boost::bind(&CofBodyPartContextMenu::createNew, this, selected_id));  		enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2)); @@ -219,9 +277,9 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),  	mBodyParts(NULL),  	mLastSelectedList(NULL)  { -	mClothingMenu = new CofClothingContextMenu(); -	mAttachmentMenu = new CofAttachmentContextMenu(); -	mBodyPartMenu = new CofBodyPartContextMenu(); +	mClothingMenu = new CofClothingContextMenu(this); +	mAttachmentMenu = new CofAttachmentContextMenu(this); +	mBodyPartMenu = new CofBodyPartContextMenu(this);  };  LLCOFWearables::~LLCOFWearables() @@ -387,13 +445,7 @@ LLPanelClothingListItem* LLCOFWearables::buildClothingListItem(LLViewerInventory  	item_panel->childSetAction("btn_edit", mCOFCallbacks.mEditWearable);  	//turning on gray separator line for the last item in the items group of the same wearable type -	if (last) -	{ -		LLRect rect = item_panel->getRect(); -		item_panel->reshape(rect.getWidth(), rect.getHeight() + -		item_panel->getChild<LLView>("wearable_type_separator_icon")->getRect().getHeight()); -		item_panel->childSetVisible("wearable_type_separator_icon", true); -	} +	item_panel->childSetVisible("wearable_type_separator_icon", last);  	return item_panel;  } @@ -427,7 +479,7 @@ LLPanelDeletableWearableListItem* LLCOFWearables::buildAttachemntListItem(LLView  	llassert(item);  	if (!item) return NULL; -	LLPanelDeletableWearableListItem* item_panel = LLPanelDeletableWearableListItem::create(item); +	LLPanelAttachmentListItem* item_panel = LLPanelAttachmentListItem::create(item);  	if (!item_panel) return NULL;  	//setting callbacks diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 96364f9418..8f6816b845 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -446,6 +446,19 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask,  	return TRUE;  } + +void LLFloaterAvatarPicker::openFriendsTab() +{ +	LLTabContainer* tab_container = getChild<LLTabContainer>("ResidentChooserTabs"); +	if (tab_container == NULL) +	{ +		llassert(tab_container != NULL); +		return; +	} + +	tab_container->selectTabByName("FriendsPanel"); +} +  // static   void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)  { diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index e69b814f9f..0af72e85a0 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -66,6 +66,8 @@ public:  						   void *cargo_data, EAcceptance *accept,  						   std::string& tooltip_msg); +	void openFriendsTab(); +  private:  	void editKeystroke(class LLLineEditor* caller, void* user_data); diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 46b3695511..d359856443 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -254,7 +254,6 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,  		std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),   							 inv_item->getInventoryType(), -							 inv_item->getIsLinkType(),  							 inv_item->getFlags(),  							 item_is_multi);  		row["columns"][0]["column"] = "icon"; diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index c35653178a..9bde3b1dac 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -223,7 +223,6 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,  		std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),   								 inv_item->getInventoryType(), -								 inv_item->getIsLinkType(),  								 inv_item->getFlags(),  								 item_is_multi);  		row["columns"][0]["column"] = "icon"; diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp index 5815df36d1..7f41a64064 100644 --- a/indra/newview/llfloaterbuycurrencyhtml.cpp +++ b/indra/newview/llfloaterbuycurrencyhtml.cpp @@ -87,6 +87,9 @@ void LLFloaterBuyCurrencyHTML::navigateToFinalURL()  	replace[ "[MSG]" ] = LLURI::escape( mMessage );  	LLStringUtil::format( buy_currency_url, replace ); +	// write final URL to debug console +	llinfos << "Buy currency HTML prased URL is " << buy_currency_url << llendl; +  	// kick off the navigation  	mBrowser->navigateTo( buy_currency_url );  } @@ -98,6 +101,9 @@ void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMedi  	// placeholder for now - just in case we want to catch media events  	if ( LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE == event )  	{ +		// update currency after we complete a navigation since there are many ways  +		// this can result in a different L$ balance +		LLStatusBar::sendMoneyBalanceRequest();  	};  } @@ -105,6 +111,9 @@ void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMedi  //  void LLFloaterBuyCurrencyHTML::onClose( bool app_quitting )  { +	// update L$ balanace one more time +	LLStatusBar::sendMoneyBalanceRequest(); +  	destroy();  } diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index ca346138fb..d6effb2b21 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -49,6 +49,9 @@  static LLDefaultChildRegistry::Register<LLPanelCameraItem> r("panel_camera_item"); +const F32 NUDGE_TIME = 0.25f;		// in seconds +const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed +  // Constants  const F32 CAMERA_BUTTON_DELAY = 0.0f; @@ -75,6 +78,7 @@ protected:  	void	onZoomPlusHeldDown();  	void	onZoomMinusHeldDown();  	void	onSliderValueChanged(); +	F32		getOrbitRate(F32 time);  private:  	LLButton*	mPlusBtn; @@ -155,8 +159,8 @@ LLPanelCameraZoom::LLPanelCameraZoom()  	mMinusBtn( NULL ),  	mSlider( NULL )  { -	mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this)); -	mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this)); +	mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this)); +	mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this));  	mCommitCallbackRegistrar.add("Slider.value_changed", boost::bind(&LLPanelCameraZoom::onSliderValueChanged, this));  } @@ -179,9 +183,9 @@ void LLPanelCameraZoom::onZoomPlusHeldDown()  	F32 val = mSlider->getValueF32();  	F32 inc = mSlider->getIncrement();  	mSlider->setValue(val - inc); -	// commit only if value changed -	if (val != mSlider->getValueF32()) -		mSlider->onCommit(); +	F32 time = mPlusBtn->getHeldDownTime(); +	gAgentCamera.unlockView(); +	gAgentCamera.setOrbitInKey(getOrbitRate(time));  }  void LLPanelCameraZoom::onZoomMinusHeldDown() @@ -189,9 +193,22 @@ void LLPanelCameraZoom::onZoomMinusHeldDown()  	F32 val = mSlider->getValueF32();  	F32 inc = mSlider->getIncrement();  	mSlider->setValue(val + inc); -	// commit only if value changed -	if (val != mSlider->getValueF32()) -		mSlider->onCommit(); +	F32 time = mMinusBtn->getHeldDownTime(); +	gAgentCamera.unlockView(); +	gAgentCamera.setOrbitOutKey(getOrbitRate(time)); +} + +F32 LLPanelCameraZoom::getOrbitRate(F32 time) +{ +	if( time < NUDGE_TIME ) +	{ +		F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; +		return rate; +	} +	else +	{ +		return 1; +	}  }  void  LLPanelCameraZoom::onSliderValueChanged() diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 8fa7a53996..564e38d02d 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -39,7 +39,6 @@  #include "llflatlistview.h"  class LLJoystickCameraRotate; -class LLJoystickCameraZoom;  class LLJoystickCameraTrack;  class LLFloaterReg;  class LLPanelCameraZoom; diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index c259659083..e74bfae026 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -54,7 +54,10 @@  // Constants  //  const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f; - +const S32 MAP_PADDING_LEFT = 0; +const S32 MAP_PADDING_TOP = 2; +const S32 MAP_PADDING_RIGHT = 2; +const S32 MAP_PADDING_BOTTOM = 0;  //  // Member functions  // @@ -106,7 +109,8 @@ BOOL LLFloaterMap::postBuild()  		mPopupMenu->setItemEnabled ("Stop Tracking", false);  	} -	stretchMiniMap(getRect().getWidth(),getRect().getHeight()); +	stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT +		,getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM);  	updateMinorDirections(); @@ -238,7 +242,7 @@ void LLFloaterMap::stretchMiniMap(S32 width,S32 height)  	if(mMap)  	{  		LLRect map_rect; -		map_rect.setLeftTopAndSize( 0, getRect().getHeight(), width, height); +		map_rect.setLeftTopAndSize( MAP_PADDING_LEFT, getRect().getHeight() - MAP_PADDING_TOP, width, height);  		mMap->reshape( width, height, 1);  		mMap->setRect(map_rect);  	} @@ -248,7 +252,8 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)  {  	LLFloater::reshape(width, height, called_from_parent); -	stretchMiniMap(width, height); +	stretchMiniMap(width - MAP_PADDING_LEFT - MAP_PADDING_RIGHT +		,height - MAP_PADDING_TOP - MAP_PADDING_BOTTOM);  	updateMinorDirections();  } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5fbbb2c1a8..2299cd719c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -330,9 +330,28 @@ BOOL LLFloaterPreference::postBuild()  	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");  	childSetText("cache_location", cache_location); +	// if floater is opened before login set default localized busy message +	if (LLStartUp::getStartupState() < STATE_STARTED) +	{ +		gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault")); +	} +  	return TRUE;  } +void LLFloaterPreference::onBusyResponseChanged() +{ +	// set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise +	if(LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString()) +	{ +		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE ); +	} +	else +	{ +		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE ); +	} +} +  LLFloaterPreference::~LLFloaterPreference()  {  	// clean up user data @@ -487,6 +506,22 @@ void LLFloaterPreference::cancel()  void LLFloaterPreference::onOpen(const LLSD& key)  { +	// this variable and if that follows it are used to properly handle busy mode response message +	static bool initialized = FALSE; +	// if user is logged in and we haven't initialized busy_response yet, do it +	if (!initialized && LLStartUp::getStartupState() == STATE_STARTED) +	{ +		// Special approach is used for busy response localization, because "BusyModeResponse" is +		// in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized. +		// To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged +		// was added into per account settings. + +		// initialization should happen once,so setting variable to TRUE +		initialized = TRUE; +		// this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in +		// busy response message. +		gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this)); +	}  	gAgent.sendAgentUserInfoRequest();  	/////////////////////////// From LLPanelGeneral ////////////////////////// @@ -540,6 +575,16 @@ void LLFloaterPreference::onVertexShaderEnable()  	refreshEnabledGraphics();  } +//static +void LLFloaterPreference::initBusyResponse() +	{ +		if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged")) +		{ +			//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885) +			gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault")); +		} +	} +  void LLFloaterPreference::setHardwareDefaults()  {  	LLFeatureManager::getInstance()->applyRecommendedSettings(); @@ -960,18 +1005,6 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data)  	refresh();  } -// static -// DEV-24146 -  needs to be removed at a later date. jan-2009 -void LLFloaterPreference::cleanupBadSetting() -{ -	if (gSavedPerAccountSettings.getString("BusyModeResponse2") == "|TOKEN COPY BusyModeResponse|") -	{ -		llinfos << "cleaning old BusyModeResponse" << llendl; -		//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885) -		gSavedPerAccountSettings.setString("BusyModeResponse2", LLTrans::getString("BusyModeResponseDefault")); -	} -} -  void LLFloaterPreference::onClickSetKey()  {  	LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 71aa5d3189..b45e09db7d 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -80,6 +80,9 @@ public:  	// refresh all the graphics preferences menus  	static void refreshEnabledGraphics(); +	// translate user's busy response message according to current locale if message is default, otherwise do nothing +	static void initBusyResponse(); +  protected:	  	void		onBtnOK();  	void		onBtnCancel(); @@ -87,6 +90,9 @@ protected:  	void		onClickBrowserClearCache(); +	// set value of "BusyResponseChanged" in account settings depending on whether busy response +	// string differs from default after user changes. +	void onBusyResponseChanged();  	// if the custom settings box is clicked  	void onChangeCustom();  	void updateMeterText(LLUICtrl* ctrl); @@ -140,7 +146,6 @@ public:  	void buildPopupLists();  	static void refreshSkin(void* data); -	static void cleanupBadSetting();  private:  	static std::string sSkin;  	bool mGotPersonalInfo; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 5bea3325a8..00981d3c25 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -91,10 +91,6 @@  ///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs  ///---------------------------------------------------------------------------- -S32 LLFloaterSnapshot::sUIWinHeightLong = 526 ; -S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 230 ; -S32 LLFloaterSnapshot::sUIWinWidth = 215 ; -  LLSnapshotFloaterView* gSnapshotFloaterView = NULL;  const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f; @@ -1172,9 +1168,6 @@ public:  	}  	static void onClickNewSnapshot(void* data);  	static void onClickAutoSnap(LLUICtrl *ctrl, void* data); -	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); -	static void onClickLess(void* data) ; -	static void onClickMore(void* data) ;  	static void onClickUICheck(LLUICtrl *ctrl, void* data);  	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);  	static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); @@ -1188,7 +1181,7 @@ public:  	static void onCommitCustomResolution(LLUICtrl *ctrl, void* data);  	static void onCommitSnapshot(LLFloaterSnapshot* view, LLSnapshotLivePreview::ESnapshotType type);  	static void onCommitProfilePic(LLFloaterSnapshot* view); -	static void onToggleAdvanced(LLUICtrl *ctrl, void* data); +	static void showAdvanced(LLFloaterSnapshot* view, const BOOL visible);  	static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ;  	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); @@ -1399,41 +1392,6 @@ void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)  	}  } -void LLFloaterSnapshot::Impl::onClickMore(void* data) -{ -	gSavedSettings.setBOOL( "AdvanceSnapshot", TRUE ); -	 -	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;		 -	if (view) -	{ -		view->translate( 0, view->getUIWinHeightShort() - view->getUIWinHeightLong() ); -		view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong()); -		updateControls(view) ; -		updateLayout(view) ; -		if(getPreviewView(view)) -		{ -			getPreviewView(view)->setThumbnailImageSize() ; -		} -	} -} -void LLFloaterSnapshot::Impl::onClickLess(void* data) -{ -	gSavedSettings.setBOOL( "AdvanceSnapshot", FALSE ); -	 -	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;		 -	if (view) -	{ -		view->translate( 0, view->getUIWinHeightLong() - view->getUIWinHeightShort() ); -		view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort()); -		updateControls(view) ; -		updateLayout(view) ; -		if(getPreviewView(view)) -		{ -			getPreviewView(view)->setThumbnailImageSize() ; -		} -	} -} -  // static  void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)  { @@ -1691,30 +1649,28 @@ void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)  }  //static  -void LLFloaterSnapshot::Impl::onToggleAdvanced(LLUICtrl* ctrl, void* data) +void LLFloaterSnapshot::Impl::showAdvanced(LLFloaterSnapshot* view, const BOOL visible)  { -	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; -  	LLPanel* advanced_panel = view->getChild<LLPanel>("snapshot_advanced"); -	if (advanced_panel->getVisible()) +	if (advanced_panel->getVisible() != visible)  	{ -		advanced_panel->setVisible(false); +		gSavedSettings.setBOOL("AdvanceSnapshot", visible); -		// shrink floater back to original size -		view->reshape(view->getRect().getWidth() - advanced_panel->getRect().getWidth(), view->getRect().getHeight()); +		advanced_panel->setVisible(visible); +		view->getChild<LLButton>("hide_advanced")->setVisible(visible); +		view->getChild<LLButton>("show_advanced")->setVisible(!visible); -		view->getChild<LLButton>("hide_advanced")->setVisible(false); -		view->getChild<LLButton>("show_advanced")->setVisible(true); -	} -	else -	{ -		advanced_panel->setVisible(true); -		// stretch the floater so it can accommodate the advanced panel -		view->reshape(view->getRect().getWidth() + advanced_panel->getRect().getWidth(), view->getRect().getHeight()); - -		view->getChild<LLButton>("hide_advanced")->setVisible(true); -		view->getChild<LLButton>("show_advanced")->setVisible(false); +		if (visible) +		{ +			// stretch the floater so it can accommodate the advanced panel +			view->reshape(view->getRect().getWidth() + advanced_panel->getRect().getWidth(), view->getRect().getHeight()); +		} +		else +		{ +			// shrink floater back to original size +			view->reshape(view->getRect().getWidth() - advanced_panel->getRect().getWidth(), view->getRect().getHeight()); +		}  	}  } @@ -2002,6 +1958,11 @@ LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key)  	  impl (*(new Impl))  {  	//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_snapshot.xml", FALSE); + +	mCommitCallbackRegistrar.add("Snapshot.ShowButtons",  boost::bind(&LLFloaterSnapshot::updateButtons, this, _2)); +	mCommitCallbackRegistrar.add("Snapshot.ShowAdvanced", boost::bind(&Impl::showAdvanced, this, true)); +	mCommitCallbackRegistrar.add("Snapshot.HideAdvanced", boost::bind(&Impl::showAdvanced, this, false)); +	mCommitCallbackRegistrar.add("Snapshot.Refresh", boost::bind(&Impl::onClickNewSnapshot, this));  }  // Destroys the object @@ -2023,27 +1984,14 @@ LLFloaterSnapshot::~LLFloaterSnapshot()  BOOL LLFloaterSnapshot::postBuild()  { - -	getChild<LLButton>("share")->setCommitCallback(boost::bind(&LLFloaterSnapshot::updateButtons, this, SNAPSHOT_SHARE)); -	getChild<LLButton>("save")->setCommitCallback(boost::bind(&LLFloaterSnapshot::updateButtons, this, SNAPSHOT_SAVE)); -	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterSnapshot::updateButtons, this, SNAPSHOT_MAIN)); -  	getChild<LLButton>("share_to_web")->setCommitCallback(boost::bind(&Impl::onCommitSnapshot, this, LLSnapshotLivePreview::SNAPSHOT_WEB));  	getChild<LLButton>("share_to_email")->setCommitCallback(boost::bind(&Impl::onCommitSnapshot, this, LLSnapshotLivePreview::SNAPSHOT_POSTCARD));  	getChild<LLButton>("save_to_inventory")->setCommitCallback(boost::bind(&Impl::onCommitSnapshot, this, LLSnapshotLivePreview::SNAPSHOT_TEXTURE));  	getChild<LLButton>("save_to_computer")->setCommitCallback(boost::bind(&Impl::onCommitSnapshot, this, LLSnapshotLivePreview::SNAPSHOT_LOCAL));  	getChild<LLButton>("set_profile_pic")->setCommitCallback(boost::bind(&Impl::onCommitProfilePic, this)); -	childSetCommitCallback("show_advanced", Impl::onToggleAdvanced, this); -	childSetCommitCallback("hide_advanced", Impl::onToggleAdvanced, this); -  	childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this); -	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); - -	childSetAction("more_btn", Impl::onClickMore, this); -	childSetAction("less_btn", Impl::onClickLess, this); -  	childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this);  	childSetValue("image_quality_slider", gSavedSettings.getS32("SnapshotQuality")); @@ -2095,12 +2043,13 @@ BOOL LLFloaterSnapshot::postBuild()  	impl.mPreviewHandle = previewp->getHandle();  	impl.updateControls(this);  	impl.updateLayout(this); +	impl.showAdvanced(this, gSavedSettings.getBOOL("AdvanceSnapshot"));  	//save off the refresh button's rectangle so we can apply offsets with thumbnail resize   	mRefreshBtnRect = getChild<LLButton>("new_snapshot_btn")->getRect();  	// make sure we share/hide the general buttons  -	updateButtons(SNAPSHOT_MAIN); +	updateButtons(LLSD("main"));  	return LLDockableFloater::postBuild();  } @@ -2190,19 +2139,20 @@ void LLFloaterSnapshot::update()  	}  } -bool LLFloaterSnapshot::updateButtons(ESnapshotMode mode) +bool LLFloaterSnapshot::updateButtons(const LLSD& mode)  { -	childSetVisible("share", mode == SNAPSHOT_MAIN); -	childSetVisible("save", mode == SNAPSHOT_MAIN); -	childSetVisible("set_profile_pic", mode == SNAPSHOT_MAIN); +	std::string button_mode = mode.asString(); -//	childSetVisible("share_to_web", mode == SNAPSHOT_SHARE); -	childSetVisible("share_to_email", mode == SNAPSHOT_SHARE); +	bool mode_main("main" == button_mode); +	bool mode_share("share" == button_mode); +	bool mode_save("save" == button_mode); -	childSetVisible("save_to_inventory", mode == SNAPSHOT_SAVE); -	childSetVisible("save_to_computer", mode == SNAPSHOT_SAVE); +	// Default to a known state if mode is invalid. +	if (!mode_main && !mode_share && !mode_save) mode_main = true; -	childSetVisible("cancel", mode != SNAPSHOT_MAIN);	 +	childSetVisible("panel_snapshot_main", mode_main); +	childSetVisible("panel_snapshot_share", mode_share); +	childSetVisible("panel_snapshot_save", mode_save);  	return true;  } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 931d355748..8c4373c35c 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -47,13 +47,6 @@ public:  		SNAPSHOT_FORMAT_BMP  	} ESnapshotFormat; -	enum ESnapshotMode -	{ -		SNAPSHOT_SHARE, -		SNAPSHOT_SAVE, -		SNAPSHOT_MAIN -	}; -  	LLFloaterSnapshot(const LLSD& key);  	virtual ~LLFloaterSnapshot(); @@ -66,7 +59,7 @@ public:  	void setAsProfilePic(const LLUUID& image_id); -	bool updateButtons(ESnapshotMode mode); +	bool updateButtons(const LLSD& mode);  	static S32  getUIWinHeightLong()  {return sUIWinHeightLong ;}  	static S32  getUIWinHeightShort() {return sUIWinHeightShort ;} diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index a87f7288fa..010033fcd3 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -246,6 +246,7 @@ LLFolderView::LLFolderView(const Params& p)  	text_p.font(font);  	text_p.visible(false);  	text_p.allow_html(true); +	text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047  	mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);  	mStatusTextBox->setFollowsLeft();  	mStatusTextBox->setFollowsTop(); @@ -953,6 +954,23 @@ void LLFolderView::draw()  		}  		mStatusTextBox->setValue(mStatusText);  		mStatusTextBox->setVisible( TRUE ); + +		// firstly reshape message textbox with current size. This is necessary to +		// LLTextBox::getTextPixelHeight works properly +		const LLRect local_rect = getLocalRect(); +		mStatusTextBox->setShape(local_rect); + +		// get preferable text height... +		S32 pixel_height = mStatusTextBox->getTextPixelHeight(); +		bool height_changed = local_rect.getHeight() != pixel_height; +		if (height_changed) +		{ +			// ... if it does not match current height, lets rearrange current view. +			// This will indirectly call ::arrange and reshape of the status textbox. +			// We should call this method to also notify parent about required rect. +			// See EXT-7564, EXT-7047. +			arrangeFromRoot(); +		}  	} @@ -2310,7 +2328,7 @@ void LLFolderView::updateRenamerPosition()  bool LLFolderView::selectFirstItem()  {  	for (folders_t::iterator iter = mFolders.begin(); -		 iter != mFolders.end();) +		 iter != mFolders.end();++iter)  	{  		LLFolderViewFolder* folder = (*iter );  		if (folder->getVisible()) @@ -2347,7 +2365,7 @@ bool LLFolderView::selectLastItem()  		}  	}  	for (folders_t::reverse_iterator iter = mFolders.rbegin(); -		 iter != mFolders.rend();) +		 iter != mFolders.rend();++iter)  	{  		LLFolderViewFolder* folder = (*iter);  		if (folder->getVisible()) diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 54e9bd5383..0c437cf035 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -96,6 +96,7 @@ void LLFolderViewItem::cleanupClass()  LLFolderViewItem::Params::Params()  :	icon(),  	icon_open(), +	icon_overlay(),  	root(),  	listener(),  	folder_arrow_image("folder_arrow_image"), @@ -133,6 +134,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mCreationDate(p.creation_date),  	mIcon(p.icon),  	mIconOpen(p.icon_open), +	mIconOverlay(p.icon_overlay),  	mListener(p.listener),  	mHidden(false),  	mShowLoadStatus(false) @@ -617,6 +619,7 @@ const std::string& LLFolderViewItem::getSearchableLabel() const  LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)  { +	if (!getListener()) return NULL;  	return gInventory.getItem(getListener()->getUUID());  } @@ -948,7 +951,8 @@ void LLFolderViewItem::draw()  		mDragAndDropTarget = FALSE;  	} -	 +	const LLViewerInventoryItem *item = getInventoryItem(); +	const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();  	//--------------------------------------------------------------------------------//  	// Draw open icon  	// @@ -962,6 +966,10 @@ void LLFolderViewItem::draw()   		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);   	} +	if (highlight_link) +	{ +		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1); +	}  	//--------------------------------------------------------------------------------//  	// Exit if no label to draw @@ -972,8 +980,7 @@ void LLFolderViewItem::draw()  	}  	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor; -	const LLViewerInventoryItem *item = getInventoryItem(); -	if (item && item->getIsLinkType()) color = sLinkColor; +	if (highlight_link) color = sLinkColor;  	if (in_library) color = sLibraryColor;  	F32 right_x  = 0; diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 57c722afa4..d6e4b2f556 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -97,6 +97,7 @@ public:  	{  		Optional<LLUIImage*>					icon;  		Optional<LLUIImage*>					icon_open;  // used for folders +		Optional<LLUIImage*>					icon_overlay;  // for links  		Optional<LLFolderView*>					root;  		Optional<LLFolderViewEventListener*>	listener; @@ -147,6 +148,7 @@ protected:  	LLUIImagePtr				mIcon;  	std::string					mStatusText;  	LLUIImagePtr				mIconOpen; +	LLUIImagePtr				mIconOverlay;  	BOOL						mHasVisibleChildren;  	S32							mIndentation;  	S32							mItemHeight; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 3aa9d75bc0..967f38bfd2 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -60,8 +60,14 @@  #include "llinventorymodel.h"  #include "llrootview.h"  #include "llspeakers.h" +#include "llsidetray.h" +static const S32 RECT_PADDING_NOT_INIT = -1; +static const S32 RECT_PADDING_NEED_RECALC = -2; + +S32 LLIMFloater::sAllowedRectRightPadding = RECT_PADDING_NOT_INIT; +  LLIMFloater::LLIMFloater(const LLUUID& session_id)    : LLTransientDockableFloater(NULL, true, session_id),  	mControlPanel(NULL), @@ -444,19 +450,44 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)  	return floater;  } +//static +bool LLIMFloater::resetAllowedRectPadding(const LLSD& newvalue) +{ +	//reset allowed rect right padding if "SidebarCameraMovement" option  +	//or sidebar state changed +	sAllowedRectRightPadding = RECT_PADDING_NEED_RECALC ; +	return true; +} +  void LLIMFloater::getAllowedRect(LLRect& rect)  { +	if (sAllowedRectRightPadding == RECT_PADDING_NOT_INIT) //wasn't initialized +	{ +		gSavedSettings.getControl("SidebarCameraMovement")->getSignal()->connect(boost::bind(&LLIMFloater::resetAllowedRectPadding, _2)); + +		LLSideTray*	side_bar = LLSideTray::getInstance(); +		side_bar->getCollapseSignal().connect(boost::bind(&LLIMFloater::resetAllowedRectPadding, _2)); +		sAllowedRectRightPadding = RECT_PADDING_NEED_RECALC; +	} +  	rect = gViewerWindow->getWorldViewRectScaled(); -	static S32 right_padding = 0; -	if (right_padding == 0) +	if (sAllowedRectRightPadding == RECT_PADDING_NEED_RECALC) //recalc allowed rect right padding  	{  		LLPanel* side_bar_tabs =  				gViewerWindow->getRootView()->getChild<LLPanel> (  						"side_bar_tabs"); -		right_padding = side_bar_tabs->getRect().getWidth(); +		sAllowedRectRightPadding = side_bar_tabs->getRect().getWidth();  		LLTransientFloaterMgr::getInstance()->addControlView(side_bar_tabs); + +		if (gSavedSettings.getBOOL("SidebarCameraMovement") == FALSE) +		{ +			LLSideTray*	side_bar = LLSideTray::getInstance(); + +			if (side_bar->getVisible() && !side_bar->getCollapsed()) +				sAllowedRectRightPadding += side_bar->getRect().getWidth(); +		}  	} -	rect.mRight -= right_padding; +	rect.mRight -= sAllowedRectRightPadding;  }  void LLIMFloater::setDocked(bool docked, bool pop_on_undock) diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index fef178e3a2..f1e68a2b3d 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -155,6 +155,10 @@ private:  	static void closeHiddenIMToasts(); +	static bool resetAllowedRectPadding(const LLSD& newvalue); +	//need to keep this static for performance issues +	static S32 sAllowedRectRightPadding; +  	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);  	LLPanelChatControlPanel* mControlPanel; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3a9c5ba698..7ce96a6ac1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -65,6 +65,7 @@  #include "llsidetray.h"  #include "lltrans.h"  #include "llviewerassettype.h" +#include "llviewerfoldertype.h"  #include "llviewermenu.h"  #include "llviewermessage.h"  #include "llviewerobjectlist.h" @@ -2208,13 +2209,7 @@ void LLFolderBridge::determineFolderType()  BOOL LLFolderBridge::isItemRenameable() const  { -	LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory(); -	if(cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) -	   && (cat->getOwnerID() == gAgent.getID())) -	{ -		return TRUE; -	} -	return FALSE; +	return get_is_category_renameable(getInventoryModel(), mUUID);  }  void LLFolderBridge::restoreItem() @@ -2255,58 +2250,14 @@ LLUIImagePtr LLFolderBridge::getIcon() const  }  // static -LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type, BOOL is_link) +LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)  { -	// Bypassing LLViewerFolderType::lookup() since -	// we aren't using different system folder icons -	if (is_link) -	{ -		if (preferred_type == LLFolderType::FT_OUTFIT) -			return LLUI::getUIImage("Inv_LookFolderClosed_Link"); -		else  -			return LLUI::getUIImage("Inv_FolderClosed_Link"); -	} - -	switch (preferred_type) -	{ -	case LLFolderType::FT_OUTFIT: -		return LLUI::getUIImage("Inv_LookFolderClosed"); -	case LLFolderType::FT_LOST_AND_FOUND: -		return LLUI::getUIImage("Inv_LostClosed"); -	case LLFolderType::FT_TRASH: -		return LLUI::getUIImage("Inv_TrashClosed"); -	case LLFolderType::FT_NONE: -		return LLUI::getUIImage("Inv_FolderClosed"); -	default: -		return LLUI::getUIImage("Inv_SysClosed"); -	} +	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));  }  LLUIImagePtr LLFolderBridge::getOpenIcon() const  { -	// Bypassing LLViewerFolderType::lookup() since -	// we aren't using different system folder icons -	if (isLink()) -	{ -		if (getPreferredType() == LLFolderType::FT_OUTFIT) -			return LLUI::getUIImage("Inv_LookFolderOpen_Link"); -		else  -			return LLUI::getUIImage("Inv_FolderOpen_Link"); -	} - -	switch (getPreferredType()) -	{ -	case LLFolderType::FT_OUTFIT: -		return LLUI::getUIImage("Inv_LookFolderOpen"); -	case LLFolderType::FT_LOST_AND_FOUND: -		return LLUI::getUIImage("Inv_LostOpen"); -	case LLFolderType::FT_TRASH: -		return LLUI::getUIImage("Inv_TrashOpen"); -	case LLFolderType::FT_NONE: -		return LLUI::getUIImage("Inv_FolderOpen"); -	default: -		return LLUI::getUIImage("Inv_SysOpen"); -	} +	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));  } @@ -3176,7 +3127,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  LLUIImagePtr LLTextureBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInvType, mIsLink); +	return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInvType);  }  void LLTextureBridge::openItem() @@ -3328,7 +3279,7 @@ LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory,  LLUIImagePtr LLLandmarkBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mIsLink, mVisited, FALSE); +	return LLInventoryIcon::getIcon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited, FALSE);  }  void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) @@ -3520,7 +3471,7 @@ LLUIImagePtr LLCallingCardBridge::getIcon() const  	{  		online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());  	} -	return LLInventoryIcon::getIcon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, mIsLink, online, FALSE); +	return LLInventoryIcon::getIcon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online, FALSE);  }  std::string LLCallingCardBridge::getLabelSuffix() const @@ -3959,7 +3910,7 @@ LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory,  LLUIImagePtr LLObjectBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(LLAssetType::AT_OBJECT, mInvType, mIsLink, mAttachPt, mIsMultiObject); +	return LLInventoryIcon::getIcon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject);  }  LLInventoryObject* LLObjectBridge::getObject() const @@ -4426,7 +4377,7 @@ std::string LLWearableBridge::getLabelSuffix() const  LLUIImagePtr LLWearableBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(mAssetType, mInvType, mIsLink, mWearableType, FALSE); +	return LLInventoryIcon::getIcon(mAssetType, mInvType, mWearableType, FALSE);  }  // virtual @@ -4851,7 +4802,7 @@ LLUIImagePtr LLLinkFolderBridge::getIcon() const  			}  		}  	} -	return LLFolderBridge::getIcon(folder_type, TRUE); +	return LLFolderBridge::getIcon(folder_type);  }  void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index a342a2da14..d97dfd535e 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -245,7 +245,7 @@ public:  	virtual LLFolderType::EType getPreferredType() const;  	virtual LLUIImagePtr getIcon() const;  	virtual LLUIImagePtr getOpenIcon() const; -	static LLUIImagePtr getIcon(LLFolderType::EType preferred_type, BOOL is_link = FALSE); +	static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);  	virtual BOOL renameItem(const std::string& new_name); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ca6cede7e9..c86d463a08 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -309,6 +309,11 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)  BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)  { +	if (!model) +	{ +		return FALSE; +	} +  	LLViewerInventoryCategory* cat = model->getCategory(id);  	if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 33b52cfd5e..c82ebd1439 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -324,6 +324,19 @@ private:  	LLWearableType::EType mWearableType;  }; +/** Filter out wearables-links */ +class LLFindActualWearablesOfType : public LLFindWearablesOfType +{ +public: +	LLFindActualWearablesOfType(LLWearableType::EType type) : LLFindWearablesOfType(type) {} +	virtual ~LLFindActualWearablesOfType() {} +	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) +	{ +		if (item && item->getIsLinkType()) return false; +		return LLFindWearablesOfType::operator()(cat, item); +	} +}; +  // Find worn items.  class LLFindWorn : public LLInventoryCollectFunctor  { diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 2fb55f4c1f..3090371a73 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -40,13 +40,10 @@  struct IconEntry : public LLDictionaryEntry  { -	IconEntry(const std::string &item_name, -			  const std::string &link_name) +	IconEntry(const std::string &item_name)  		: -		LLDictionaryEntry(item_name), -		mLinkName(link_name) +		LLDictionaryEntry(item_name)  	{} -	const std::string mLinkName;  };  class LLIconDictionary : public LLSingleton<LLIconDictionary>, @@ -58,52 +55,51 @@ public:  LLIconDictionary::LLIconDictionary()  { -	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture", 		"Inv_Texture_Link")); -	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Texture", 		"Inv_Texture_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard", 	"Inv_CallingCard_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard", 	"Inv_CallingCard_Link")); -	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark", 		"Inv_Landmark_Link")); -	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark", 		"Inv_Landmark_Link")); -	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script", 		"Inv_Script_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing", 		"Inv_Clothing_Link")); -	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object", 		"Inv_Object_Link")); -	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi", 	"Inv_Object_Multi_Link")); -	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard", 		"Inv_Notecard_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin", 			"Inv_Skin_Link")); -	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot", 		"Inv_Snapshot_Link")); +	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture")); +	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Texture")); +	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard")); +	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard")); +	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark")); +	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark")); +	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing")); +	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object")); +	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi")); +	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin")); +	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape", 		"Inv_BodyShape_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin", 			"Inv_Skin_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair", 			"Inv_Hair_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye", 			"Inv_Eye_Link")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt", 			"Inv_Shirt_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants", 			"Inv_Pants_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe", 			"Inv_Shoe_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks", 			"Inv_Socks_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket", 		"Inv_Jacket_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves", 		"Inv_Gloves_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt", 	"Inv_Undershirt_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants", 	"Inv_Underpants_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt", 			"Inv_Skirt_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha", 			"Inv_Alpha_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo", 		"Inv_Tattoo_Link")); -	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation", 		"Inv_Animation_Link")); -	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture", 		"Inv_Gesture_Link")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo")); +	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation")); +	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture")); -	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem", 		"Inv_LinkItem")); -	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkItem", 		"Inv_LinkItem")); +	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem")); +	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkItem")); -	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE", 				"NONE")); +	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE"));  }  LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,  									  LLInventoryType::EType inventory_type, -									  BOOL item_is_link,  									  U32 misc_flag,  									  BOOL item_is_multi)  { -	const std::string& icon_name = getIconName(asset_type, inventory_type, item_is_link, misc_flag, item_is_multi); +	const std::string& icon_name = getIconName(asset_type, inventory_type, misc_flag, item_is_multi);  	return LLUI::getUIImage(icon_name);  } @@ -114,7 +110,6 @@ LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx)  const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,  												LLInventoryType::EType inventory_type, -												BOOL item_is_link,  												U32 misc_flag,  												BOOL item_is_multi)  { @@ -169,14 +164,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,  			break;  	} -	return getIconName(idx, item_is_link); +	return getIconName(idx);  } -const std::string& LLInventoryIcon::getIconName(EIconName idx, BOOL item_is_link) +const std::string& LLInventoryIcon::getIconName(EIconName idx)  {  	const IconEntry *entry = LLIconDictionary::instance().lookup(idx); -	if (item_is_link) return entry->mLinkName;  	return entry->mName;  } diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index 4cb7a123c4..6e29012c4c 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -86,15 +86,12 @@ public:  	static const std::string& getIconName(LLAssetType::EType asset_type,  										  LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, -										  BOOL item_is_link = FALSE,  										  U32 misc_flag = 0, // different meanings depending on item type  										  BOOL item_is_multi = FALSE); -	static const std::string& getIconName(EIconName idx,  -										  BOOL item_is_link = FALSE); +	static const std::string& getIconName(EIconName idx);  	static LLUIImagePtr getIcon(LLAssetType::EType asset_type,  								LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, -								BOOL item_is_link = FALSE,  								U32 misc_flag = 0, // different meanings depending on item type  								BOOL item_is_multi = FALSE);  	static LLUIImagePtr getIcon(EIconName idx); diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index cd0e976a79..55cb2619cf 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -79,7 +79,15 @@ void LLPanelInventoryListItemBase::draw()  void LLPanelInventoryListItemBase::updateItem()  {  	setIconImage(mIconImage); -	setTitle(mItem->getName(), mHighlightedText); + +	std::string name = mItem->getName(); + +	if (get_is_item_worn(mItem->getUUID())) +	{ +		name += LLTrans::getString("worn"); +	} + +	setTitle(name, mHighlightedText);  }  void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) @@ -132,8 +140,7 @@ BOOL LLPanelInventoryListItemBase::postBuild()  	setIconCtrl(getChild<LLIconCtrl>("item_icon"));  	setTitleCtrl(getChild<LLTextBox>("item_name")); -	BOOL show_links = mForceNoLinksOnIcons ? FALSE : mItem->getIsLinkType(); -	mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), show_links, mItem->getFlags(), FALSE); +	mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);  	setNeedsRefresh(true); @@ -199,7 +206,6 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem  , mLeftWidgetsWidth(0)  , mRightWidgetsWidth(0)  , mNeedsRefresh(false) -, mForceNoLinksOnIcons(false)  {  } diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 0dd6f53be7..c1b1a6f281 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -177,10 +177,10 @@ protected:  	void setIconImage(const LLUIImagePtr& image);  	/** Set item title - inventory item name usually */ -	void setTitle(const std::string& title, const std::string& highlit_text); +	virtual void setTitle(const std::string& title, const std::string& highlit_text); -	// force not showing link icon on item's icon -	bool mForceNoLinksOnIcons; + +	LLViewerInventoryItem* mItem;  private: @@ -196,7 +196,6 @@ private:  	/** reshape remaining widgets */  	void reshapeMiddleWidgets(); -	LLViewerInventoryItem* mItem;  	LLIconCtrl*		mIconCtrl;  	LLTextBox*		mTitleCtrl; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 6fc5804a48..15760bf155 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -721,8 +721,20 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)  			// Valid UUID; set the item UUID and rename it  			new_item->setCreator(id);  			std::string avatar_name; -			// Fetch the currect name -			gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3)); + +			if (gCacheName->getFullName(id, avatar_name)) +			{ +				new_item->rename(avatar_name); +				mask |= LLInventoryObserver::LABEL; +			} +			else +			{ +				// Fetch the current name +				gCacheName->get(id, FALSE, +					boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), +					_1, _2, _3)); +			} +  		}  	}  	else if (new_item->getType() == LLAssetType::AT_GESTURE) diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index b4f0947b2c..ce44e37017 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -33,15 +33,14 @@  #include "llviewerprecompiledheaders.h"  #include "llinventorymodelbackgroundfetch.h" -// Seraph clean this up  #include "llagent.h" +#include "llappviewer.h" +#include "llcallbacklist.h"  #include "llinventorypanel.h"  #include "llviewercontrol.h"  #include "llviewermessage.h" -#include "llviewerwindow.h" -#include "llappviewer.h"  #include "llviewerregion.h" -#include "llcallbacklist.h" +#include "llviewerwindow.h"  const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;  const S32 MAX_FETCH_RETRIES = 10; @@ -63,47 +62,47 @@ LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch()  {  } -bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() +bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const  {  	return mFetchQueue.empty() && mBulkFetchCount<=0;  } -bool LLInventoryModelBackgroundFetch::libraryFetchStarted() +bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const  {  	return mRecursiveLibraryFetchStarted;  } -bool LLInventoryModelBackgroundFetch::libraryFetchCompleted() +bool LLInventoryModelBackgroundFetch::libraryFetchCompleted() const  {  	return libraryFetchStarted() && fetchQueueContainsNoDescendentsOf(gInventory.getLibraryRootFolderID());  } -bool LLInventoryModelBackgroundFetch::libraryFetchInProgress() +bool LLInventoryModelBackgroundFetch::libraryFetchInProgress() const  {  	return libraryFetchStarted() && !libraryFetchCompleted();  } -bool LLInventoryModelBackgroundFetch::inventoryFetchStarted() +bool LLInventoryModelBackgroundFetch::inventoryFetchStarted() const  {  	return mRecursiveInventoryFetchStarted;  } -bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted() +bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted() const  {  	return inventoryFetchStarted() && fetchQueueContainsNoDescendentsOf(gInventory.getRootFolderID());  } -bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() +bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() const  {  	return inventoryFetchStarted() && !inventoryFetchCompleted();  } -bool LLInventoryModelBackgroundFetch::isEverythingFetched() +bool LLInventoryModelBackgroundFetch::isEverythingFetched() const  {  	return mAllFoldersFetched;  } -BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() +BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() const  {  	return mBackgroundFetchActive;  } @@ -132,7 +131,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive  		}  		else  		{ -			// specific folder requests go to front of queue +			// Specific folder requests go to front of queue.  			if (mFetchQueue.empty() || mFetchQueue.front().mCatUUID != cat_id)  			{  				mFetchQueue.push_front(FetchQueueInfo(cat_id, recursive)); @@ -187,7 +186,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  {  	if (mBackgroundFetchActive && gAgent.getRegion())  	{ -		//If we'll be using the capability, we'll be sending batches and the background thing isn't as important. +		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important.  		std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");     		if (!url.empty())   		{ @@ -195,8 +194,12 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			return;  		} -		//DEPRECATED OLD CODE FOLLOWS. -		// no more categories to fetch, stop fetch process +#if 1 +		//-------------------------------------------------------------------------------- +		// DEPRECATED OLD CODE +		// + +		// No more categories to fetch, stop fetch process.  		if (mFetchQueue.empty())  		{  			llinfos << "Inventory fetch completed" << llendl; @@ -209,11 +212,11 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  		F32 slow_fetch_time = lerp(mMinTimeBetweenFetches, mMaxTimeBetweenFetches, 0.5f);  		if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() > slow_fetch_time)  		{ -			// double timeouts on failure +			// Double timeouts on failure.  			mMinTimeBetweenFetches = llmin(mMinTimeBetweenFetches * 2.f, 10.f);  			mMaxTimeBetweenFetches = llmin(mMaxTimeBetweenFetches * 2.f, 120.f);  			llinfos << "Inventory fetch times grown to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; -			// fetch is no longer considered "timely" although we will wait for full time-out +			// fetch is no longer considered "timely" although we will wait for full time-out.  			mTimelyFetchPending = FALSE;  		} @@ -226,14 +229,14 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			if(gDisconnected)  			{ -				// just bail if we are disconnected. +				// Just bail if we are disconnected.  				break;  			}  			const FetchQueueInfo info = mFetchQueue.front();  			LLViewerInventoryCategory* cat = gInventory.getCategory(info.mCatUUID); -			// category has been deleted, remove from queue. +			// Category has been deleted, remove from queue.  			if (!cat)  			{  				mFetchQueue.pop_front(); @@ -243,8 +246,8 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches &&   				LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion())  			{ -				// category exists but has no children yet, fetch the descendants -				// for now, just request every time and rely on retry timer to throttle +				// Category exists but has no children yet, fetch the descendants +				// for now, just request every time and rely on retry timer to throttle.  				if (cat->fetch())  				{  					mFetchTimer.reset(); @@ -258,13 +261,13 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  					break;  				}  			} -			// do I have all my children? +			// Do I have all my children?  			else if (gInventory.isCategoryComplete(info.mCatUUID))  			{ -				// finished with this category, remove from queue +				// Finished with this category, remove from queue.  				mFetchQueue.pop_front(); -				// add all children to queue +				// Add all children to queue.  				LLInventoryModel::cat_array_t* categories;  				LLInventoryModel::item_array_t* items;  				gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); @@ -275,10 +278,10 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  					mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive));  				} -				// we received a response in less than the fast time +				// We received a response in less than the fast time.  				if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time)  				{ -					// shrink timeouts based on success +					// Shrink timeouts based on success.  					mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f);  					mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f);  					//llinfos << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; @@ -289,8 +292,8 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			}  			else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches)  			{ -				// received first packet, but our num descendants does not match db's num descendants -				// so try again later +				// Received first packet, but our num descendants does not match db's num descendants +				// so try again later.  				mFetchQueue.pop_front();  				if (mNumFetchRetries++ < MAX_FETCH_RETRIES) @@ -303,9 +306,14 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  				break;  			} -			// not enough time has elapsed to do a new fetch +			// Not enough time has elapsed to do a new fetch  			break;  		} + +		// +		// DEPRECATED OLD CODE +		//-------------------------------------------------------------------------------- +#endif  	}  } @@ -333,10 +341,10 @@ protected:  	BOOL getIsRecursive(const LLUUID& cat_id) const;  private:  	LLSD mRequestSD; -	uuid_vec_t mRecursiveCatUUIDs; // Hack for storing away which cat fetches are recursive. +	uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive  }; -//If we get back a normal response, handle it here +// If we get back a normal response, handle it here.  void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  {  	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); @@ -428,7 +436,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  				gInventory.updateItem(titem);  			} -			// set version and descendentcount according to message. +			// Set version and descendentcount according to message.  			LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);  			if(cat)  			{ @@ -448,7 +456,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  		{	  			LLSD folder_sd = *folder_it; -			//These folders failed on the dataserver.  We probably don't want to retry them. +			// These folders failed on the dataserver.  We probably don't want to retry them.  			llinfos << "Folder " << folder_sd["folder_id"].asString()   					<< "Error: " << folder_sd["error"].asString() << llendl;  		} @@ -465,7 +473,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  	gInventory.notifyObservers("fetchDescendents");  } -//If we get back an error (not found, etc...), handle it here +// If we get back an error (not found, etc...), handle it here.  void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)  {  	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); @@ -475,7 +483,7 @@ void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::str  	fetcher->incrBulkFetch(-1); -	if (status==499) // Timed out. +	if (status==499) // timed out  	{  		for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();  			folder_it != mRequestSD["folders"].endArray(); @@ -502,7 +510,8 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat  	return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());  } -//static   Bundle up a bunch of requests to send all at once. +// Bundle up a bunch of requests to send all at once. +// static     void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)  {  	//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. @@ -521,7 +530,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)  		(mBulkFetchCount > max_concurrent_fetches) ||  		(mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches))  	{ -		return; // just bail if we are disconnected. +		return; // just bail if we are disconnected  	}	  	U32 folder_count=0; diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index c1e37eda8f..04f96586d7 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -33,39 +33,15 @@  #ifndef LL_LLINVENTORYMODELBACKGROUNDFETCH_H  #define LL_LLINVENTORYMODELBACKGROUNDFETCH_H -// Seraph clean this up -#include "llassettype.h" -#include "llfoldertype.h" -#include "lldarray.h" -#include "llframetimer.h" -#include "llhttpclient.h" +#include "llsingleton.h"  #include "lluuid.h" -#include "llpermissionsflags.h" -#include "llstring.h" -#include <map> -#include <set> -#include <string> -#include <vector> - -// Seraph clean this up -class LLInventoryObserver; -class LLInventoryObject; -class LLInventoryItem; -class LLInventoryCategory; -class LLViewerInventoryItem; -class LLViewerInventoryCategory; -class LLViewerInventoryItem; -class LLViewerInventoryCategory; -class LLMessageSystem; -class LLInventoryCollectFunctor; -  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLInventoryModelBackgroundFetch  // -// This class handles background fetch. +// This class handles background fetches, which are fetches of +// inventory folder.  Fetches can be recursive or not.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -  class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch>  {  	friend class LLInventoryModelFetchDescendentsResponder; @@ -75,48 +51,37 @@ public:  	~LLInventoryModelBackgroundFetch();  	// Start and stop background breadth-first fetching of inventory contents. -	// This gets triggered when performing a filter-search +	// This gets triggered when performing a filter-search.  	void start(const LLUUID& cat_id = LLUUID::null, BOOL recursive = TRUE); -	BOOL backgroundFetchActive(); -	bool isEverythingFetched(); -	void incrBulkFetch(S16 fetching); -	void stopBackgroundFetch(); // stop fetch process -	bool isBulkFetchProcessingComplete(); -	// Add categories to a list to be fetched in bulk. -	void bulkFetch(std::string url); +	BOOL backgroundFetchActive() const; +	bool isEverythingFetched() const; // completing the fetch once per session should be sufficient -	bool libraryFetchStarted(); -	bool libraryFetchCompleted(); -	bool libraryFetchInProgress(); +	bool libraryFetchStarted() const; +	bool libraryFetchCompleted() const; +	bool libraryFetchInProgress() const; -	bool inventoryFetchStarted(); -	bool inventoryFetchCompleted(); -	bool inventoryFetchInProgress(); -    void findLostItems(); +	bool inventoryFetchStarted() const; +	bool inventoryFetchCompleted() const; +	bool inventoryFetchInProgress() const; -	void setAllFoldersFetched(); +    void findLostItems();	 +protected: +	void incrBulkFetch(S16 fetching); +	bool isBulkFetchProcessingComplete() const; +	void bulkFetch(std::string url); -	static void backgroundFetchCB(void*); // background fetch idle function  	void backgroundFetch(); -	 -	struct FetchQueueInfo -	{ -		FetchQueueInfo(const LLUUID& id, BOOL recursive) : -			mCatUUID(id), mRecursive(recursive) -		{ -		} -		LLUUID mCatUUID; -		BOOL mRecursive; -	}; -protected: +	static void backgroundFetchCB(void*); // background fetch idle function +	void stopBackgroundFetch(); // stop fetch process + +	void setAllFoldersFetched();  	bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const;  private:   	BOOL mRecursiveInventoryFetchStarted;  	BOOL mRecursiveLibraryFetchStarted;  	BOOL mAllFoldersFetched; -	// completing the fetch once per session should be sufficient  	BOOL mBackgroundFetchActive;  	S16 mBulkFetchCount;  	BOOL mTimelyFetchPending; @@ -126,6 +91,15 @@ private:  	F32 mMinTimeBetweenFetches;  	F32 mMaxTimeBetweenFetches; +	struct FetchQueueInfo +	{ +		FetchQueueInfo(const LLUUID& id, BOOL recursive) : +			mCatUUID(id), mRecursive(recursive) +		{ +		} +		LLUUID mCatUUID; +		BOOL mRecursive; +	};  	typedef std::deque<FetchQueueInfo> fetch_queue_t;  	fetch_queue_t mFetchQueue;  }; diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index d2b402fe14..bd35259670 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -62,13 +62,9 @@  #include "llsdutil.h"  #include <deque> -// If the viewer gets a notification, your observer assumes -// that that notification is for itself and then tries to process -// the results.  The notification could be for something else (e.g. -// you're fetching an item and a notification gets triggered because -// you renamed some other item).  This counter is to specify how many -// notification to wait for before giving up. -static const U32 MAX_NUM_NOTIFICATIONS_TO_PROCESS = 127; +const U32 LLInventoryFetchItemsObserver::MAX_NUM_ATTEMPTS_TO_PROCESS = 10; +const F32 LLInventoryFetchItemsObserver::FETCH_TIMER_EXPIRY = 10.0f; +  LLInventoryObserver::LLInventoryObserver()  { @@ -149,7 +145,7 @@ void LLInventoryCompletionObserver::watchItem(const LLUUID& id)  LLInventoryFetchItemsObserver::LLInventoryFetchItemsObserver(const LLUUID& item_id) :  	LLInventoryFetchObserver(item_id), -	mNumTries(MAX_NUM_NOTIFICATIONS_TO_PROCESS) +	mNumTries(MAX_NUM_ATTEMPTS_TO_PROCESS)  {  	mIDs.clear();  	mIDs.push_back(item_id); @@ -158,35 +154,47 @@ LLInventoryFetchItemsObserver::LLInventoryFetchItemsObserver(const LLUUID& item_  LLInventoryFetchItemsObserver::LLInventoryFetchItemsObserver(const uuid_vec_t& item_ids) :  	LLInventoryFetchObserver(item_ids), -	mNumTries(MAX_NUM_NOTIFICATIONS_TO_PROCESS) +	mNumTries(MAX_NUM_ATTEMPTS_TO_PROCESS)  {  }  void LLInventoryFetchItemsObserver::changed(U32 mask)  { -	BOOL any_items_missing = FALSE; -  	// scan through the incomplete items and move or erase them as  	// appropriate.  	if (!mIncomplete.empty())  	{ +		// if period of an attempt expired... +		if (mFetchingPeriod.hasExpired()) +		{ +			// ...reset timer and reduce count of attempts +			mFetchingPeriod.reset(); +			mFetchingPeriod.setTimerExpirySec(FETCH_TIMER_EXPIRY); + +			--mNumTries; + +			LL_INFOS("InventoryFetch") << "LLInventoryFetchItemsObserver: " << this << ", attempt(s) left: " << (S32)mNumTries << LL_ENDL; +		} + +		// do we still have any attempts? +		bool timeout_expired = mNumTries <= 0; +  		for (uuid_vec_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )  		{  			const LLUUID& item_id = (*it);  			LLViewerInventoryItem* item = gInventory.getItem(item_id);  			if (!item)  			{ -				any_items_missing = TRUE; -				if (mNumTries > 0) +				if (timeout_expired)  				{ -					// Keep trying. -					++it; +					// Just concede that this item hasn't arrived in reasonable time and continue on. +					LL_WARNS("InventoryFetch") << "Fetcher timed out when fetching inventory item UUID: " << item_id << LL_ENDL; +					it = mIncomplete.erase(it);  				}  				else  				{ -					// Just concede that this item hasn't arrived in reasonable time and continue on. -					llwarns << "Fetcher timed out when fetching inventory item assetID:" << item_id << llendl; -					it = mIncomplete.erase(it); +					// Keep trying. +					++it;  				}  				continue;  			} @@ -198,14 +206,10 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)  			}  			++it;  		} -		if (any_items_missing) -		{ -			mNumTries--; -		}  		if (mIncomplete.empty())  		{ -			mNumTries = MAX_NUM_NOTIFICATIONS_TO_PROCESS; +			mNumTries = MAX_NUM_ATTEMPTS_TO_PROCESS;  			done();  		}  	} @@ -315,6 +319,10 @@ void LLInventoryFetchItemsObserver::startFetch()  		item_entry["item_id"] = (*it);  		items_llsd.append(item_entry);  	} + +	mFetchingPeriod.resetWithExpiry(FETCH_TIMER_EXPIRY); +	mNumTries = MAX_NUM_ATTEMPTS_TO_PROCESS; +  	fetch_items_from_llsd(items_llsd);  } diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 6d5a86a6fc..72c13f55c6 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -110,6 +110,22 @@ public:  	/*virtual*/ void changed(U32 mask);  private:  	S8 mNumTries; // Number of times changed() was called without success +	LLFrameTimer mFetchingPeriod; + +	/** +	 * If the viewer gets a notification, your observer assumes +	 * that that notification is for itself and then tries to process +	 * the results.  The notification could be for something else (e.g. +	 * you're fetching an item and a notification gets triggered because +	 * you renamed some other item).  This counter is to specify how many +	 * periods of time to wait for before giving up. +	 */ +	static const U32 MAX_NUM_ATTEMPTS_TO_PROCESS; + +	/** +	 * Period of waiting a notification when requested items get added into inventory. +	 */ +	static const F32 FETCH_TIMER_EXPIRY;  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index bb3f34dde2..7d81cf18aa 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -87,6 +87,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mSortOrderSetting(p.sort_order_setting),  	mInventory(p.inventory),  	mAllowMultiSelect(p.allow_multi_select), +	mShowItemLinkOverlays(p.show_item_link_overlays),  	mViewsInitialized(false),  	mStartFolderString(p.start_folder),	  	mBuildDefaultHierarchy(true), @@ -522,6 +523,10 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  				params.name = new_listener->getDisplayName();  				params.icon = new_listener->getIcon();  				params.icon_open = new_listener->getOpenIcon(); +				if (mShowItemLinkOverlays) // if false, then links show up just like normal items +				{ +					params.icon_overlay = LLUI::getUIImage("Inv_Link"); +				}  				params.root = mFolderRoot;  				params.listener = new_listener;  				params.tool_tip = params.name; @@ -560,6 +565,10 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  				params.name = new_listener->getDisplayName();  				params.icon = new_listener->getIcon();  				params.icon_open = new_listener->getOpenIcon(); +				if (mShowItemLinkOverlays) // if false, then links show up just like normal items +				{ +					params.icon_overlay = LLUI::getUIImage("Inv_Link"); +				}  				params.creation_date = new_listener->getCreationDate();  				params.root = mFolderRoot;  				params.listener = new_listener; diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 4373cedf66..67c8904868 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -84,6 +84,7 @@ public:  		Optional<std::string>				sort_order_setting;  		Optional<LLInventoryModel*>			inventory;  		Optional<bool>						allow_multi_select; +		Optional<bool>						show_item_link_overlays;  		Optional<Filter>					filter;  		Optional<std::string>               start_folder; @@ -91,6 +92,7 @@ public:  		:	sort_order_setting("sort_order_setting"),  			inventory("", &gInventory),  			allow_multi_select("allow_multi_select", true), +			show_item_link_overlays("show_item_link_overlays", false),  			filter("filter"),  			start_folder("start_folder")  		{} @@ -177,6 +179,7 @@ protected:  	LLInventoryModel*			mInventory;  	LLInventoryObserver*		mInventoryObserver;  	BOOL 						mAllowMultiSelect; +	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons  	LLFolderView*				mFolderRoot;  	LLScrollContainer*			mScroller; diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 9e1dc3a4b0..c2a1923dfe 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -53,7 +53,6 @@  static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide");  static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn");  static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate"); -static LLDefaultChildRegistry::Register<LLJoystickCameraZoom> r4("joystick_zoom");  static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track"); @@ -647,155 +646,3 @@ void LLJoystickCameraTrack::onHeldDown()  		gAgentCamera.setPanDownKey(getOrbitRate());  	}  } - - - -//------------------------------------------------------------------------------- -// LLJoystickCameraZoom -//------------------------------------------------------------------------------- - -LLJoystickCameraZoom::LLJoystickCameraZoom(const LLJoystickCameraZoom::Params& p) -:	LLJoystick(p), -	mInTop( FALSE ), -	mInBottom( FALSE ), -	mPlusInImage(p.plus_image), -	mMinusInImage(p.minus_image) -{ -} - -BOOL LLJoystickCameraZoom::handleMouseDown(S32 x, S32 y, MASK mask) -{ -	BOOL handled = LLJoystick::handleMouseDown(x, y, mask); - -	if( handled ) -	{ -		if (mFirstMouse.mY > getRect().getHeight() / 2) -		{ -			mInitialQuadrant = JQ_UP; -		} -		else -		{ -			mInitialQuadrant = JQ_DOWN; -		} -	} -	return handled; -} - - -void LLJoystickCameraZoom::onHeldDown() -{ -	updateSlop(); - -	const F32 FAST_RATE = 2.5f; // two and a half times the normal rate - -	S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY; - -	if (dy > mVertSlopFar) -	{ -		// Zoom in fast -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitInKey(FAST_RATE); -	} -	else if (dy > mVertSlopNear) -	{ -		// Zoom in slow -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitInKey(getOrbitRate()); -	} -	else if (dy < -mVertSlopFar) -	{ -		// Zoom out fast -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitOutKey(FAST_RATE); -	} -	else if (dy < -mVertSlopNear) -	{ -		// Zoom out slow -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitOutKey(getOrbitRate()); -	} -} - -// Only used for drawing -void LLJoystickCameraZoom::setToggleState( BOOL top, BOOL bottom ) -{ -	mInTop = top; -	mInBottom = bottom; -} - -void LLJoystickCameraZoom::draw() -{ -	if( mInTop ) -	{ -		mPlusInImage->draw(0,0); -	} -	else -	if( mInBottom ) -	{ -		mMinusInImage->draw(0,0); -	} -	else -	{ -		getImageUnselected()->draw( 0, 0 ); -	} -} - -void LLJoystickCameraZoom::updateSlop() -{ -	mVertSlopNear = getRect().getHeight() / 4; -	mVertSlopFar = getRect().getHeight() / 2; - -	mHorizSlopNear = getRect().getWidth() / 4; -	mHorizSlopFar = getRect().getWidth() / 2; - -	// Compute initial mouse offset based on initial quadrant. -	// Place the mouse evenly between the near and far zones. -	switch (mInitialQuadrant) -	{ -	case JQ_ORIGIN: -		mInitialOffset.set(0, 0); -		break; - -	case JQ_UP: -		mInitialOffset.mX = 0; -		mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2; -		break; - -	case JQ_DOWN: -		mInitialOffset.mX = 0; -		mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2; -		break; - -	case JQ_LEFT: -		mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2; -		mInitialOffset.mY = 0; -		break; - -	case JQ_RIGHT: -		mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2; -		mInitialOffset.mY = 0; -		break; - -	default: -		llerrs << "LLJoystick::LLJoystick() - bad switch case" << llendl; -		break; -	} - -	return; -} - - -F32 LLJoystickCameraZoom::getOrbitRate() -{ -	F32 time = getElapsedHeldDownTime(); -	if( time < NUDGE_TIME ) -	{ -		F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; -//		llinfos << "rate " << rate << " time " << time << llendl; -		return rate; -	} -	else -	{ -		return 1; -	} -} diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 2b071a8999..1dd30036ab 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -183,44 +183,4 @@ public:  	virtual void	onHeldDown();  }; - -// Zoom the camera in and out -class LLJoystickCameraZoom -:	public LLJoystick -{ -public: -	struct Params  -	:	public LLInitParam::Block<Params, LLJoystick::Params> -	{ -		Optional<LLUIImage*>	plus_image; -		Optional<LLUIImage*>	minus_image; - -		Params() -		: plus_image ("plus_image", NULL), -		  minus_image ("minus_image", NULL) -		{ -			held_down_delay.seconds(0.0); -		} -	}; -	LLJoystickCameraZoom(const Params&); - -	virtual void	setToggleState( BOOL top, BOOL bottom ); - -	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask); -	virtual void	onHeldDown(); -	virtual void	draw(); - -protected: -	virtual void updateSlop(); -	F32				getOrbitRate(); - -protected: -	BOOL			mInTop; -	BOOL			mInBottom; -	LLUIImagePtr	mPlusInImage; -	LLUIImagePtr	mMinusInImage; -}; - - -  #endif  // LL_LLJOYSTICKBUTTON_H diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index f1c13de8bb..1beaaf3cb4 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -49,7 +49,6 @@  #include "llchannelmanager.h"  #include "llagent.h" 			// gAgent -#include "llfloaterscriptdebug.h"  #include "llchathistory.h"  #include "llstylemap.h" @@ -163,25 +162,6 @@ std::string appendTime()  void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)  { -	if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) -	{ -		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) -			return; -		if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat")) -		{ - -			LLColor4 txt_color; - -			LLViewerChat::getChatColor(chat,txt_color); -			 -			LLFloaterScriptDebug::addScriptLine(chat.mText, -												chat.mFromName,  -												txt_color,  -												chat.mFromID); -			return; -		} -	} -  	LLChat& tmp_chat = const_cast<LLChat&>(chat);  	if(tmp_chat.mTimeStr.empty()) diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 9824517ed1..4b5e765c4f 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -36,6 +36,7 @@  #include "llbottomtray.h"  #include "llchatitemscontainerctrl.h" +#include "llfloaterscriptdebug.h"  #include "llnearbychat.h"  #include "llrecentpeople.h" @@ -287,7 +288,7 @@ void LLNearbyChatScreenChannel::showToastsBottom()  		toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());  		toast->setRect(toast_rect); -		bottom += toast_rect.getHeight() + margin; +		bottom += toast_rect.getHeight() - toast->getTopPad() + margin;  	}  	// use reverse order to provide correct z-order and avoid toast blinking @@ -358,6 +359,29 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  		//if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null)  		//	tmp_chat.mFromName = tmp_chat.mFromID.asString();  	} + +	// don't show toast and add message to chat history on receive debug message +	// with disabled setting showing script errors or enabled setting to show script +	// errors in separate window. +	if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG) +	{ +		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) +			return; +		if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat")) +		{ + +			LLColor4 txt_color; + +			LLViewerChat::getChatColor(chat_msg,txt_color); + +			LLFloaterScriptDebug::addScriptLine(chat_msg.mText, +												chat_msg.mFromName, +												txt_color, +												chat_msg.mFromID); +			return; +		} +	} +  	nearby_chat->addMessage(chat_msg, true, args);  	if( nearby_chat->getVisible()  		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp new file mode 100644 index 0000000000..efa01bade9 --- /dev/null +++ b/indra/newview/lloutfitobserver.cpp @@ -0,0 +1,150 @@ +/** + * @file lloutfitobserver.cpp + * @brief Outfit observer facade. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llappearancemgr.h" +#include "lloutfitobserver.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" + +LLOutfitObserver::LLOutfitObserver() : +	mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) +{ +	gInventory.addObserver(this); +} + +LLOutfitObserver::~LLOutfitObserver() +{ +	if (gInventory.containsObserver(this)) +	{ +		gInventory.removeObserver(this); +	} +} + +void LLOutfitObserver::changed(U32 mask) +{ +	if (!gInventory.isInventoryUsable()) +		return; + +	bool COF_changed = checkCOF(); + +	if (!COF_changed) +	{ +		checkBaseOutfit(); +	} +} + +// static +S32 LLOutfitObserver::getCategoryVersion(const LLUUID& cat_id) +{ +	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); +	if (!cat) +		return LLViewerInventoryCategory::VERSION_UNKNOWN; + +	return cat->getVersion(); +} + +// static +const std::string& LLOutfitObserver::getCategoryName(const LLUUID& cat_id) +{ +	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); +	if (!cat) +		return LLStringUtil::null; + +	return cat->getName(); +} + +bool LLOutfitObserver::checkCOF() +{ +	LLUUID cof = LLAppearanceMgr::getInstance()->getCOF(); +	if (cof.isNull()) +		return false; + +	S32 cof_version = getCategoryVersion(cof); + +	if (cof_version == mCOFLastVersion) +		return false; + +	mCOFLastVersion = cof_version; + +	// dirtiness state should be updated before sending signal +	LLAppearanceMgr::getInstance()->updateIsDirty(); +	mCOFChanged(); + +	return true; +} + +void LLOutfitObserver::checkBaseOutfit() +{ +	LLUUID baseoutfit_id = +			LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); + +	if (baseoutfit_id == mBaseOutfitId) +	{ +		if (baseoutfit_id.isNull()) +			return; + +		const S32 baseoutfit_ver = getCategoryVersion(baseoutfit_id); +		const std::string& baseoutfit_name = getCategoryName(baseoutfit_id); + +		if (baseoutfit_ver == mBaseOutfitLastVersion +				// renaming category doesn't change version, so it's need to check it +				&& baseoutfit_name == mLastBaseOutfitName) +			return; +	} +	else +	{ +		mBaseOutfitId = baseoutfit_id; +		mBOFReplaced(); + +		if (baseoutfit_id.isNull()) +			return; +	} + +	mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId); +	mLastBaseOutfitName = getCategoryName(baseoutfit_id); + +	LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance(); +	// dirtiness state should be updated before sending signal +	app_mgr.updateIsDirty(); +	mBOFChanged(); + +	if (mLastOutfitDirtiness != app_mgr.isOutfitDirty()) +	{ +		if(!app_mgr.isOutfitDirty()) +		{ +			mCOFSaved(); +		} +		mLastOutfitDirtiness = app_mgr.isOutfitDirty(); +	} +} diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h new file mode 100644 index 0000000000..3a66b5ea9f --- /dev/null +++ b/indra/newview/lloutfitobserver.h @@ -0,0 +1,99 @@ +/** + * @file lloutfitobserver.h + * @brief Outfit observer facade. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_OUTFITOBSERVER_H +#define LL_OUTFITOBSERVER_H + +#include "llsingleton.h" + +/** + * Outfit observer facade that provides simple possibility to subscribe on + * BOF(base outfit) replaced, BOF changed, COF(current outfit) changed events. + */ +class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitObserver> +{ +public: +	virtual ~LLOutfitObserver(); + +	friend class LLSingleton<LLOutfitObserver>; + +	virtual void changed(U32 mask); + +	void notifyOutfitLockChanged() { mOutfitLockChanged();  } + +	typedef boost::signals2::signal<void (void)> signal_t; + +	void addBOFReplacedCallback(const signal_t::slot_type& cb) { mBOFReplaced.connect(cb); } + +	void addBOFChangedCallback(const signal_t::slot_type& cb) { mBOFChanged.connect(cb); } + +	void addCOFChangedCallback(const signal_t::slot_type& cb) { mCOFChanged.connect(cb); } + +	void addCOFSavedCallback(const signal_t::slot_type& cb) { mCOFSaved.connect(cb); } + +	void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); } + +protected: +	LLOutfitObserver(); + +	/** Get a version of an inventory category specified by its UUID */ +	static S32 getCategoryVersion(const LLUUID& cat_id); + +	static const std::string& getCategoryName(const LLUUID& cat_id); + +	bool checkCOF(); + +	void checkBaseOutfit(); + +	//last version number of a COF category +	S32 mCOFLastVersion; + +	LLUUID mBaseOutfitId; + +	S32 mBaseOutfitLastVersion; +	std::string mLastBaseOutfitName; + +	bool mLastOutfitDirtiness; + +private: +	signal_t mBOFReplaced; +	signal_t mBOFChanged; +	signal_t mCOFChanged; +	signal_t mCOFSaved; + +	/** +	 * Signal for changing state of outfit lock. +	 */ +	signal_t mOutfitLockChanged; +}; + +#endif /* LL_OUTFITOBSERVER_H */ diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 77db280487..bca292fa4a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -44,6 +44,7 @@  #include "llinventorymodel.h"  #include "lllistcontextmenu.h"  #include "llnotificationsutil.h" +#include "lloutfitobserver.h"  #include "llsidetray.h"  #include "lltransutil.h"  #include "llviewermenu.h" @@ -53,6 +54,20 @@  static bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y); +static const LLOutfitTabNameComparator OUTFIT_TAB_NAME_COMPARATOR; + +/*virtual*/ +bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const +{ +	std::string name1 = tab1->getTitle(); +	std::string name2 = tab2->getTitle(); + +	LLStringUtil::toUpper(name1); +	LLStringUtil::toUpper(name2); + +	return name1 < name2; +} +  //////////////////////////////////////////////////////////////////////////  class OutfitContextMenu : public LLListContextMenu @@ -158,6 +173,7 @@ LLOutfitsList::~LLOutfitsList()  BOOL LLOutfitsList::postBuild()  {  	mAccordion = getChild<LLAccordionCtrl>("outfits_accordion"); +	mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);  	return TRUE;  } @@ -184,6 +200,9 @@ void LLOutfitsList::onOpen(const LLSD& /*info*/)  		mCategoriesObserver->addCategory(outfits,  			boost::bind(&LLOutfitsList::refreshList, this, outfits)); +		// Start observing changes in Current Outfit to update items worn state. +		LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLOutfitsList::onCOFChanged, this)); +  		// Fetch "My Outfits" contents and refresh the list to display  		// initially fetched items. If not all items are fetched now  		// the observer will refresh the list as soon as the new items @@ -307,7 +326,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  			// 3. Reset currently selected outfit id if it is being removed.  			if (outfit_id == mSelectedOutfitUUID)  			{ -				mSelectedOutfitUUID = LLUUID(); +				setSelectedOutfitUUID(LLUUID());  			}  			// 4. Remove category UUID to accordion tab mapping. @@ -328,7 +347,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  		updateOutfitTab(*items_iter);  	} -	mAccordion->arrange(); +	mAccordion->sort();  }  void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl) @@ -370,6 +389,11 @@ void LLOutfitsList::setFilterSubString(const std::string& string)  	mFilterSubString = string;  } +boost::signals2::connection LLOutfitsList::addSelectionChangeCallback(selection_change_callback_t cb) +{ +	return mSelectionChangeSignal.connect(cb); +} +  //////////////////////////////////////////////////////////////////////////  // Private methods  ////////////////////////////////////////////////////////////////////////// @@ -456,7 +480,12 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI  	}  	mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list)); -	mSelectedOutfitUUID = category_id; +	setSelectedOutfitUUID(category_id); +} + +void LLOutfitsList::setSelectedOutfitUUID(const LLUUID& category_id) +{ +	mSelectionChangeSignal(mSelectedOutfitUUID = category_id);  }  void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl) @@ -500,6 +529,8 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)  void LLOutfitsList::applyFilter(const std::string& new_filter_substring)  { +	mAccordion->setFilterSubString(new_filter_substring); +  	for (outfits_map_t::iterator  			 iter = mOutfitsMap.begin(),  			 iter_end = mOutfitsMap.end(); @@ -628,6 +659,43 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)  	LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y);  } +void LLOutfitsList::onCOFChanged() +{ +	LLInventoryModel::changed_items_t changed_linked_items; + +	const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); +	for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items.begin(); +		 iter != changed_items.end(); +		 ++iter) +	{ +		LLViewerInventoryItem* item = gInventory.getItem(*iter); +		if (item) +		{ +			// From gInventory we get the UUIDs of new links added to COF +			// or removed from COF. These links UUIDs are not the same UUIDs +			// that we have in each wearable items list. So we collect base items +			// UUIDs to find all items or links that point to same base items in wearable +			// items lists and update their worn state there. +			changed_linked_items.insert(item->getLinkedUUID()); +		} +	} + +	for (outfits_map_t::iterator iter = mOutfitsMap.begin(); +			iter != mOutfitsMap.end(); +			++iter) +	{ +		LLAccordionCtrlTab* tab = iter->second; +		if (!tab) continue; + +		LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); +		if (!list) continue; + +		// Every list updates the labels of changed items  or +		// the links that point to these items. +		list->updateChangedItems(changed_linked_items); +	} +} +  bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)  {  	if(!tab || !tab->getHeaderVisible()) return false; diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 44f6ec908b..478eaa50b3 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -32,18 +32,34 @@  #ifndef LL_LLOUTFITSLIST_H  #define LL_LLOUTFITSLIST_H +#include "llaccordionctrl.h"  #include "llpanel.h"  // newview  #include "llinventorymodel.h"  #include "llinventoryobserver.h" -class LLAccordionCtrl;  class LLAccordionCtrlTab;  class LLWearableItemsList;  class LLListContextMenu;  /** + * @class LLOutfitTabNameComparator + * + * Comparator of outfit tabs. + */ +class LLOutfitTabNameComparator : public LLAccordionCtrl::LLTabComparator +{ +	LOG_CLASS(LLOutfitTabNameComparator); + +public: +	LLOutfitTabNameComparator() {}; +	virtual ~LLOutfitTabNameComparator() {}; + +	/*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const; +}; + +/**   * @class LLOutfitsList   *   * A list of agents's outfits from "My Outfits" inventory category @@ -55,6 +71,9 @@ class LLListContextMenu;  class LLOutfitsList : public LLPanel  {  public: +	typedef boost::function<void (const LLUUID&)> selection_change_callback_t; +	typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t; +  	LLOutfitsList();  	virtual ~LLOutfitsList(); @@ -70,6 +89,8 @@ public:  	const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } +	boost::signals2::connection addSelectionChangeCallback(selection_change_callback_t cb); +  private:  	/**  	 * Reads xml with accordion tab and Flat list from xml file. @@ -94,6 +115,11 @@ private:  	void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);  	/** +	 * Saves newly selected outfit ID. +	 */ +	void setSelectedOutfitUUID(const LLUUID& category_id); + +	/**  	 * Called upon list refresh event to update tab visibility depending on  	 * the results of applying filter to the title and list items of the tab.  	 */ @@ -107,6 +133,7 @@ private:  	void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);  	void onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);  	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); +	void onCOFChanged();  	void onSelectionChange(LLUICtrl* ctrl); @@ -122,6 +149,7 @@ private:  	wearables_lists_map_t			mSelectedListsMap;  	LLUUID							mSelectedOutfitUUID; +	selection_change_signal_t		mSelectionChangeSignal;  	std::string 					mFilterSubString; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index a1a9300ec2..1aedfec86f 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -61,6 +61,9 @@  #include "llagentcamera.h"  #include "llmorphview.h" +#include "llcommandhandler.h" +#include "lltextutil.h" +  // register panel with appropriate XML  static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable"); @@ -608,6 +611,36 @@ LLPanelEditWearable::~LLPanelEditWearable()  } +bool LLPanelEditWearable::changeHeightUnits(const LLSD& new_value) +{ +	updateMetricLayout( new_value.asBoolean() ); +	updateTypeSpecificControls(LLWearableType::WT_SHAPE); +	return true; +} + +void LLPanelEditWearable::updateMetricLayout(BOOL new_value) +{ +	LLUIString current_metric, replacment_metric; +	current_metric = new_value ? mMeters : mFeet; +	replacment_metric = new_value ? mFeet : mMeters; +	mHeigthValue.setArg( "[METRIC1]", current_metric.getString() ); +	mReplacementMetricUrl.setArg( "[URL_METRIC2]", std::string("[secondlife:///app/metricsystem ") + replacment_metric.getString() + std::string("]")); +} + +void LLPanelEditWearable::updateAvatarHeightLabel() +{ +	mTxtAvatarHeight->setText(LLStringUtil::null); +	LLStyle::Params param; +	param.color = mAvatarHeigthLabelColor; +	mTxtAvatarHeight->appendText(mHeigth, false, param); +	param.color = mAvatarHeigthValueLabelColor; +	mTxtAvatarHeight->appendText(mHeigthValue, false, param); +	param.color = mAvatarHeigthLabelColor; // using mAvatarHeigthLabelColor for '/' separator +	mTxtAvatarHeight->appendText(" / ", false, param); +	mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param); +} + +  // virtual   BOOL LLPanelEditWearable::postBuild()  { @@ -700,6 +733,20 @@ BOOL LLPanelEditWearable::postBuild()  		for_each_picker_ctrl_entry <LLTextureCtrl>     (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2));  	} +	// init all strings +	mMeters		= mPanelShape->getString("meters"); +	mFeet		= mPanelShape->getString("feet"); +	mHeigth		= mPanelShape->getString("height") + " "; +	mHeigthValue	= "[HEIGHT] [METRIC1]"; +	mReplacementMetricUrl	= "[URL_METRIC2]"; + +	std::string color = mPanelShape->getString("heigth_label_color"); +	mAvatarHeigthLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green); +	color = mPanelShape->getString("heigth_value_label_color"); +	mAvatarHeigthValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green); +	gSavedSettings.getControl("HeightUnits")->getSignal()->connect(boost::bind(&LLPanelEditWearable::changeHeightUnits, this, _2)); +	updateMetricLayout(gSavedSettings.getBOOL("HeightUnits")); +  	return TRUE;  } @@ -1107,12 +1154,22 @@ void LLPanelEditWearable::toggleTypeSpecificControls(LLWearableType::EType type)  void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type)  { +	const F32 ONE_METER = 1.0; +	const F32 ONE_FOOT = 0.3048 * ONE_METER; // in meters  	// Update controls specific to shape editing panel.  	if (type == LLWearableType::WT_SHAPE)  	{  		// Update avatar height -		std::string avatar_height_str = llformat("%.2f", gAgentAvatarp->mBodySize.mV[VZ]); -		mTxtAvatarHeight->setTextArg("[HEIGHT]", avatar_height_str); +		F32 new_size = gAgentAvatarp->mBodySize.mV[VZ]; +		if (gSavedSettings.getBOOL("HeightUnits") == FALSE) +		{ +			// convert meters to feet +			new_size = new_size / ONE_FOOT; +		} + +		std::string avatar_height_str = llformat("%.2f", new_size); +		mHeigthValue.setArg("[HEIGHT]", avatar_height_str); +		updateAvatarHeightLabel();  	}  	if (LLWearableType::WT_ALPHA == type) @@ -1381,4 +1438,21 @@ void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::EText  	}  } +// handle secondlife:///app/metricsystem +class LLMetricSystemHandler : public LLCommandHandler +{ +public: +	LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_THROTTLE) { } + +	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) +	{ +		// change height units TRUE for meters and FALSE for feet +		BOOL new_value = (gSavedSettings.getBOOL("HeightUnits") == FALSE) ? TRUE : FALSE; +		gSavedSettings.setBOOL("HeightUnits", new_value); +		return true; +	} +}; + +LLMetricSystemHandler gMetricSystemHandler; +  // EOF diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 54f729fa7a..c63671fcc9 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -104,6 +104,15 @@ private:  	void initPreviousAlphaTextures();  	void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te); +	// callback for HeightUnits parameter. +	bool changeHeightUnits(const LLSD& new_value); + +	// updates current metric and replacemet metric label text +	void updateMetricLayout(BOOL new_value); + +	// updates avatar height label +	void updateAvatarHeightLabel(); +  	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.  	LLWearable *mWearablePtr;  	LLViewerInventoryItem* mWearableItem; @@ -117,6 +126,18 @@ private:  	LLTextBox *mTxtAvatarHeight; +	// localized and parametrized strings that used to build avatar_height_label +	std::string mMeters; +	std::string mFeet; +	std::string mHeigth; +	LLUIString  mHeigthValue; +	LLUIString  mReplacementMetricUrl; + +	// color for mHeigth string +	LLUIColor mAvatarHeigthLabelColor; +	// color for mHeigthValue string +	LLUIColor mAvatarHeigthValueLabelColor; +  	// This text editor reference will change each time we edit a new wearable -   	// it will be grabbed from the currently visible panel  	LLTextEditor *mTextEditor; diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 42ff514f09..ba50081fb2 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -338,7 +338,6 @@ void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)  	std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),  										inv_item->getInventoryType(),  										inv_item->getFlags(), -										inv_item->getIsLinkType(),  										item_is_multi );  	mCreateInventoryIcon->setValue(icon_name); diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 7fb46fc84f..ce1131f45c 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -334,7 +334,7 @@ void LLLandmarksPanel::updateVerbs()  	bool landmark_selected = isLandmarkSelected();  	mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport"));  	mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info")); -	mShowOnMapBtn->setEnabled(true); +	mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map"));  	// TODO: mantipov: Uncomment when mShareBtn is supported  	// Share button should be enabled when neither a folder nor a landmark is selected diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index c557e9b85d..ad3a5c2380 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -351,7 +351,7 @@ LLUIImagePtr LLTaskInvFVBridge::getIcon() const  {  	const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS); -	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, FALSE, 0, item_is_multi ); +	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi );  }  void LLTaskInvFVBridge::openItem() @@ -1236,7 +1236,7 @@ public:  LLUIImagePtr LLTaskWearableBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, FALSE, mFlags, FALSE ); +	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );  } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 4982e98f8e..32b209dd0d 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -39,6 +39,7 @@  #include "llagentcamera.h"  #include "llagentwearables.h"  #include "llappearancemgr.h" +#include "lloutfitobserver.h"  #include "llcofwearables.h"  #include "llfilteredwearablelist.h"  #include "llinventory.h" @@ -143,100 +144,6 @@ private:  	}  }; -class LLCOFObserver : public LLInventoryObserver -{ -public: -	LLCOFObserver(LLPanelOutfitEdit *panel) : mPanel(panel),  -		mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) -	{ -		gInventory.addObserver(this); -	} - -	virtual ~LLCOFObserver() -	{ -		if (gInventory.containsObserver(this)) -		{ -			gInventory.removeObserver(this); -		} -	} -	 -	virtual void changed(U32 mask) -	{ -		if (!gInventory.isInventoryUsable()) return; -	 -		bool panel_updated = checkCOF(); - -		if (!panel_updated) -		{ -			checkBaseOutfit(); -		} -	} - -protected: - -	/** Get a version of an inventory category specified by its UUID */ -	static S32 getCategoryVersion(const LLUUID& cat_id) -	{ -		LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); -		if (!cat) return LLViewerInventoryCategory::VERSION_UNKNOWN; - -		return cat->getVersion(); -	} - -	bool checkCOF() -	{ -		LLUUID cof = LLAppearanceMgr::getInstance()->getCOF(); -		if (cof.isNull()) return false; - -		S32 cof_version = getCategoryVersion(cof); - -		if (cof_version == mCOFLastVersion) return false; -		 -		mCOFLastVersion = cof_version; - -		mPanel->update(); - -		return true; -	} - -	void checkBaseOutfit() -	{ -		LLUUID baseoutfit_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); - -		if (baseoutfit_id == mBaseOutfitId) -		{ -			if (baseoutfit_id.isNull()) return; - -			const S32 baseoutfit_ver = getCategoryVersion(baseoutfit_id); - -			if (baseoutfit_ver == mBaseOutfitLastVersion) return; -		} -		else -		{ -			mBaseOutfitId = baseoutfit_id; -			mPanel->updateCurrentOutfitName(); - -			if (baseoutfit_id.isNull()) return; - -			mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId); -		} - -		mPanel->updateVerbs(); -	} -	 - - - -	LLPanelOutfitEdit *mPanel; - -	//last version number of a COF category -	S32 mCOFLastVersion; - -	LLUUID  mBaseOutfitId; - -	S32 mBaseOutfitLastVersion; -}; -  class LLCOFDragAndDropObserver : public LLInventoryAddItemByAssetObserver  {  public: @@ -277,18 +184,23 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()  	mSearchFilter(NULL),  	mCOFWearables(NULL),  	mInventoryItemsPanel(NULL), -	mCOFObserver(NULL),  	mGearMenu(NULL),  	mCOFDragAndDropObserver(NULL),  	mInitialized(false),  	mAddWearablesPanel(NULL),  	mWearableListMaskCollector(NULL), -	mWearableListTypeCollector(NULL) +	mWearableListTypeCollector(NULL), +	mFilterComboBox(NULL)  {  	mSavedFolderState = new LLSaveFolderState();  	mSavedFolderState->setApply(FALSE); -	mCOFObserver = new LLCOFObserver(this); + +	LLOutfitObserver& observer = LLOutfitObserver::instance(); +	observer.addBOFReplacedCallback(boost::bind(&LLPanelOutfitEdit::updateCurrentOutfitName, this)); +	observer.addBOFChangedCallback(boost::bind(&LLPanelOutfitEdit::updateVerbs, this)); +	observer.addOutfitLockChangedCallback(boost::bind(&LLPanelOutfitEdit::updateVerbs, this)); +	observer.addCOFChangedCallback(boost::bind(&LLPanelOutfitEdit::update, this));  	mLookItemTypes.reserve(NUM_LOOK_ITEM_TYPES);  	for (U32 i = 0; i < NUM_LOOK_ITEM_TYPES; i++) @@ -303,7 +215,6 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()  {  	delete mSavedFolderState; -	delete mCOFObserver;  	delete mCOFDragAndDropObserver;  	delete mWearableListMaskCollector; @@ -325,12 +236,13 @@ BOOL LLPanelOutfitEdit::postBuild()  	mListViewBtn = getChild<LLButton>("list_view_btn");  	childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL); -	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL); -	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL); +	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesFolderView, this), NULL); +	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL);  	childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); +	childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);  	mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list"); -	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this)); +	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this));  	mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this);  	mCOFWearables->getCOFCallbacks().mEditWearable = boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this); @@ -348,19 +260,20 @@ BOOL LLPanelOutfitEdit::postBuild()  	mCOFDragAndDropObserver = new LLCOFDragAndDropObserver(mInventoryItemsPanel->getModel()); -	LLComboBox* type_filter = getChild<LLComboBox>("filter_wearables_combobox"); -	type_filter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); -	type_filter->removeall(); +	mFilterComboBox = getChild<LLComboBox>("filter_wearables_combobox"); +	mFilterComboBox->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); +	mFilterComboBox->removeall();  	for (U32 i = 0; i < mLookItemTypes.size(); ++i)  	{ -		type_filter->add(mLookItemTypes[i].displayName); +		mFilterComboBox->add(mLookItemTypes[i].displayName);  	} -	type_filter->setCurrentByIndex(LIT_ALL); +	mFilterComboBox->setCurrentByIndex(LIT_ALL);  	mSearchFilter = getChild<LLFilterEditor>("look_item_filter");  	mSearchFilter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onSearchEdit, this, _2)); -	childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); +	childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::onAddMoreButtonClicked, this)); +  	childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this));  	mEditWearableBtn = getChild<LLButton>("edit_wearable_btn"); @@ -371,7 +284,7 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));  	mWearableListMaskCollector = new LLFindNonLinksByMask(ALL_ITEMS_MASK); -	mWearableListTypeCollector = new LLFindWearablesOfType(LLWearableType::WT_NONE); +	mWearableListTypeCollector = new LLFindActualWearablesOfType(LLWearableType::WT_NONE);  	mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel");  	mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list"); @@ -443,7 +356,7 @@ void LLPanelOutfitEdit::showWearablesFilter()  	}  } -void LLPanelOutfitEdit::showFilteredWearablesPanel() +void LLPanelOutfitEdit::showWearablesListView()  {  	if(switchPanels(mInventoryItemsPanel, mWearableItemsPanel))  	{ @@ -454,7 +367,7 @@ void LLPanelOutfitEdit::showFilteredWearablesPanel()  	mListViewBtn->setToggleState(TRUE);  } -void LLPanelOutfitEdit::showFilteredFolderWearablesPanel() +void LLPanelOutfitEdit::showWearablesFolderView()  {  	if(switchPanels(mWearableItemsPanel, mInventoryItemsPanel))  	{ @@ -467,17 +380,12 @@ void LLPanelOutfitEdit::showFilteredFolderWearablesPanel()  void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)  { -	LLComboBox* type_filter = dynamic_cast<LLComboBox*>(ctrl); -	llassert(type_filter); -	if (type_filter) -	{ -		U32 curr_filter_type = type_filter->getCurrentIndex(); -		mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask); +	U32 curr_filter_type = mFilterComboBox->getCurrentIndex(); +	mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask); + +	mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); +	mWearableListManager->setFilterCollector(mWearableListMaskCollector); -		mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); -		mWearableListManager->setFilterCollector(mWearableListMaskCollector); -	} -	  	mSavedFolderState->setApply(TRUE);  	mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -561,7 +469,7 @@ void LLPanelOutfitEdit::onAddWearableClicked(void)  	if(item)  	{ -		showFilteredWearableItemsList(item->getWearableType()); +		showFilteredWearablesListView(item->getWearableType());  	}  } @@ -571,7 +479,7 @@ void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id  	if (item && item->getType() == LLAssetType::AT_BODYPART)  	{ -		showFilteredWearableItemsList(item->getWearableType()); +		showFilteredWearablesListView(item->getWearableType());  	}  } @@ -585,35 +493,10 @@ void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)  void LLPanelOutfitEdit::onEditWearableClicked(void)  { -	LLUUID id_to_edit = mCOFWearables->getSelectedUUID(); -	LLViewerInventoryItem * item_to_edit = gInventory.getItem(id_to_edit); - -	if (item_to_edit) +	LLUUID selected_item_id = mCOFWearables->getSelectedUUID(); +	if (selected_item_id.notNull())  	{ -		// returns null if not a wearable (attachment, etc). -		LLWearable* wearable_to_edit = gAgentWearables.getWearableFromAssetID(item_to_edit->getAssetUUID()); -		if(wearable_to_edit) -		{ -			bool can_modify = false; -			bool is_complete = item_to_edit->isFinished(); -			// if item_to_edit is a link, its properties are not appropriate,  -			// lets get original item with actual properties -			LLViewerInventoryItem* original_item = gInventory.getItem(wearable_to_edit->getItemID()); -			if(original_item) -			{ -				can_modify = original_item->getPermissions().allowModifyBy(gAgentID); -				is_complete = original_item->isFinished(); -			} - -			if (can_modify && is_complete) -			{											  -				LLSidepanelAppearance::editWearable(wearable_to_edit, getParent()); -				if (mEditWearableBtn->getVisible()) -				{ -					mEditWearableBtn->setVisible(FALSE); -				} -			} -		} +		gAgentWearables.editWearable(selected_item_id);  	}  } @@ -653,24 +536,81 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView  	current_item->addChild(mAddToLookBtn); */  } -void LLPanelOutfitEdit::onOutfitItemSelectionChange(void) -{	 -	LLUUID item_id = mCOFWearables->getSelectedUUID(); -	//*TODO show Edit Wearable Button +void LLPanelOutfitEdit::applyFilter(e_look_item_type type) +{ +	mFilterComboBox->setCurrentByIndex(type); +	mFilterComboBox->onCommit(); +} + +void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) +{ +	if (!mAddWearablesPanel->getVisible()) return; +	 +	uuid_vec_t ids; +	mCOFWearables->getSelectedUUIDs(ids); -	LLViewerInventoryItem* item_to_remove = gInventory.getItem(item_id); -	if (!item_to_remove) return; +	bool nothing_selected = ids.empty(); +	bool one_selected = ids.size() == 1; +	bool more_than_one_selected = ids.size() > 1; +	bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem())); -	switch (item_to_remove->getType()) +	//resetting selection if no item is selected or than one item is selected +	if (nothing_selected || more_than_one_selected)  	{ -	case LLAssetType::AT_CLOTHING: -	case LLAssetType::AT_OBJECT: -	default: -		break; +		if (nothing_selected) +		{ +			showWearablesFolderView(); +		} + +		if (more_than_one_selected) +		{ +			showWearablesListView(); +		} +		 +		applyFilter(LIT_ALL); +		return; +	} + + +	//filter wearables by a type represented by a dummy item +	if (one_selected && is_dummy_item) +	{ +		onAddWearableClicked(); +		return; +	} + +	LLViewerInventoryItem* item = gInventory.getItem(ids[0]); +	if (!item && ids[0].notNull()) +	{ +		//Inventory misses an item with non-zero id +		showWearablesListView(); +		applyFilter(LIT_ALL); +		return;  	} + +	if (one_selected && !is_dummy_item) +	{ +		if (item->isWearableType()) +		{ +			//single clothing or bodypart item is selected +			showFilteredWearablesListView(item->getWearableType()); +			mFilterComboBox->setLabel(getString("Filter.Custom")); +			return; +		} +		else +		{ +			//attachment is selected +			showWearablesListView(); +			applyFilter(LIT_ATTACHMENT); +			return; +		} +	} +  } + +  void LLPanelOutfitEdit::update()  {  	mCOFWearables->refresh(); @@ -756,19 +696,18 @@ void LLPanelOutfitEdit::updateCurrentOutfitName()  //private  void LLPanelOutfitEdit::updateVerbs()  { -	//*TODO implement better handling of COF dirtiness -	LLAppearanceMgr::getInstance()->updateIsDirty(); -  	bool outfit_is_dirty = LLAppearanceMgr::getInstance()->isOutfitDirty(); +	bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();  	bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull(); -	mSaveComboBtn->setSaveBtnEnabled(outfit_is_dirty); +	mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty);  	childSetEnabled(REVERT_BTN, outfit_is_dirty && has_baseoutfit); -	mSaveComboBtn->setMenuItemEnabled("save_outfit", outfit_is_dirty); +	mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty);  	mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing")); +	updateCurrentOutfitName();  }  bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel) @@ -793,12 +732,21 @@ void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)  	LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);  } -void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type) +void LLPanelOutfitEdit::onAddMoreButtonClicked() +{ +	toggleAddWearablesPanel(); +	filterWearablesBySelectedItem(); +} + +void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type)  { +	mFilterComboBox->setLabel(getString("Filter.Custom"));  	mWearableListTypeCollector->setType(type);  	mWearableListManager->setFilterCollector(mWearableListTypeCollector);  	showAddWearablesPanel(true); -	showFilteredWearablesPanel(); +	showWearablesListView();  } + +  // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 802386c573..d19ede04f1 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -47,9 +47,10 @@  class LLButton;  class LLCOFWearables; +class LLComboBox;  class LLTextBox;  class LLInventoryCategory; -class LLCOFObserver; +class LLOutfitObserver;  class LLCOFDragAndDropObserver;  class LLInventoryPanel;  class LLSaveFolderState; @@ -94,15 +95,27 @@ public:  	void toggleAddWearablesPanel();  	void showAddWearablesPanel(bool show__add_wearables); + +	//following methods operate with "add wearables" panel  	void showWearablesFilter(); -	void showFilteredWearablesPanel(); -	void showFilteredFolderWearablesPanel(); +	void showWearablesListView(); +	void showWearablesFolderView();  	void onTypeFilterChanged(LLUICtrl* ctrl);  	void onSearchEdit(const std::string& string);  	void onInventorySelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	void onAddToOutfitClicked(void); -	void onOutfitItemSelectionChange(void); + +	void applyFilter(e_look_item_type type); + +	/** +	 * Filter items in views of Add Wearables Panel and show appropriate view depending on currently selected COF item(s) +	 * No COF items selected - shows the folder view, reset filter +	 * 1 COF item selected - shows the list view and filters wearables there by a wearable type of the selected item +	 * More than 1 COF item selected - shows the list view and filters it by a type of the selected item (attachment or clothing) +	 */ +	void filterWearablesBySelectedItem(void); +  	void onRemoveFromOutfitClicked(void);  	void onEditWearableClicked(void);  	void onAddWearableClicked(void); @@ -132,7 +145,8 @@ public:  private:  	void onGearButtonClick(LLUICtrl* clicked_button); -	void showFilteredWearableItemsList(LLWearableType::EType type); +	void onAddMoreButtonClicked(); +	void showFilteredWearablesListView(LLWearableType::EType type);  	LLTextBox*			mCurrentOutfitName; @@ -145,6 +159,7 @@ private:  	LLButton*			mFolderViewBtn;  	LLButton*			mListViewBtn;  	LLPanel*			mAddWearablesPanel; +	LLComboBox*			mFilterComboBox;  	LLFindNonLinksByMask*  mWearableListMaskCollector;  	LLFindWearablesOfType* mWearableListTypeCollector; @@ -153,7 +168,6 @@ private:  	LLInventoryItemsList* 			mWearableItemsList;  	LLPanel*						mWearableItemsPanel; -	LLCOFObserver*	mCOFObserver;  	LLCOFDragAndDropObserver* mCOFDragAndDropObserver;  	std::vector<LLLookItemType> mLookItemTypes; @@ -163,6 +177,8 @@ private:  	bool				mInitialized;  	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; + +  };  #endif // LL_LLPANELOUTFITEDIT_H diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 5f67f3d989..1286642897 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -50,6 +50,7 @@  #include "lllineeditor.h"  #include "llmodaldialog.h"  #include "llnotificationsutil.h" +#include "lloutfitobserver.h"  #include "lloutfitslist.h"  #include "llsaveoutfitcombobtn.h"  #include "llsidepanelappearance.h" @@ -168,6 +169,11 @@ private:  	bool onEnable(LLSD::String param)  	{  		const LLUUID& selected_outfit_id = getSelectedOutfitID(); +		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected +		{ +			return false; +		} +  		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;  		if ("wear" == param) @@ -204,6 +210,11 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() :  	mSavedFolderState = new LLSaveFolderState();  	mSavedFolderState->setApply(FALSE);  	gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this)); + +	LLOutfitObserver& observer = LLOutfitObserver::instance(); +	observer.addBOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); +	observer.addCOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); +	observer.addOutfitLockChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));  }  LLPanelOutfitsInventory::~LLPanelOutfitsInventory() @@ -517,12 +528,12 @@ void LLPanelOutfitsInventory::updateListCommands()  {  	bool trash_enabled = isActionEnabled("delete");  	bool wear_enabled = isActionEnabled("wear"); -	bool make_outfit_enabled = isActionEnabled("make_outfit"); +	bool make_outfit_enabled = isActionEnabled("save_outfit");  	mListCommands->childSetEnabled("trash_btn", trash_enabled);  	mListCommands->childSetEnabled("wear_btn", wear_enabled);  	mListCommands->childSetVisible("wear_btn", wear_enabled); -	mSaveComboBtn->setSaveBtnEnabled(make_outfit_enabled); +	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);  }  void LLPanelOutfitsInventory::showGearMenu() @@ -549,11 +560,25 @@ void LLPanelOutfitsInventory::onTrashButtonClick()  void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)  {  	std::string command_name = userdata.asString(); -	// TODO: add handling "My Outfits" tab.  	if (isCOFPanelActive())  	{  		getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);  	} +	else // "My Outfits" tab active +	{ +		if (command_name == "delete") +		{ +			const LLUUID& selected_outfit_id = mMyOutfitsPanel->getSelectedOutfitUUID(); +			if (selected_outfit_id.notNull()) +			{ +				remove_category(&gInventory, selected_outfit_id); +			} +		} +		else +		{ +			llwarns << "Unrecognized action" << llendl; +		} +	}  	updateListCommands();  	updateVerbs();  } @@ -608,7 +633,6 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)  	{  		BOOL can_delete = FALSE; -		// TODO: add handling "My Outfits" tab.  		if (isCOFPanelActive())  		{  			LLFolderView* root = getActivePanel()->getRootFolder(); @@ -624,10 +648,15 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)  					LLFolderViewItem *item = root->getItemByID(item_id);  					can_delete &= item->getListener()->isItemRemovable();  				} -				return can_delete;  			}  		} -		return FALSE; +		else // "My Outfits" tab active +		{ +			const LLUUID& selected_outfit = mMyOutfitsPanel->getSelectedOutfitUUID(); +			can_delete = LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit); +		} + +		return can_delete;  	}  	if (command_name == "remove_link")  	{ @@ -663,9 +692,12 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)  			return FALSE;  		}  	} -	if (command_name == "make_outfit") +	if (command_name == "save_outfit")  	{ -		return TRUE; +		bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked(); +		bool outfit_dirty =LLAppearanceMgr::getInstance()->isOutfitDirty(); +		// allow save only if outfit isn't locked and is dirty +		return !outfit_locked && outfit_dirty;  	}  	if (command_name == "edit" ||  @@ -721,6 +753,7 @@ void LLPanelOutfitsInventory::initTabPanels()  	mCurrentOutfitPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, mCurrentOutfitPanel, _1, _2));  	mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME); +	mMyOutfitsPanel->addSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));  	mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");  	mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this)); @@ -789,6 +822,7 @@ void LLPanelOutfitsInventory::onWearablesLoaded()  	setWearablesLoading(false);  } +// static  LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()  {  	static LLSidepanelAppearance* panel_appearance = diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index aff7839bcc..d58ae554b0 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -75,7 +75,7 @@ public:  	void setParent(LLSidepanelAppearance *parent);  	LLFolderView* getRootFolder(); -	LLSidepanelAppearance* getAppearanceSP(); +	static LLSidepanelAppearance* getAppearanceSP();  	static LLPanelOutfitsInventory* findInstance(); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 0a4af00f78..f16d1d8fda 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -1450,6 +1450,8 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded()  		LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");  		accordion->arrange(); +		// *TODO: new empty_accordion_text attribute was implemented in accordion (EXT-7368). +		// this code should be refactored to use it  		// keep help text in a synchronization with accordions visibility.  		updateFriendListHelpText();  	} diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index e8b6c6bfe5..494cba8c6f 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -564,6 +564,7 @@ void LLTeleportHistoryPanel::updateVerbs()  	{  		mTeleportBtn->setEnabled(false);  		mShowProfile->setEnabled(false); +		mShowOnMapBtn->setEnabled(false);  		return;  	} @@ -571,7 +572,7 @@ void LLTeleportHistoryPanel::updateVerbs()  	mTeleportBtn->setEnabled(NULL != itemp);  	mShowProfile->setEnabled(NULL != itemp); -	mShowOnMapBtn->setEnabled(true); +	mShowOnMapBtn->setEnabled(NULL != itemp);  }  void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date) diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp index b9b577084b..9518b0cbb3 100644 --- a/indra/newview/llsaveoutfitcombobtn.cpp +++ b/indra/newview/llsaveoutfitcombobtn.cpp @@ -34,6 +34,7 @@  #include "llappearancemgr.h"  #include "llpaneloutfitsinventory.h" +#include "llsidepanelappearance.h"  #include "llsaveoutfitcombobtn.h"  #include "llviewermenu.h" diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 872939c209..e23643da0b 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -42,6 +42,7 @@  #include "llfloaterreg.h"  #include "llfloaterworldmap.h"  #include "llfoldervieweventlistener.h" +#include "lloutfitobserver.h"  #include "llpaneleditwearable.h"  #include "llpaneloutfitsinventory.h"  #include "llsidetray.h" @@ -73,26 +74,6 @@ private:  	LLSidepanelAppearance *mPanel;  }; -class LLWatchForOutfitRenameObserver : public LLInventoryObserver -{ -public: -	LLWatchForOutfitRenameObserver(LLSidepanelAppearance *panel) : -		mPanel(panel) -	{} -	virtual void changed(U32 mask); -	 -private: -	LLSidepanelAppearance *mPanel; -}; - -void LLWatchForOutfitRenameObserver::changed(U32 mask) -{ -	if (mask & LABEL) -	{ -		mPanel->refreshCurrentOutfitName(); -	} -} -  LLSidepanelAppearance::LLSidepanelAppearance() :  	LLPanel(),  	mFilterSubString(LLStringUtil::null), @@ -101,12 +82,13 @@ LLSidepanelAppearance::LLSidepanelAppearance() :  	mCurrOutfitPanel(NULL),  	mOpened(false)  { +	LLOutfitObserver& outfit_observer =  LLOutfitObserver::instance(); +	outfit_observer.addBOFChangedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, "")); +	outfit_observer.addCOFChangedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, ""));  }  LLSidepanelAppearance::~LLSidepanelAppearance()  { -	gInventory.removeObserver(mOutfitRenameWatcher); -	delete mOutfitRenameWatcher;  }  // virtual @@ -160,8 +142,6 @@ BOOL LLSidepanelAppearance::postBuild()  	mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook"); -	mOutfitRenameWatcher = new LLWatchForOutfitRenameObserver(this); -	gInventory.addObserver(mOutfitRenameWatcher);  	setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChange,this,_2)); diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 30022ae375..812d6362ef 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -40,7 +40,6 @@  class LLFilterEditor;  class LLCurrentlyWornFetchObserver; -class LLWatchForOutfitRenameObserver;  class LLPanelEditWearable;  class LLWearable;  class LLPanelOutfitsInventory; @@ -97,9 +96,6 @@ private:  	// Used to make sure the user's inventory is in memory.  	LLCurrentlyWornFetchObserver* mFetchWorn; -	// Used to update title when currently worn outfit gets renamed. -	LLWatchForOutfitRenameObserver* mOutfitRenameWatcher; -  	// Search string for filtering landmarks and teleport  	// history locations  	std::string					mFilterSubString; diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 3c97f01887..9406f80b75 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -469,6 +469,9 @@ void LLSideTray::reflectCollapseChange()  	}  	gFloaterView->refresh(); +	 +	LLSD new_value = mCollapsed; +	mCollapseSignal(this,new_value);  }  void LLSideTray::arrange() diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index e8fdee9430..e176ff5aff 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -159,6 +159,8 @@ public:  	void		updateSidetrayVisibility(); +	commit_signal_t& getCollapseSignal() { return mCollapseSignal; } +  protected:  	LLSideTrayTab* getTab		(const std::string& name); @@ -187,6 +189,8 @@ private:  	child_vector_t					mTabs;  	LLSideTrayTab*					mActiveTab;	 +	commit_signal_t					mCollapseSignal; +  	LLButton*						mCollapseButton;  	bool							mCollapsed; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index e51e6363dd..fff80e57dc 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -781,9 +781,6 @@ bool idle_startup()  		gViewerWindow->getWindow()->show();  		display_startup(); -		//DEV-10530.  do cleanup.  remove at some later date.  jan-2009 -		LLFloaterPreference::cleanupBadSetting(); -  		// DEV-16927.  The following code removes errant keystrokes that happen while the window is being   		// first made visible.  #ifdef _WIN32 diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 6c6eda2e68..db1f4dc4cb 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -172,6 +172,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  	params.tab_stop(false);  	params.wrap(true);  	params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); +	params.allow_scroll(true);  	LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params);  	// Compute max allowable height for the dialog text, so we can allocate @@ -180,9 +181,16 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  			gFloaterView->getRect().getHeight()  			- LINE_HEIGHT			// title bar  			- 3*VPAD - BTN_HEIGHT; +	// reshape to calculate real text width and height  	msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height );  	msg_box->setValue(msg); -	msg_box->reshapeToFitText(); + +	S32 pixel_width = msg_box->getTextPixelWidth(); +	S32 pixel_height = msg_box->getTextPixelHeight(); + +	// We should use some space to prevent set textbox's scroller visible when it is unnecessary. +	msg_box->reshape( llmin(MAX_ALLOWED_MSG_WIDTH,pixel_width + 2 * msg_box->getHPad() + HPAD), +		llmin(max_allowed_msg_height,pixel_height + 2 * msg_box->getVPad())  ) ;  	const LLRect& text_rect = msg_box->getRect();  	S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD; diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 8996157258..fa21b1a866 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -96,7 +96,7 @@ LLVisualParamHint::LLVisualParamHint(  	mCamTargetJoint(jointp)  {  	LLVisualParamHint::sInstances.insert( this ); -	mBackgroundp = LLUI::getUIImage("avatar_thumb_bkgrnd.j2c"); +	mBackgroundp = LLUI::getUIImage("avatar_thumb_bkgrnd.png");  	llassert(width != 0);  	llassert(height != 0); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 033d35d80a..2859dabfba 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -43,13 +43,15 @@ struct ViewerFolderEntry : public LLDictionaryEntry  {  	// Constructor for non-ensembles  	ViewerFolderEntry(const std::string &new_category_name, // default name when creating a new category of this type -					  const std::string &icon_name,			// name of the folder icon +					  const std::string &icon_name_open,	// name of the folder icon +					  const std::string &icon_name_closed,  					  BOOL is_quiet							// folder doesn't need a UI update when changed  		)   		:  		LLDictionaryEntry(empty_string), // no reverse lookup needed on non-ensembles, so just leave this blank -		mIconName(icon_name),  		mNewCategoryName(new_category_name), +		mIconNameOpen(icon_name_open), +		mIconNameClosed(icon_name_closed),  		mIsQuiet(is_quiet)  	{  		mAllowedNames.clear(); @@ -63,7 +65,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry  		)   		:  		LLDictionaryEntry(xui_name), -		mIconName(icon_name), +		mIconNameOpen(icon_name), +		mIconNameClosed(icon_name),  		mNewCategoryName(new_category_name),  		mIsQuiet(FALSE)  	{ @@ -84,7 +87,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry  		}  		return false;  	} -	const std::string mIconName; +	const std::string mIconNameOpen; +	const std::string mIconNameClosed;  	const std::string mNewCategoryName;  	typedef std::vector<std::string> name_vec_t;  	name_vec_t mAllowedNames; @@ -104,31 +108,31 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()  {  	initEnsemblesFromFile(); -	//       													    	  NEW CATEGORY NAME         FOLDER ICON NAME                QUIET? -	//      												  		     |-------------------------|-------------------------------|-----------| -	addEntry(LLFolderType::FT_TEXTURE, 				new ViewerFolderEntry("Textures",				"inv_folder_texture.tga",		FALSE)); -	addEntry(LLFolderType::FT_SOUND, 				new ViewerFolderEntry("Sounds",					"inv_folder_sound.tga",			FALSE)); -	addEntry(LLFolderType::FT_CALLINGCARD, 			new ViewerFolderEntry("Calling Cards",			"inv_folder_callingcard.tga",	FALSE)); -	addEntry(LLFolderType::FT_LANDMARK, 			new ViewerFolderEntry("Landmarks",				"inv_folder_landmark.tga",		FALSE)); -	addEntry(LLFolderType::FT_CLOTHING, 			new ViewerFolderEntry("Clothing",				"inv_folder_clothing.tga",		FALSE)); -	addEntry(LLFolderType::FT_OBJECT, 				new ViewerFolderEntry("Objects",				"inv_folder_object.tga",		FALSE)); -	addEntry(LLFolderType::FT_NOTECARD, 			new ViewerFolderEntry("Notecards",				"inv_folder_notecard.tga",		FALSE)); -	addEntry(LLFolderType::FT_ROOT_INVENTORY, 		new ViewerFolderEntry("My Inventory",			"",								FALSE)); -	addEntry(LLFolderType::FT_LSL_TEXT, 			new ViewerFolderEntry("Scripts",				"inv_folder_script.tga",		FALSE)); -	addEntry(LLFolderType::FT_BODYPART, 			new ViewerFolderEntry("Body Parts",				"inv_folder_bodypart.tga",		FALSE)); -	addEntry(LLFolderType::FT_TRASH, 				new ViewerFolderEntry("Trash",					"inv_folder_trash.tga",			TRUE)); -	addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, 	new ViewerFolderEntry("Photo Album",			"inv_folder_snapshot.tga",		FALSE)); -	addEntry(LLFolderType::FT_LOST_AND_FOUND, 		new ViewerFolderEntry("Lost And Found",	   		"inv_folder_lostandfound.tga",	TRUE)); -	addEntry(LLFolderType::FT_ANIMATION, 			new ViewerFolderEntry("Animations",				"inv_folder_animation.tga",		FALSE)); -	addEntry(LLFolderType::FT_GESTURE, 				new ViewerFolderEntry("Gestures",				"inv_folder_gesture.tga",		FALSE)); -	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorites",				"inv_folder_plain_closed.tga",	FALSE)); +	//       													    	  NEW CATEGORY NAME         FOLDER OPEN             FOLDER CLOSED          QUIET? +	//      												  		     |-------------------------|-----------------------|----------------------|-----------| +	addEntry(LLFolderType::FT_TEXTURE, 				new ViewerFolderEntry("Textures",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_SOUND, 				new ViewerFolderEntry("Sounds",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_CALLINGCARD, 			new ViewerFolderEntry("Calling Cards",			"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_LANDMARK, 			new ViewerFolderEntry("Landmarks",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_CLOTHING, 			new ViewerFolderEntry("Clothing",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_OBJECT, 				new ViewerFolderEntry("Objects",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_NOTECARD, 			new ViewerFolderEntry("Notecards",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_ROOT_INVENTORY, 		new ViewerFolderEntry("My Inventory",			"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_LSL_TEXT, 			new ViewerFolderEntry("Scripts",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_BODYPART, 			new ViewerFolderEntry("Body Parts",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_TRASH, 				new ViewerFolderEntry("Trash",					"Inv_TrashOpen",		"Inv_TrashClosed",		TRUE)); +	addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, 	new ViewerFolderEntry("Photo Album",			"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_LOST_AND_FOUND, 		new ViewerFolderEntry("Lost And Found",	   		"Inv_LostOpen",			"Inv_LostClosed",		TRUE)); +	addEntry(LLFolderType::FT_ANIMATION, 			new ViewerFolderEntry("Animations",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_GESTURE, 				new ViewerFolderEntry("Gestures",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorites",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); -	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"inv_folder_current_outfit.tga",TRUE)); -	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"inv_folder_outfit.tga",		TRUE)); -	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"inv_folder_my_outfits.tga",	TRUE)); -	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"inv_folder_inbox.tga",			FALSE)); +	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"Inv_SysOpen",			"Inv_SysClosed",		TRUE)); +	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"Inv_LookFolderOpen",	"Inv_LookFolderClosed",	TRUE)); +	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE)); +	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); -	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"inv_folder_plain_closed.tga",	FALSE)); +	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE));  }  bool LLViewerFolderDictionary::initEnsemblesFromFile() @@ -213,12 +217,15 @@ LLFolderType::EType LLViewerFolderType::lookupTypeFromXUIName(const std::string  	return LLViewerFolderDictionary::getInstance()->lookup(name);  } -const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder_type) +const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder_type, BOOL is_open)  {  	const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);  	if (entry)  	{ -		return entry->mIconName; +		if (is_open) +			return entry->mIconNameOpen; +		else +			return entry->mIconNameClosed;  	}  	return badLookup();  } diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h index dd9360da90..3744ac20f8 100644 --- a/indra/newview/llviewerfoldertype.h +++ b/indra/newview/llviewerfoldertype.h @@ -44,7 +44,7 @@ public:  	static const std::string&   lookupXUIName(EType folder_type); // name used by the UI  	static LLFolderType::EType 	lookupTypeFromXUIName(const std::string& name); -	static const std::string&   lookupIconName(EType folder_type); // folder icon name +	static const std::string&   lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name  	static BOOL					lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured  	static const std::string&	lookupNewCategoryName(EType folder_type); // default name when creating new category  	static LLFolderType::EType	lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index face7124c2..40f15fe86a 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -883,12 +883,8 @@ void ModifiedCOFCallback::fire(const LLUUID& inv_item)  {  	LLAppearanceMgr::instance().updateAppearanceFromCOF(); -	if (LLSideTray::getInstance()->isPanelActive("sidepanel_appearance")) -	{ -		// *HACK: Edit the wearable that has just been worn -		//        only if the Appearance SP is currently opened. -		LLAgentWearables::editWearable(inv_item); -	} +	// Start editing the item if previously requested. +	gAgentWearables.editWearableIfRequested(inv_item);  	// TODO: camera mode may not be changed if a debug setting is tweaked  	if( gAgentCamera.cameraCustomizeAvatar() ) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5836aff4e7..b00fa39815 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2063,7 +2063,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				// initiated by the other party) then...  				std::string my_name;  				LLAgentUI::buildFullname(my_name); -				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2"); +				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");  				pack_instant_message(  					gMessageSystem,  					gAgent.getID(), @@ -2736,7 +2736,7 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)  	{  		std::string my_name;  		LLAgentUI::buildFullname(my_name); -		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2"); +		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");  		pack_instant_message(  			gMessageSystem,  			gAgent.getID(), diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 7e779986df..9b5b210bf7 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -541,11 +541,6 @@ void LLViewerTexture::setBoostLevel(S32 level)  		if(mBoostLevel != LLViewerTexture::BOOST_NONE)  		{  			setNoDelete() ;		 - -			if(LLViewerTexture::BOOST_AVATAR_BAKED_SELF == mBoostLevel || LLViewerTexture::BOOST_AVATAR_BAKED == mBoostLevel) -			{ -				mCanResetMaxVirtualSize = false ; -			}  		}  		if(gAuditTexture)  		{ @@ -596,6 +591,11 @@ void LLViewerTexture::forceImmediateUpdate()  {  } +void LLViewerTexture::setResetMaxVirtualSizeFlag(bool flag)  +{ +	mCanResetMaxVirtualSize = flag ; +} +  void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const   {  	if(needs_gltexture) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 1bd4cc793d..361f56e02f 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -166,6 +166,7 @@ public:  	void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;  	void resetTextureStats();	 +	void setResetMaxVirtualSizeFlag(bool flag) ;  	virtual F32  getMaxVirtualSize() ; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 83556452c0..0a65cb7330 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1591,6 +1591,9 @@ void LLViewerWindow::initBase()  	gDebugView->init();  	gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view"); +	// Initialize busy response message when logged in +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse)); +  	// Add the progress bar view (startup view), which overrides everything  	mProgressView = getRootView()->getChild<LLProgressView>("progress_view");  	setShowProgress(FALSE); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1fa953f157..3e93dc1a90 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4210,9 +4210,14 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel  	mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);  	mMinPixelArea = llmin(pixel_area, mMinPixelArea);  	imagep->resetTextureStats(); +	imagep->setResetMaxVirtualSizeFlag(false) ;  	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.  	imagep->addTextureStats(pixel_area / texel_area_ratio);  	imagep->setBoostLevel(boost_level); +	if(boost_level == LLViewerTexture::BOOST_AVATAR_BAKED_SELF) +	{ +		imagep->setAdditionalDecodePriority(1.0f) ; +	}  }  //virtual	 diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index eae92f8992..a4d888cd72 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -975,12 +975,6 @@ void LLVOAvatarSelf::wearableUpdated( LLWearableType::EType type, BOOL upload_re  		const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;  		const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first; -		// if we're editing our appearance, ensure that we're not using baked textures -		// The baked texture for alpha masks is set explicitly when you hit "save" -		if (gAgentCamera.cameraCustomizeAvatar()) -		{ -			setNewBakedTexture(index,IMG_DEFAULT_AVATAR); -		}  		if (baked_dict)  		{  			for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); @@ -2036,7 +2030,11 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  			F32 desired_pixels;  			desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());  			imagep->setBoostLevel(getAvatarBoostLevel()); + +			imagep->resetTextureStats(); +			imagep->setResetMaxVirtualSizeFlag(false) ;  			imagep->addTextureStats( desired_pixels / texel_area_ratio ); +			imagep->setAdditionalDecodePriority(1.0f) ;  			imagep->forceUpdateBindStats() ;  			if (imagep->getDiscardLevel() < 0)  			{ diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 96bde129ee..39649f0370 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -5287,6 +5287,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)  			LLVoiceChannel::getCurrentVoiceChannel()->deactivate();  			status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;  		} +		notifyStatusObservers(status);		  	}  } diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 121e691710..46c736c853 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -705,7 +705,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake  	}  	gAgentAvatarp->updateVisualParams(); -	gAgentAvatarp->wearableUpdated(type, TRUE); +	gAgentAvatarp->wearableUpdated(type, FALSE);  //	if( upload_bake )  //	{ diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 6c4774ba5a..54695e9d40 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -38,10 +38,10 @@  #include "llagentwearables.h"  #include "llappearancemgr.h"  #include "llinventoryfunctions.h" -#include "llinventorymodel.h"  #include "llmenugl.h" // for LLContextMenu  #include "lltransutil.h"  #include "llviewerattachmenu.h" +#include "llvoavatarself.h"  class LLFindOutfitItems : public LLInventoryCollectFunctor  { @@ -88,8 +88,6 @@ void LLPanelWearableListItem::onMouseLeave(S32 x, S32 y, MASK mask)  LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item)  : LLPanelInventoryListItemBase(item)  { -	// icons should not be shown for this type of items (EXT-7511) -	mForceNoLinksOnIcons = true;  }  ////////////////////////////////////////////////////////////////////////// @@ -258,6 +256,31 @@ BOOL LLPanelDeletableWearableListItem::postBuild()  } +// static +LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryItem* item) +{ +	LLPanelAttachmentListItem* list_item = NULL; +	if(item) +	{ +		list_item = new LLPanelAttachmentListItem(item); +		list_item->init(); +	} +	return list_item; +} + +void LLPanelAttachmentListItem::setTitle(const std::string& title, const std::string& highlit_text) +{ +	std::string title_joint = title; + +	if (mItem && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(mItem->getLinkedUUID())) +	{ +		std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(mItem->getLinkedUUID())); +		title_joint = title + " (" + joint + ")"; +	} + +	LLPanelDeletableWearableListItem::setTitle(title_joint, highlit_text); +} +  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// @@ -281,9 +304,9 @@ BOOL LLPanelDummyClothingListItem::postBuild()  	setIconCtrl(icon);  	setTitleCtrl(getChild<LLTextBox>("item_name")); -	addWidgetToRightSide("btn_add"); +	addWidgetToRightSide("btn_add_panel"); -	setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, FALSE, mWearableType, FALSE)); +	setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, FALSE));  	updateItem();  	// Make it look loke clothing item - reserve space for 'delete' button @@ -484,6 +507,37 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)  	refreshList(item_array);  } +void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids) +{ +	typedef std::vector<LLPanel*> item_panel_list_t; + +	item_panel_list_t items; +	getItems(items); + +	for (item_panel_list_t::iterator items_iter = items.begin(); +			items_iter != items.end(); +			++items_iter) +	{ +		LLPanelInventoryListItemBase* item = dynamic_cast<LLPanelInventoryListItemBase*>(*items_iter); +		if (!item) continue; + +		LLViewerInventoryItem* inv_item = item->getItem(); +		if (!inv_item) continue; + +		LLUUID linked_uuid = inv_item->getLinkedUUID(); + +		for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items_uuids.begin(); +				iter != changed_items_uuids.end(); +				++iter) +		{ +			if (linked_uuid == *iter) +			{ +				item->setNeedsRefresh(true); +			} +		} +	} +} +  void LLWearableItemsList::onRightClick(S32 x, S32 y)  {  	uuid_vec_t selected_uuids; diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 2fdb8f0ab8..dd0ceb99e4 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -116,6 +116,21 @@ protected:  	/*virtual*/ void init();  }; +/** Outfit list item for an attachment */ +class LLPanelAttachmentListItem : public LLPanelDeletableWearableListItem +{ +	LOG_CLASS(LLPanelAttachmentListItem); +public: +	static LLPanelAttachmentListItem* create(LLViewerInventoryItem* item); +	virtual ~LLPanelAttachmentListItem() {}; + +	/** Set item title. Joint name is added to the title in parenthesis */ +	/*virtual*/ void setTitle(const std::string& title, const std::string& highlit_text); + +protected: +	LLPanelAttachmentListItem(LLViewerInventoryItem* item) : LLPanelDeletableWearableListItem(item) {}; +}; +  /**   * @class LLPanelClothingListItem   * @@ -340,6 +355,12 @@ public:  	void updateList(const LLUUID& category_id); +	/** +	 * Update items that match UUIDs from changed_items_uuids +	 * or links that point at such items. +	 */ +	void updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids); +  protected:  	friend class LLUICtrlFactory;  	LLWearableItemsList(const LLWearableItemsList::Params& p); diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index a8ac0c0c90..1d10ec7b28 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -513,7 +513,7 @@ void LLXMLRPCTransaction::Impl::setStatus(EStatus status,  				// Usually this means that there's a problem with the login server,  				// not with the client.  Direct user to status page.  				mStatusMessage = LLTrans::getString("server_is_down"); -				mStatusURI = "http://secondlife.com/status/"; +				mStatusURI = "http://status.secondlifegrid.net/";  		}  	}  } diff --git a/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png b/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png Binary files differnew file mode 100644 index 0000000000..84cc2159c1 --- /dev/null +++ b/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Link.png b/indra/newview/skins/default/textures/icons/Inv_Link.png Binary files differnew file mode 100644 index 0000000000..c1543dacb5 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Link.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 85ccf0f564..c02bf5741e 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -228,39 +228,7 @@ with the same filename but different name    <texture name="Inv_TrashOpen" file_name="icons/Inv_TrashOpen.png" preload="false" />    <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />    <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" /> - -  <texture name="Inv_Alpha_Link" file_name="icons/Inv_Alpha_Link.png" preload="false" /> -  <texture name="Inv_Animation_Link" file_name="icons/Inv_Animation_Link.png" preload="false" /> -  <texture name="Inv_BodyShape_Link" file_name="icons/Inv_BodyShape_Link.png" preload="false" /> -  <texture name="Inv_CallingCard_Link" file_name="icons/Inv_CallingCard_Link.png" preload="false" /> -  <texture name="Inv_Clothing_Link" file_name="icons/Inv_Clothing_Link.png" preload="false" /> -  <texture name="Inv_Eye_Link" file_name="icons/Inv_Eye_Link.png" preload="false" /> -  <texture name="Inv_FolderClosed_Link" file_name="icons/Inv_FolderClosed_Link.png" preload="false" /> -  <texture name="Inv_FolderOpen_Link" file_name="icons/Inv_FolderOpen_Link.png" preload="false" /> -  <texture name="Inv_Gesture_Link" file_name="icons/Inv_Gesture_Link.png" preload="false" /> -  <texture name="Inv_Gloves_Link" file_name="icons/Inv_Gloves_Link.png" preload="false" /> -  <texture name="Inv_Hair_Link" file_name="icons/Inv_Hair_Link.png" preload="false" /> -  <texture name="Inv_LinkFolder_Link" file_name="icons/Inv_LinkFolder_Link.png" preload="false" /> -  <texture name="Inv_Jacket_Link" file_name="icons/Inv_Jacket_Link.png" preload="false" /> -  <texture name="Inv_LookFolderOpen_Link" file_name="icons/Inv_LookFolderOpen_Link.png" preload="false" /> -  <texture name="Inv_LookFolderClosed_Link" file_name="icons/Inv_LookFolderClosed_Link.png" preload="false" /> -  <texture name="Inv_Landmark_Link" file_name="icons/Inv_Landmark_Link.png" preload="false" /> -  <texture name="Inv_Notecard_Link" file_name="icons/Inv_Notecard_Link.png" preload="false" /> -  <texture name="Inv_Object_Link" file_name="icons/Inv_Object_Link.png" preload="false" /> -  <texture name="Inv_Object_Multi_Link" file_name="icons/Inv_Object_Multi_Link.png" preload="false" /> -  <texture name="Inv_Pants_Link" file_name="icons/Inv_Pants_Link.png" preload="false" /> -  <texture name="Inv_Script_Link" file_name="icons/Inv_Script_Link.png" preload="false" /> -  <texture name="Inv_Shirt_Link" file_name="icons/Inv_Shirt_Link.png" preload="false" /> -  <texture name="Inv_Shoe_Link" file_name="icons/Inv_Shoe_Link.png" preload="false" /> -  <texture name="Inv_Skin_Link" file_name="icons/Inv_Skin_Link.png" preload="false" /> -  <texture name="Inv_Skirt_Link" file_name="icons/Inv_Skirt_Link.png" preload="false" /> -  <texture name="Inv_Snapshot_Link" file_name="icons/Inv_Snapshot_Link.png" preload="false" /> -  <texture name="Inv_Socks_Link" file_name="icons/Inv_Socks_Link.png" preload="false" /> -  <texture name="Inv_Sound_Link" file_name="icons/Inv_Sound_Link.png" preload="false" /> -  <texture name="Inv_Tattoo_Link" file_name="icons/Inv_Tattoo_Link.png" preload="false" /> -  <texture name="Inv_Texture_Link" file_name="icons/Inv_Texture_Link.png" preload="false" /> -  <texture name="Inv_Underpants_Link" file_name="icons/Inv_Underpants_Link.png" preload="false" /> -  <texture name="Inv_Undershirt_Link" file_name="icons/Inv_Undershirt_Link.png" preload="false" /> +  <texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" />    <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>    <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/> diff --git a/indra/newview/skins/default/xui/de/panel_bottomtray.xml b/indra/newview/skins/default/xui/de/panel_bottomtray.xml index d52b8dcf4d..83f67344ca 100644 --- a/indra/newview/skins/default/xui/de/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/de/panel_bottomtray.xml @@ -9,7 +9,7 @@  	<layout_stack name="toolbar_stack">  		<layout_panel name="speak_panel">  			<talk_button name="talk"> -				<speak_button label="Sprechen" label_selected="Sprechen" name="speak_btn" halign="right" /> +				<speak_button label="Sprechen" label_selected="Sprechen" name="speak_btn" />  			</talk_button>  		</layout_panel>  		<layout_panel name="gesture_panel"> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml index 4643f66bd8..4b990fa566 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml @@ -1,27 +1,27 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater - legacy_header_height="18"   can_resize="false" - height="280" + can_close="true" + width="422" + height="202"   layout="topleft" - min_height="280" - min_width="450"   name="floater_buy_currency_html"   help_topic="floater_buy_currency_html"   save_rect="true"   single_instance="true"   title="BUY CURRENCY" - width="452"> - <floater.string -      name="buy_currency_url" translate="false"> -        https://quick-buy-www.jeff.ooze.lindenlab.com/en/display - </floater.string> -    <web_browser -     bottom="278" -     follows="left|right|top|bottom" -     layout="topleft" -     left="2" -     name="browser" -     top="18" -     width="450" /> +> +  <floater.string +    name="buy_currency_url" translate="false"> +    https://quick-buy.secondlife.com/[LANGUAGE]/display/?sa=[SPECIFIC_AMOUNT]&sum=[SUM]&msg=[MSG]&bal=[BAL] +  </floater.string> +  <web_browser +    follows="all" +    layout="topleft" +    left="1" +    right="-1"  +    top="1" +    bottom="-1"  +    ignore_ui_scale="false" +    name="browser"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index f537c81860..c9b013099b 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -33,7 +33,6 @@        name="panel_im_control_panel"        layout="topleft"        follows="left" -      label="IM Control Panel"        min_width="115"         auto_resize="false"        user_resize="true" /> diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index f3d297c303..7d81c3e551 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -38,91 +38,129 @@      left="20"      top_pad="-30"      name="new_snapshot_btn" -    width="23" /> +    width="23" +    commit_callback.function="Snapshot.Refresh"/>    <line_editor      border_style="line"      border_thickness="1" -	  follows="left|top" -	  height="20" -		layout="topleft" +    follows="left|top" +    height="20" +    layout="topleft"      left="10" -		max_length="500" +    max_length="500"      name="description" -	  top_pad="15" -	  width="230" +    top_pad="15" +    width="230"      label="Description"/> +  <panel +   top_pad="20" +   left="10" +   height="83" +   name="panel_snapshot_main" +   width="130"> +    <button +     label="Share Snapshot" +     name="share" +     top="0" +     left="0" +     width="130" +     commit_callback.function="Snapshot.ShowButtons" +     commit_callback.parameter="share"/> +    <button +     label="Save Snapshot" +     name="save" +     top_pad="7" +     left_delta="0" +     width="130" +     commit_callback.function="Snapshot.ShowButtons" +     commit_callback.parameter="save"/> +    <button +     label="Set As Profile Pic" +     name="set_profile_pic" +     top_pad="7" +     left_delta="0" +     width="130"/> +  </panel> +  <panel +   top_delta="0" +   left_delta="0" +   height="83" +   name="panel_snapshot_share" +   width="130"> +    <button +     label="Share to Web" +     name="share_to_web" +     top="0" +     left="0" +     visible="false" +     width="130"/> +    <button +     label="Email Snapshot" +     name="share_to_email" +     top_pad="7" +     left_delta="0" +     width="130"/> +    <button +     label="Back" +     name="cancel_share" +     top_pad="7" +     left_delta="0" +     width="130" +     commit_callback.function="Snapshot.ShowButtons" +     commit_callback.parameter="main"/> +  </panel> +  <panel +   top_delta="0" +   left_delta="0" +   height="83" +   name="panel_snapshot_save" +   width="130"> +    <button +     label="Save to My Inventory" +     name="save_to_inventory" +     top="0" +     left="0" +     width="130"/> +    <button +     label="Save to My Computer" +     name="save_to_computer" +     top_pad="7" +     left_delta="0" +     width="130"/> +    <button +     label="Back" +     name="cancel_save" +     top_pad="7" +     left_delta="0" +     width="130" +     commit_callback.function="Snapshot.ShowButtons" +     commit_callback.parameter="main"/> +  </panel>    <button -   label="Share Snapshot"  -   name="share"  -   top_pad="20"  -   left="10"  -   width="130"/> +   follows="left" +   height="22" +   layout="topleft" +   left="210" +   name="show_advanced" +   image_overlay="TabIcon_Close_Off" +   bottom_delta="0" +   width="30" +   commit_callback.function="Snapshot.ShowAdvanced"/>    <button -   label="Share to Web"  -   name="share_to_web"  -   top_delta="0"  -   left="10"  +   follows="left" +   height="22" +   layout="topleft" +   left="210" +   name="hide_advanced" +   image_overlay="TabIcon_Open_Off" +   top_delta="0"     visible="false" -   width="130"/> -  <button -   label="Save to My Inventory"  -   name="save_to_inventory"  -   top_delta="0"  -   left="10"  -   width="130"/> -  <button -   label="Save Snapshot"  -   name="save"  -   top_pad="7"  -   left="10"  -   width="130"/> -  <button -   label="Email Snapshot"  -   name="share_to_email"  -   top_delta="0"  -   left="10"  -   width="130"/> -  <button -   label="Save to My Computer"  -   name="save_to_computer"  -   top_delta="0"  -   left="10"  -   width="130"/> -  <button -   label="Set As Profile Pic"  -   name="set_profile_pic"  -   top_pad="7"  -   left="10"  -   width="130"/> -  <button -   label="Back"  -   name="cancel"  -   top_delta="0"  -   left="10"  -   width="130"/> -  <button -     follows="left" -     height="22" -     layout="topleft" -     left="210" -    name="show_advanced" -    image_overlay="TabIcon_Close_Off" -    top_delta="1" -    width="30"/> -  <button -     follows="left" -     height="22" -     layout="topleft" -     left="210" -     visible="false"  -     name="hide_advanced" -     image_overlay="TabIcon_Open_Off" -     top_delta="0" -     width="30"/> +   width="30" +   commit_callback.function="Snapshot.HideAdvanced"/>    <panel  -    visible="false"  -    left="250"  -    top="17"     -    name="snapshot_advanced"  -    filename="panel_snapshot_advanced.xml"/> +   visible="false" +   left="250" +   top="17" +   name="snapshot_advanced" +   filename="panel_snapshot_advanced.xml"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index 4e6a07d020..62365f7cc2 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -61,14 +61,6 @@      <menu_item_separator       layout="topleft" />      <menu_item_call -     label="Empty Trash" -     layout="topleft" -     name="empty_trash"> -        <on_click -         function="Inventory.GearDefault.Custom.Action" -         parameter="empty_trash" /> -    </menu_item_call> -    <menu_item_call       label="Empty Lost and Found"       layout="topleft"       name="empty_lostnfound"> @@ -111,4 +103,15 @@  			 function="Inventory.GearDefault.Enable"  			 parameter="find_links" />          </menu_item_call> +    <menu_item_separator +     layout="topleft" /> + +    <menu_item_call +     label="Empty Trash" +     layout="topleft" +     name="empty_trash"> +        <on_click +         function="Inventory.GearDefault.Custom.Action" +         parameter="empty_trash" /> +    </menu_item_call>  </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index b5eda8e999..c4e31ed180 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -170,7 +170,7 @@      <menu_item_separator />      <menu_item_call -     label="Rename" +     label="Rename Outfit"       layout="topleft"       name="rename">          <on_click diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index fa5ca60a19..430a7b6444 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -38,13 +38,6 @@       layout="topleft"       name="wearable_attach_to_hud" />      <menu_item_call -     label="Object Profile" -     layout="topleft" -     name="object_profile"> -        <on_click -         function="Attachment.Profile" /> -    </menu_item_call> -    <menu_item_call       label="Take Off"       layout="topleft"       name="take_off"> @@ -59,6 +52,13 @@           function="Wearable.Edit" />      </menu_item_call>      <menu_item_call +     label="Object Profile" +     layout="topleft" +     name="object_profile"> +        <on_click +         function="Attachment.Profile" /> +    </menu_item_call> +    <menu_item_call       label="Show Original"       layout="topleft"       name="show_original"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 6d3d0f13bf..aca3b750c8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2066,6 +2066,7 @@ Would you be my friend?         name="Cancel"         text="Cancel"/>      </form> +    <unique/>    </notification>    <notification @@ -6207,7 +6208,7 @@ The button will be shown when there is enough space for it.     icon="notifytip.tga"     name="ShareNotification"     type="notifytip"> -Drag items from inventory onto a person in the resident picker +Select residents to share with.    </notification>    <notification     icon="notifytip.tga" @@ -6304,36 +6305,39 @@ Avatar '[NAME]' entered appearance mode.  Avatar '[NAME]' left appearance mode.    </notification> -    <notification +  <notification     icon="alertmodal.tga"     name="NoConnect"     type="alertmodal"> -        We're having trouble connecting using [PROTOCOL] [HOSTID]. -        Please check your network and firewall setup. -        <form name="form"> -            <button -               default="true" -               index="0" -               name="OK" -               text="OK"/> -        </form> -    </notification> +We're having trouble connecting using [PROTOCOL] [HOSTID]. +Please check your network and firewall setup. +    <form name="form"> +      <button +       default="true" +       index="0" +       name="OK" +       text="OK"/> +    </form> +  </notification> -    <notification -          icon="alertmodal.tga" -          name="NoVoiceConnect" -          type="alertmodal"> -        We're having trouble connecting your voiceserver using [HOSTID]. -        Voice communications will not be available. -        Please check your network and firewall setup. -        <form name="form"> -            <button -               default="true" -               index="0" -               name="OK" -               text="OK"/> -        </form> -    </notification> +  <notification +   icon="alertmodal.tga" +   name="NoVoiceConnect" +   type="alertmodal"> +We're having trouble connecting to your voice server: + +[HOSTID] + +Voice communications will not be available. +Please check your network and firewall setup. +    <form name="form"> +      <button +       default="true" +       index="0" +       name="OK" +       text="OK"/> +    </form> +  </notification>    <notification     icon="notifytip.tga" @@ -6361,7 +6365,7 @@ Are you sure you want to leave this call?       name="okcancelignore"       notext="No"       yestext="Yes"/> -     <unique/> +    <unique/>    </notification>    <notification @@ -6378,7 +6382,7 @@ Mute everyone?       name="okcancelignore"       yestext="Ok"       notext="Cancel"/> -     <unique/> +    <unique/>    </notification>    <global name="UnsupportedCPU"> diff --git a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml index a0bbc8f2ee..4e5f594ffe 100644 --- a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel   follows="top|right|left" - height="25" + height="23"   layout="topleft"   left="0"   name="wearable_item" @@ -45,7 +45,7 @@       use_ellipses="true"       name="item_name"       text_color="white" -     top="4" +     top="5"       value="..."       width="359" />      <panel @@ -74,10 +74,10 @@       name="btn_edit_panel"       layout="topleft"       follows="top|right" -     top="0" +     top="1"       left_pad="3" -     height="24" -     width="27" +     height="23" +     width="26"       tab_stop="false">           <button             name="btn_edit" @@ -86,8 +86,8 @@            image_overlay="Edit_Wrench"            top="0"            left="0" -          height="24" -          width="24" +          height="23" +          width="23"            tab_stop="false" />        </panel>      <icon @@ -97,7 +97,7 @@       layout="bottomleft"       left="0"       name="wearable_type_separator_icon" -     top="3" +     top="0"       visible="true"       width="380"/>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 82b2405ec9..4eff5bc48a 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -90,7 +90,7 @@                   label="Speak"                   label_selected="Speak"                   name="speak_btn" -                 pad_right="22" +                 pad_right="20"                   tab_stop="true"                   use_ellipses="true" />              </talk_button> diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml index e41141f6bd..5d81aebbd5 100644 --- a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml @@ -33,7 +33,7 @@       follows="top|left"       image_unselected="Toast_CloseBtn"       image_selected="Toast_CloseBtn" -     top="2" +     top="3"       left="0"       height="18"       width="18" @@ -56,7 +56,7 @@       use_ellipses="true"       name="item_name"       text_color="white" -     top="4" +     top="5"       value="..."       width="359" />      <button  @@ -64,20 +64,20 @@       layout="topleft"       follows="top|right"       image_overlay="UpArrow_Off" -     top="0" +     top="1"       left="0" -     height="24" -     width="24" +     height="23" +     width="23"       tab_stop="false" />      <button        name="btn_move_down"       layout="topleft"       follows="top|right"       image_overlay="DownArrow_Off" -     top="0" +     top="1"       left_pad="3" -     height="24" -     width="24" +     height="23" +     width="23"       tab_stop="false" />      <panel       background_visible="false" @@ -107,18 +107,18 @@       follows="top|right"       top="0"       left_pad="3" -     height="24" -     width="27" +     height="23" +     width="26"       tab_stop="false">          <button            name="btn_edit"           layout="topleft"           follows="top|right"           image_overlay="Edit_Wrench" -         top="0" +         top="1"           left="0" -         height="24" -         width="24" +         height="23" +         width="23"           tab_stop="false" />        </panel>      <icon diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index 5f34c24bca..f016c27b0a 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -11,7 +11,7 @@      <accordion       fit_parent="true"       follows="all" -     height="200" +     height="198"       layout="topleft"       left="0"       single_expansion="true" @@ -28,6 +28,7 @@               allow_select="true"               follows="all"               height="10" +             item_pad="3"               layout="topleft"               left="0"               multi_select="true" @@ -43,6 +44,7 @@               allow_select="true"               follows="all"               height="10" +             item_pad="3"               layout="topleft"               left="0"               multi_select="true" @@ -58,6 +60,7 @@               allow_select="true"               follows="all"               height="10" +             item_pad="3"               layout="topleft"               left="0"               multi_select="true" diff --git a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml index b006d125ee..45031859f1 100644 --- a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel   follows="top|right|left" - height="25" + height="23"   layout="topleft"   left="0"   name="deletable_wearable_item" @@ -33,7 +33,7 @@       follows="top|left"       image_unselected="Toast_CloseBtn"       image_selected="Toast_CloseBtn" -     top="2" +     top="3"       left="0"       height="18"       width="18" @@ -56,7 +56,7 @@       use_ellipses="true"       name="item_name"       text_color="white" -     top="4" +     top="5"       value="..."       width="359" />      <icon @@ -66,7 +66,7 @@       layout="bottomleft"       left="0"       name="wearable_type_separator_icon" -     top="3" +     top="0"       visible="true"       width="380"/>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml index 6c43635d49..b1f4cbb079 100644 --- a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel   follows="top|right|left" - height="25" + height="23"   layout="topleft"   left="0"   name="dummy_clothing_item" @@ -49,16 +49,26 @@       top="4"       value="..."       width="359" /> -    <button  -     name="btn_add" +    <panel +     name="btn_add_panel"       layout="topleft"       follows="top|right" -     image_overlay="AddItem_Off"       top="0"       left="0" -     height="24" -     width="24" -     tab_stop="false" /> +     height="23" +     width="26" +     tab_stop="false"> +      <button  +       name="btn_add" +       layout="topleft" +       follows="top|right" +       image_overlay="AddItem_Off" +       top="0" +       left="0" +       height="23" +       width="23" +       tab_stop="false" /> +    </panel>      <icon       follows="left|right|top"       height="3" @@ -66,7 +76,7 @@       layout="bottomleft"       left="0"       name="wearable_type_separator_icon" -     top="3" +     top="0"       visible="true"       width="380"/>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml index cf15fb0455..d295f5fe4a 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml @@ -8,19 +8,22 @@  	 name="edit_shape_panel"  	 top_pad="10"  	 width="333" > -	 <text -		 follows="top|left|right" -		 font="SansSerifSmallBold" -		 halign="right" -		 height="12" -		 layout="topleft" -		 left="0" -		 name="avatar_height" -		 text_color="EmphasisColor" -		 top="0" -		 width="310"> -		 [HEIGHT] Meters tall -	 </text> +     <string name="meters">Meters</string> +     <string name="feet">Feet</string> +     <string name="height">Height:</string> +     <string name="heigth_label_color" translate="false">White_50</string> +     <string name="heigth_value_label_color" translate="false">White</string> +     <text +         follows="top|left|right" +         font="SansSerifSmallBold" +         halign="right" +         height="12" +         layout="topleft" +         left="0" +         name="avatar_height" +         top="0" +         width="310"> +     </text>       <panel           border="false"           bg_alpha_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 67ff71cef1..645ee8a435 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -7,6 +7,7 @@   label="Wearable"   layout="topleft"  left="0" + help_topic="edit_wearable"   name="panel_edit_wearable"  	top="0"   width="333"> @@ -235,7 +236,7 @@ left="0"  	 </panel>  	 <panel  		 follows="all" -		 height="408" +		 height="433"  		 layout="topleft"  		 left="0"  		 name="edit_subpanel_container" @@ -246,7 +247,7 @@ left="0"  		 <panel  			 filename="panel_edit_shape.xml"  			 follows="all" -			 height="408" +			 height="433"  			 layout="topleft"  			 left="0"  			 name="edit_shape_panel" @@ -256,7 +257,7 @@ left="0"  		 <panel  			 filename="panel_edit_skin.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_skin_panel" @@ -266,7 +267,7 @@ left="0"  		 <panel  			 filename="panel_edit_hair.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_hair_panel" @@ -276,7 +277,7 @@ left="0"  		 <panel  			 filename="panel_edit_eyes.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_eyes_panel" @@ -286,7 +287,7 @@ left="0"  		 <panel  			 filename="panel_edit_shirt.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_shirt_panel" @@ -296,7 +297,7 @@ left="0"  		 <panel  			 filename="panel_edit_pants.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_pants_panel" @@ -306,7 +307,7 @@ left="0"  		 <panel  			 filename="panel_edit_shoes.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_shoes_panel" @@ -316,7 +317,7 @@ left="0"  		 <panel  			 filename="panel_edit_socks.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_socks_panel" @@ -326,7 +327,7 @@ left="0"  		 <panel  			 filename="panel_edit_jacket.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_jacket_panel" @@ -336,7 +337,7 @@ left="0"  		 <panel  			 filename="panel_edit_skirt.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_skirt_panel" @@ -346,7 +347,7 @@ left="0"  		 <panel  			 filename="panel_edit_gloves.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_gloves_panel" @@ -356,7 +357,7 @@ left="0"  		 <panel  			 filename="panel_edit_undershirt.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_undershirt_panel" @@ -366,7 +367,7 @@ left="0"  		 <panel  			 filename="panel_edit_underpants.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_underpants_panel" @@ -376,7 +377,7 @@ left="0"  		 <panel  			 filename="panel_edit_alpha.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_alpha_panel" @@ -386,7 +387,7 @@ left="0"  		 <panel  			 filename="panel_edit_tattoo.xml"  			 follows="all" -			 height="400" +			 height="425"  			 layout="topleft"  			 left="0"  			 name="edit_tattoo_panel" @@ -394,65 +395,7 @@ left="0"  			 visible="false"  			 width="333" />  	 </panel> -     <panel -        follows="bottom|left|right" -        height="25" -        label="gear_buttom_panel" -        layout="topleft" -        left="0" -        name="gear_buttom_panel" -        top_pad="0" -        width="333"> -        <button -            follows="bottom|left" -            tool_tip="Options" -            height="25" -            image_hover_unselected="Toolbar_Left_Over" -            image_disabled="OptionsMenu_Disabled" -            image_overlay="OptionsMenu_Off" -            image_selected="Toolbar_Left_Selected" -            image_unselected="Toolbar_Left_Off" -            layout="topleft" -            left="10" -            name="friends_viewsort_btn" -            top="0" -            width="31" /> -        <button -            follows="bottom|left" -            height="25" -            image_hover_unselected="Toolbar_Middle_Over" -            image_overlay="AddItem_Off" -            image_selected="Toolbar_Middle_Selected" -            image_unselected="Toolbar_Middle_Off" -            image_disabled="AddItem_Disabled" -            layout="topleft" -            left_pad="1" -            name="add_btn" -            tool_tip="TODO" -            width="31" /> -        <icon -            follows="bottom|left|right" -            height="25" -            image_name="Toolbar_Middle_Off" -            layout="topleft" -            left_pad="1" -            name="dummy_right_icon" -            width="218" > -        </icon> -        <button -            follows="bottom|right" -            height="25" -            image_hover_unselected="Toolbar_Right_Over" -            image_overlay="TrashItem_Off" -            image_selected="Toolbar_Right_Selected" -            image_unselected="Toolbar_Right_Off" -            image_disabled="TrashItem_Disabled" -            layout="topleft" -            left_pad="1" -            name="del_btn" -            tool_tip="TODO" -            width="31" /> -     </panel> +  	 <panel  		 follows="bottom|left|right"  		 height="23" diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 19fe2ea874..6523b0d491 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -74,16 +74,14 @@ Maximum 200 per group daily      </text>        <button         follows="top|left" -       height="18" -       image_selected="AddItem_Press" -       image_unselected="AddItem_Off" -       image_disabled="AddItem_Disabled" +       height="23" +       image_overlay="AddItem_Off"         layout="topleft"         left="5"         name="create_new_notice"         tool_tip="Create a new notice" -     top_delta="-3" -       width="18" /> +       top_delta="-3" +       width="23" />       <button       follows="top|left"       height="23" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index d65b86f007..2a53b3e2fa 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -42,7 +42,7 @@    <filter_editor     text_pad_left="10"     follows="left|top|right" - height="23" +   height="23"     label="Filter Inventory"     layout="topleft"     left="10" @@ -68,10 +68,10 @@       top_pad="10"       width="312">      <inventory_panel -        bg_opaque_color="DkGray2" -   bg_alpha_color="DkGray2" -   background_visible="true" -   background_opaque="true" +     bg_opaque_color="DkGray2" +     bg_alpha_color="DkGray2" +     background_visible="true" +     background_opaque="true"       border="false"       bevel_style="none"       follows="all" @@ -82,13 +82,14 @@       left="0"       name="All Items"       sort_order_setting="InventorySortOrder" +	 show_item_link_overlays="true"       top="16"       width="288" />      <recent_inventory_panel -        bg_opaque_color="DkGray2" -   bg_alpha_color="DkGray2" -   background_visible="true" -   background_opaque="true" +     bg_opaque_color="DkGray2" +     bg_alpha_color="DkGray2" +     background_visible="true" +     background_opaque="true"       border="false"       bevel_style="none"       follows="all" @@ -98,6 +99,7 @@       layout="topleft"       left_delta="0"       name="Recent Items" +	 show_item_link_overlays="true"       width="290" />    </tab_container>    <layout_stack diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 769f9b7bbf..741f60669a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -5,8 +5,8 @@   border="false"   height="600"   follows="all" - label="Outfit Edit"   layout="topleft" + help_topic="edit_outfit"   left="0"   min_height="350"   name="outfit_edit" @@ -51,6 +51,7 @@      <string name="Filter.All" value="All"/>      <string name="Filter.Clothes/Body" value="Clothes/Body"/>      <string name="Filter.Objects" value="Objects"/> +    <string name="Filter.Custom" value="Custom filter"/>      <button @@ -85,7 +86,6 @@       bevel_style="none"       follows="top|left|right"       height="40" -     label="bottom_panel"       layout="topleft"       left="6"       name="header_panel" @@ -106,7 +106,6 @@               bevel_style="none"               follows="top|right"               height="38" -             label="bottom_panel"               layout="topleft"               left_pad="5"               name="outfit_name_and_status" @@ -160,7 +159,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap          <layout_panel           layout="topleft"           height="187" -         label="IM Control Panel"           min_height="100"           name="outfit_wearables_panel"           width="313" @@ -183,7 +181,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap                   bg_alpha_color="DkGray2"                   layout="topleft"                   height="154" -                 label="add_button_and_combobox"                   name="add_button_and_combobox"                   width="311"                   user_resize="false" @@ -256,15 +253,14 @@ It is calculated as border_size + 2*UIResizeBarOverlap  		             background_image="TextField_Search_Off"  		             enabled="true"  		             follows="left|right|top" -		             font="SansSerif" -		             label="Filter" +		             label="Filter Inventory Wearables"  		             layout="topleft"  		             left="5"  		             width="290"  		             height="25"  		             name="look_item_filter" +		             search_button_visible="true"  		             text_color="black" -		             text_pad_left="25"  		             visible="true"/>                  </layout_panel> @@ -344,7 +340,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap       bevel_style="none"       follows="bottom|left|right"       height="27" -     label="bottom_panel"       layout="topleft"       left="5"       name="no_add_wearables_button_bar" @@ -379,7 +374,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap       bevel_style="none"       follows="left|right|bottom"       height="27" -     label="add_wearables_button_bar"       layout="topleft"       left="5"       name="add_wearables_button_bar" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 13e1f5ba5c..de1f2cf31b 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -30,6 +30,7 @@             height="490"             name="outfitslist_tab"             background_visible="true" +           help_topic="my_outfits_tab"             follows="all"             label="MY OUTFITS"             layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_list.xml b/indra/newview/skins/default/xui/en/panel_outfits_list.xml index 5cf94c25d7..5c9ae51a48 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_list.xml @@ -14,6 +14,7 @@       background_visible="true"       bg_alpha_color="DkGray2"       bg_opaque_color="DkGray2" +     empty_accordion_text.value="Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search]."       follows="all"       height="400"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index b79ef1e287..da28773c74 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -173,6 +173,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M         		 background_visible="true"         		 bg_alpha_color="DkGray2"         		 bg_opaque_color="DkGray2" +             empty_accordion_text.value=""               follows="all"               height="356"               layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index c9e41edd5a..59f1f6d638 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -2,7 +2,7 @@  <panel   background_visible="true"   follows="all" - height="570" + height="610"   layout="topleft"   left="0"   min_height="350" @@ -181,7 +181,7 @@      <scroll_container       color="DkGray2"       follows="all" -     height="532" +     height="572"       layout="topleft"       left="9"       name="place_scroll" @@ -191,7 +191,7 @@          <panel           bg_alpha_color="DkGray2"           follows="left|top|right" -         height="540" +         height="580"           layout="topleft"           left="0"           min_height="300" @@ -337,21 +337,22 @@              <accordion               fit_parent="true"               follows="all" -             height="223" +             height="268"               layout="topleft"               single_expansion="true"               left="0"               name="advanced_info_accordion" -             top_pad="10" +             top_pad="5"               width="313">                  <accordion_tab -                 height="170" +                 fit_panel="false" +                 height="175"                   layout="topleft"                   name="parcel_characteristics_tab"                   title="Parcel">                      <panel                       follows="all" -                     height="160" +                     height="175"                       layout="topleft"                       left="0"                       name="parcel_characteristics_panel" @@ -548,8 +549,8 @@                           name="about_land_btn"                           right="-5"                           tab_stop="false" -                         top="138" -                         width="90"> +                         top_pad="2" +                         width="140">                              <click_callback                               function="Floater.Show"                               parameter="about_land" /> @@ -558,7 +559,8 @@                  </accordion_tab>                  <accordion_tab                   expanded="false" -                 height="150" +                 fit_panel="false" +                 height="125"                   layout="topleft"                   name="region_information_tab"                   title="Region"> @@ -677,7 +679,8 @@                           name="region_info_btn"                           right="-5"                           tab_stop="false" -                         width="105"> +                         top_pad="2" +                         width="180">                              <click_callback                               function="Floater.Show"                               parameter="region_info" /> @@ -686,13 +689,14 @@                  </accordion_tab>                  <accordion_tab                   expanded="false" -                 height="190" +                 fit_panel="false" +                 height="180"                   layout="topleft"                   name="estate_information_tab"                   title="Estate">                      <panel                       follows="all" -                     height="189" +                     height="180"                       layout="topleft"                       left="0"                       name="estate_information_panel" @@ -775,13 +779,14 @@                  </accordion_tab>                  <accordion_tab                   expanded="false" -                 height="320" +                 fit_panel="false" +                 height="290"                   layout="topleft"                   name="sales_tab"                   title="For Sale">                      <panel                       follows="all" -                     height="300" +                     height="290"                       layout="topleft"                       left="0"                       name="sales_panel" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index 1c68d59993..a69e8d29b0 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -348,7 +348,7 @@         Busy mode response:      </text>      <text_editor -     control_name="BusyModeResponse2" +     control_name="BusyModeResponse"        text_readonly_color="LabelDisabledColor"        bg_writeable_color="LtGray"        use_ellipses="false" diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index 3d7b0b7edc..ae08a13793 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -111,6 +111,7 @@ width="333">     label="Filter Outfits"     max_length="300"     name="Filter" +   search_button_visible="true"     top_pad="10"     width="303" />     <panel diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index c816fd1479..b736f5e29c 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -395,7 +395,7 @@ top_pad="10"  			    label_width="75"  			    left="120"  			    width="170" -			    min_val="1" +			    min_val="0"  			    height="23"  			    max_val="999999999"  			    top_pad="10"/> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0d14a6b3c8..294267d43b 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3181,12 +3181,12 @@ Abuse Report</string>    <!-- language specific white-space characters, delimiters, spacers, item separation symbols -->    <string name="sentences_separator" value=" "></string> -  <string name="words_separator">, </string> +  <string name="words_separator" value=", "/>    <string name="server_is_down">  	Despite our best efforts, something unexpected has gone wrong. -	Please check secondlife.com/status to see if there is a known problem with the service.   +	Please check status.secondlifegrid.net to see if there is a known problem with the service.            If you continue to experience problems, please check your network and firewall setup.    </string> diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml new file mode 100644 index 0000000000..05d7447a6f --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<accordion + height="100" + name="accordion" + width="200"> +    <empty_accordion_text +     follows="all" +     height="100" +     h_pad="10" +     name="no_visible_items_msg" +     v_pad="15" +     width="200" +     wrap="true "/> +</accordion> diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml index dfd301a770..48b987d7e8 100644 --- a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml +++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml @@ -4,5 +4,6 @@                name="color_swatch">    <color_swatch.caption_text name="caption"                               halign="center" -                             follows="left|right|bottom"/> +                             follows="left|right|bottom" +                             v_pad="2"/>  </color_swatch> diff --git a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml index 33c3475eb2..757f0f49d1 100644 --- a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml +++ b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml @@ -3,7 +3,8 @@    <multiselect_text font="SansSerifSmall"/>    <caption_text text="Multiple"                   halign="center"  -                font="SansSerifSmall"/> +                font="SansSerifSmall" +                v_pad="2"/>    <border bevel_style="in"/>  </texture_picker> diff --git a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml index 0e69671f06..e5703c559b 100644 --- a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml @@ -4,11 +4,11 @@  	<menu_item_check label="移動ボタン" name="ShowMoveButton"/>  	<menu_item_check label="視界ボタン" name="ShowCameraButton"/>  	<menu_item_check label="スナップショットボタン" name="ShowSnapshotButton"/> -	<menu_item_check label="サイドバーのボタン" name="ShowSidebarButton"/> -	<menu_item_check label="制作のボタン" name="ShowBuildButton"/> -	<menu_item_check label="検索のボタン" name="ShowSearchButton"/> -	<menu_item_check label="地図のボタン" name="ShowWorldMapButton"/> -	<menu_item_check label="ミニマップのボタン" name="ShowMiniMapButton"/> +	<menu_item_check label="サイドバーボタン" name="ShowSidebarButton"/> +	<menu_item_check label="制作ボタン" name="ShowBuildButton"/> +	<menu_item_check label="検索ボタン" name="ShowSearchButton"/> +	<menu_item_check label="地図ボタン" name="ShowWorldMapButton"/> +	<menu_item_check label="ミニマップボタン" name="ShowMiniMapButton"/>  	<menu_item_call label="切り取り" name="NearbyChatBar_Cut"/>  	<menu_item_call label="コピー" name="NearbyChatBar_Copy"/>  	<menu_item_call label="貼り付け" name="NearbyChatBar_Paste"/> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 1ac7677b07..c82f1198a4 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -349,7 +349,7 @@ L$ が不足しているのでこのグループに参加することができ  		<usetemplate name="okcancelbuttons" notext="もう一度試す" yestext="新しいアカウントを作成"/>  	</notification>  	<notification name="InvalidCredentialFormat"> -		「ユーザー名」欄にアバターのファーストネームとラストネーム両方を入力してからログインしてください。 +		「ユーザーネーム」欄にアバターのファーストネームとラストネーム両方を入力してからログインしてください。  	</notification>  	<notification name="AddClassified">  		クラシファイド広告は、検索ディレクトリと [http://secondlife.com/community/classifieds secondlife.com] の「クラシファイド広告」セクションに一週間掲載されます。 diff --git a/indra/newview/skins/default/xui/ja/panel_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml index f0ebc67ef5..47d7a88b4c 100644 --- a/indra/newview/skins/default/xui/ja/panel_login.xml +++ b/indra/newview/skins/default/xui/ja/panel_login.xml @@ -9,9 +9,9 @@  	<layout_stack name="login_widgets">  		<layout_panel name="login">  			<text name="username_text"> -				ユーザー名: +				ユーザーネーム:  			</text> -			<line_editor label="ユーザー名" name="username_edit" tool_tip="[SECOND_LIFE] ユーザー名"/> +			<line_editor label="ユーザーネーム" name="username_edit" tool_tip="[SECOND_LIFE] ユーザーネーム"/>  			<text name="password_text">  				パスワード:  			</text> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 7671f58691..4044110b47 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -26,9 +26,9 @@ Placa gráfica: [GRAPHICS_CARD]  Versão libcurl: [LIBCURL_VERSION]  Versão J2C Decoder: [J2C_VERSION] -Versão do driver de áudio: [AUDIO_DRIVER_VERSION]  +Versão do driver de áudio: [AUDIO_DRIVER_VERSION]  Versão Qt Webkit: [QT_WEBKIT_VERSION] -Versão Vivox: [VIVOX_VERSION] +Versão do servidor de voz: [VOICE_VERSION]  	</floater.string>  	<floater.string name="none">  		(nenhum) diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml index 787836a8bd..56ffcbdece 100644 --- a/indra/newview/skins/default/xui/pt/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml @@ -63,6 +63,9 @@  				Nenhum lote selecionado.  Vá para o menu Mundo > Sobre o terreno ou selecione outro lote para mostrar os detalhes.  			</panel.string> +			<panel.string name="time_stamp_template"> +				[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] +			</panel.string>  			<text name="Name:">  				Nome:  			</text> diff --git a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml index 5fb64f64b3..9473ee7ce9 100644 --- a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml @@ -3,41 +3,48 @@  	<floater.string name="InvalidAvatar">  		AVATAR INVÁLIDO  	</floater.string> -	<text name="composite_label"> -		Texturas compostas -	</text> -	<button label="Tombar" label_selected="Tombar" name="Dump"/>  	<scroll_container name="profile_scroll">  		<panel name="scroll_content_panel"> -			<texture_picker label="Cabelo" name="hair-baked"/> -			<texture_picker label="Cabelo" name="hair_grain"/> -			<texture_picker label="Cabelo alpha" name="hair_alpha"/> -			<texture_picker label="Cabeça" name="head-baked"/> -			<texture_picker label="Maquilagem" name="head_bodypaint"/> -			<texture_picker label="Cabeça Alpha" name="head_alpha"/> -			<texture_picker label="Tatuagem na cabeça" name="head_tattoo"/> -			<texture_picker label="Olhos" name="eyes-baked"/> -			<texture_picker label="Olho" name="eyes_iris"/> -			<texture_picker label="Olhos Alpha" name="eyes_alpha"/> -			<texture_picker label="Cintura acima" name="upper-baked"/> -			<texture_picker label="Pintura corporal, cintura para cima" name="upper_bodypaint"/> -			<texture_picker label="Camiseta" name="upper_undershirt"/> -			<texture_picker label="Luvas" name="upper_gloves"/> -			<texture_picker label="Camisa" name="upper_shirt"/> -			<texture_picker label="Jaqueta (cima)" name="upper_jacket"/> -			<texture_picker label="Alpha de cima" name="upper_alpha"/> -			<texture_picker label="Tatuagem parte de cima" name="upper_tattoo"/> -			<texture_picker label="Cintura para baixo" name="lower-baked"/> -			<texture_picker label="Pintura corporal, cintura para baixo" name="lower_bodypaint"/> -			<texture_picker label="Roupa de baixo" name="lower_underpants"/> -			<texture_picker label="Meias" name="lower_socks"/> -			<texture_picker label="Sapatos" name="lower_shoes"/> -			<texture_picker label="Calças" name="lower_pants"/> -			<texture_picker label="Jaqueta" name="lower_jacket"/> -			<texture_picker label="Alpha inferior" name="lower_alpha"/> -			<texture_picker label="Tatuagem de baixo" name="lower_tattoo"/> -			<texture_picker label="Saia" name="skirt-baked"/> -			<texture_picker label="Saia" name="skirt"/> +			<text name="label"> +				Pronto +Texturas +			</text> +			<text name="composite_label"> +				Compósito: +Texturas +			</text> +			<button label="Enviar IDs para painel" label_selected="Dump" name="Dump"/> +			<panel name="scroll_content_panel"> +				<texture_picker label="Cabelo" name="hair-baked"/> +				<texture_picker label="Cabelo" name="hair_grain"/> +				<texture_picker label="Cabelo alpha" name="hair_alpha"/> +				<texture_picker label="Cabeça" name="head-baked"/> +				<texture_picker label="Maquilagem" name="head_bodypaint"/> +				<texture_picker label="Cabeça Alpha" name="head_alpha"/> +				<texture_picker label="Tatuagem na cabeça" name="head_tattoo"/> +				<texture_picker label="Olhos" name="eyes-baked"/> +				<texture_picker label="Olho" name="eyes_iris"/> +				<texture_picker label="Olhos Alpha" name="eyes_alpha"/> +				<texture_picker label="Cintura acima" name="upper-baked"/> +				<texture_picker label="Pintura corporal, cintura para cima" name="upper_bodypaint"/> +				<texture_picker label="Camiseta" name="upper_undershirt"/> +				<texture_picker label="Luvas" name="upper_gloves"/> +				<texture_picker label="Camisa" name="upper_shirt"/> +				<texture_picker label="Jaqueta (cima)" name="upper_jacket"/> +				<texture_picker label="Alpha de cima" name="upper_alpha"/> +				<texture_picker label="Tatuagem parte de cima" name="upper_tattoo"/> +				<texture_picker label="Cintura para baixo" name="lower-baked"/> +				<texture_picker label="Cintura para baixo" name="lower_bodypaint"/> +				<texture_picker label="Roupa de baixo" name="lower_underpants"/> +				<texture_picker label="Meias" name="lower_socks"/> +				<texture_picker label="Sapatos" name="lower_shoes"/> +				<texture_picker label="Calças" name="lower_pants"/> +				<texture_picker label="Jaqueta" name="lower_jacket"/> +				<texture_picker label="Alpha inferior" name="lower_alpha"/> +				<texture_picker label="Tatuagem de baixo" name="lower_tattoo"/> +				<texture_picker label="Saia" name="skirt-baked"/> +				<texture_picker label="Saia" name="skirt"/> +			</panel>  		</panel>  	</scroll_container>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml new file mode 100644 index 0000000000..24e41ac8c8 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_buy_currency_html" title="COMPRAR MOEDA"/> diff --git a/indra/newview/skins/default/xui/pt/floater_map.xml b/indra/newview/skins/default/xui/pt/floater_map.xml index 3a04528228..f8e4e76752 100644 --- a/indra/newview/skins/default/xui/pt/floater_map.xml +++ b/indra/newview/skins/default/xui/pt/floater_map.xml @@ -1,5 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Map" title="Mini Mapa"> +<floater name="Map" title="">  	<floater.string name="mini_map_north">  		N  	</floater.string> diff --git a/indra/newview/skins/default/xui/pt/floater_moveview.xml b/indra/newview/skins/default/xui/pt/floater_moveview.xml index 9c02570076..b1dc65e3af 100644 --- a/indra/newview/skins/default/xui/pt/floater_moveview.xml +++ b/indra/newview/skins/default/xui/pt/floater_moveview.xml @@ -6,18 +6,48 @@  	<string name="walk_back_tooltip">  		Andar para trás (flecha para baixo ou S)  	</string> +	<string name="walk_left_tooltip"> +		Andar para a esquerda (Shift + Seta esquerda ou A) +	</string> +	<string name="walk_right_tooltip"> +		Andar para a direita (Shift + Seta direita ou D) +	</string>  	<string name="run_forward_tooltip">  		Correr para frente (flecha para cima ou W)  	</string>  	<string name="run_back_tooltip">  		Correr para trás (flecha para baixo ou S)  	</string> +	<string name="run_left_tooltip"> +		Correr para a esquerda (Shift + Seta esquerda ou A) +	</string> +	<string name="run_right_tooltip"> +		Correr para a direita (Shift + Seta direita ou D) +	</string>  	<string name="fly_forward_tooltip">  		Voar para frente (flecha para cima ou W)  	</string>  	<string name="fly_back_tooltip">  		Voar para trás (flecha para baixo ou S)  	</string> +	<string name="fly_left_tooltip"> +		Voar para a esquerda (Shift + Seta esquerda ou A) +	</string> +	<string name="fly_right_tooltip"> +		Voar para a direita (Shift + Seta direita ou D) +	</string> +	<string name="fly_up_tooltip"> +		Voar para cima (tecla E) +	</string> +	<string name="fly_down_tooltip"> +		Voar para baixo (tecla C) +	</string> +	<string name="jump_tooltip"> +		Pular (tecla E) +	</string> +	<string name="crouch_tooltip"> +		Agachar (tecla C) +	</string>  	<string name="walk_title">  		Andar  	</string> @@ -28,10 +58,12 @@  		Voar  	</string>  	<panel name="panel_actions"> -		<button label="" label_selected="" name="turn left btn" tool_tip="Virar à esquerda (flecha ESQ ou A)"/> -		<button label="" label_selected="" name="turn right btn" tool_tip="Virar à direita (flecha DIR ou D)"/>  		<button label="" label_selected="" name="move up btn" tool_tip="Voar para cima (tecla E)"/> +		<button label="" label_selected="" name="turn left btn" tool_tip="Virar à esquerda (flecha ESQ ou A)"/> +		<joystick_slide name="move left btn" tool_tip="Andar para a esquerda (Shift + Seta esquerda ou A)"/>  		<button label="" label_selected="" name="move down btn" tool_tip="Voar para baixo (tecla C)"/> +		<button label="" label_selected="" name="turn right btn" tool_tip="Virar à direita (flecha DIR ou D)"/> +		<joystick_slide name="move right btn" tool_tip="Andar para a direita (Shift + Seta direita ou D)"/>  		<joystick_turn name="forward btn" tool_tip="Andar para frente (flecha para cima ou W)"/>  		<joystick_turn name="backward btn" tool_tip="Andar para trás (flecha para baixo ou S)"/>  	</panel> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml b/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml index e648a7d873..d094c1b63a 100644 --- a/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml @@ -9,9 +9,6 @@  	<floater.string name="Title">  		Anotação: [NAME]  	</floater.string> -	<floater.string label="Salvar" label_selected="Salvar" name="Save"> -		Salvar -	</floater.string>  	<text name="desc txt">  		Descrição:  	</text> @@ -19,4 +16,5 @@  		Carregando...  	</text_editor>  	<button label="Salvar" label_selected="Salvar" name="Save"/> +	<button label="Excluir" label_selected="Excluir" name="Delete"/>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 74b45f1d1e..dbc8b3ffbe 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -67,9 +67,9 @@  	<text name="RenderingCost" tool_tip="Mostra o cálculo do custo de renderização do objeto">  		þ: [COUNT]  	</text> -	<check_box name="checkbox uniform"/> -	<text name="checkbox uniform label"> -		Esticar ambos os lados +	<check_box label="" name="checkbox uniform"/> +	<text label="Esticar ambos lados" name="checkbox uniform label"> +		Esticar ambos lados  	</text>  	<check_box initial_value="true" label="Esticar texturas" name="checkbox stretch textures"/>  	<check_box initial_value="true" label="Mostrar na grade" name="checkbox snap to grid"/> diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml index de3178b946..5cb1b211cf 100644 --- a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml @@ -5,7 +5,7 @@  	<menu_item_call label="Tirar" name="Detach"/>  	<menu_item_call label="Largar" name="Drop"/>  	<menu_item_call label="Ficar de pé" name="Stand Up"/> -	<menu_item_call label="Minha aparência" name="Appearance..."/> +	<menu_item_call label="Trocar de look" name="Change Outfit"/>  	<menu_item_call label="Meus amigos" name="Friends..."/>  	<menu_item_call label="Meus grupos" name="Groups..."/>  	<menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml index ccbb921ebc..62055303b5 100644 --- a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml @@ -20,7 +20,9 @@  		<context_menu label="Tirar  ▶" name="Object Detach"/>  		<menu_item_call label="Tirar tudo" name="Detach All"/>  	</context_menu> -	<menu_item_call label="Minha aparência" name="Appearance..."/> +	<menu_item_call label="Trocar de look" name="Chenge Outfit"/> +	<menu_item_call label="Editar meu look" name="Edit Outfit"/> +	<menu_item_call label="Editar meu corpo" name="Edit My Shape"/>  	<menu_item_call label="Meus amigos" name="Friends..."/>  	<menu_item_call label="Meus grupos" name="Groups..."/>  	<menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml index 43b446a67e..479d02512f 100644 --- a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml @@ -4,6 +4,11 @@  	<menu_item_check label="Botão de movimento" name="ShowMoveButton"/>  	<menu_item_check label="Botão de ver" name="ShowCameraButton"/>  	<menu_item_check label="Botão de fotos" name="ShowSnapshotButton"/> +	<menu_item_check label="Botão da Barra lateral" name="ShowSidebarButton"/> +	<menu_item_check label="Botão Construir" name="ShowBuildButton"/> +	<menu_item_check label="Botão Buscar" name="ShowSearchButton"/> +	<menu_item_check label="Botão Mapa" name="ShowWorldMapButton"/> +	<menu_item_check label="Botão do Mini Mapa" name="ShowMiniMapButton"/>  	<menu_item_call label="Cortar" name="NearbyChatBar_Cut"/>  	<menu_item_call label="Copiar" name="NearbyChatBar_Copy"/>  	<menu_item_call label="Colar" name="NearbyChatBar_Paste"/> diff --git a/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml index effc970eb8..c3e0608954 100644 --- a/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8"?>  <menu name="Gear Menu">  	<menu_item_call label="Ficar de pé" name="stand_up"/> -	<menu_item_call label="Minha aparência" name="my_appearance"/> +	<menu_item_call label="Trocar de look" name="change_outfit"/>  	<menu_item_call label="Meu perfil" name="my_profile"/>  	<menu_item_call label="Meus amigos" name="my_friends"/>  	<menu_item_call label="Meus grupos" name="my_groups"/> diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml index 345534261a..1b86b37075 100644 --- a/indra/newview/skins/default/xui/pt/menu_inventory.xml +++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml @@ -54,6 +54,7 @@  	<menu_item_call label="Remover item" name="Purge Item"/>  	<menu_item_call label="Restaurar item" name="Restore Item"/>  	<menu_item_call label="Abrir" name="Open"/> +	<menu_item_call label="Abrir original" name="Open Original"/>  	<menu_item_call label="Propriedades" name="Properties"/>  	<menu_item_call label="Renomear" name="Rename"/>  	<menu_item_call label="Copiar item UUID" name="Copy Asset UUID"/> diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml index 8ea87a06d1..a43ac271a9 100644 --- a/indra/newview/skins/default/xui/pt/menu_login.xml +++ b/indra/newview/skins/default/xui/pt/menu_login.xml @@ -2,7 +2,7 @@  <menu_bar name="Login Menu">  	<menu label="Eu" name="File">  		<menu_item_call label="Preferências" name="Preferences..."/> -		<menu_item_call label="Sair" name="Quit"/> +		<menu_item_call label="Sair do [APP_NAME]" name="Quit"/>  	</menu>  	<menu label="Ajuda" name="Help">  		<menu_item_call label="Ajuda do [SECOND_LIFE]" name="Second Life Help"/> diff --git a/indra/newview/skins/default/xui/pt/menu_participant_list.xml b/indra/newview/skins/default/xui/pt/menu_participant_list.xml index c0db7752af..01f1d4ef80 100644 --- a/indra/newview/skins/default/xui/pt/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/pt/menu_participant_list.xml @@ -14,8 +14,8 @@  	<context_menu label="Opções do moderador >" name="Moderator Options">  		<menu_item_check label="Pode bater papo por escrito" name="AllowTextChat"/>  		<menu_item_call label="Silenciar este participante" name="ModerateVoiceMuteSelected"/> -		<menu_item_call label="Silenciar os demais" name="ModerateVoiceMuteOthers"/>  		<menu_item_call label="Desfazer silenciar deste participante" name="ModerateVoiceUnMuteSelected"/> -		<menu_item_call label="Desfazer silenciar dos demais" name="ModerateVoiceUnMuteOthers"/> +		<menu_item_call label="Silenciar todos" name="ModerateVoiceMute"/> +		<menu_item_call label="Desfazer silenciar para todos" name="ModerateVoiceUnmute"/>  	</context_menu>  </context_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 84ad056df6..b091cc2c97 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -7,7 +7,7 @@  		</menu_item_call>  		<menu_item_call label="Comprar L$" name="Buy and Sell L$"/>  		<menu_item_call label="Meu perfil" name="Profile"/> -		<menu_item_call label="Minha aparência" name="Appearance"/> +		<menu_item_call label="Trocar de look" name="ChangeOutfit"/>  		<menu_item_check label="Meu inventário" name="Inventory"/>  		<menu_item_check label="Meu inventário" name="ShowSidetrayInventory"/>  		<menu_item_check label="Meus gestos" name="Gestures"/> @@ -162,6 +162,7 @@  			<menu_item_check label="Objetos flexíveis" name="Flexible Objects"/>  		</menu>  		<menu_item_check label="Executar diversas instâncias" name="Run Multiple Threads"/> +		<menu_item_check label="Usar plugin de leitura de threads" name="Use Plugin Read Thread"/>  		<menu_item_call label="Limpar cache de grupo" name="ClearGroupCache"/>  		<menu_item_check label="Smoothing de mouse" name="Mouse Smoothing"/>  		<menu label="Atalhos" name="Shortcuts"> @@ -188,7 +189,6 @@  			<menu_item_call label="Mais zoom" name="Zoom In"/>  			<menu_item_call label="Zoom padrão" name="Zoom Default"/>  			<menu_item_call label="Menos zoom" name="Zoom Out"/> -			<menu_item_call label="Alternar tela inteira" name="Toggle Fullscreen"/>  		</menu>  		<menu_item_call label="Mostrar configurações de depuração" name="Debug Settings"/>  		<menu_item_check label="Show Develop Menu" name="Debug Mode"/> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 462dcf2b21..e64940ecb1 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -323,6 +323,9 @@ Você precisa de uma conta para entrar no [SECOND_LIFE]. Você gostaria de abrir  		</url>  		<usetemplate name="okcancelbuttons" notext="Tentar novamente" yestext="Abrir conta"/>  	</notification> +	<notification name="InvalidCredentialFormat"> +		Digite o nome e sobrenome do seu avatar no campo Nome de usuário, depois faça o login novamente. +	</notification>  	<notification name="AddClassified">  		Os anúncios serão publicados na seção 'Classificados' das buscas e em [http://secondlife.com/community/classifieds secondlife.com] durante uma semana.  Escreva seu anúncio e clique em 'Publicar...'  @@ -603,6 +606,11 @@ Esperada [VALIDS]  	<notification name="CannotEncodeFile">  		Impossível codificar o arquivo: [FILE]  	</notification> +	<notification name="CorruptedProtectedDataStore"> +		Não foi possível fazer a leitura dos dados protegidos, redefinindo. +   Isso pode ocorrer após mudanças na configuração da rede. +		<usetemplate name="okbutton" yestext="OK"/> +	</notification>  	<notification name="CorruptResourceFile">  		Fonte do arquivo corrompida: [FILE]  	</notification> @@ -962,6 +970,12 @@ em TODOS OS TERRENOS deste sim?  Por favor, insira um valor maior.  	</notification> +	<notification name="ConfirmItemDeleteHasLinks"> +		Pelo menos um dos itens possui links que levam a ele.  Ao excluir o item, os links não funcionarão mais.   Por isso, recomendamos excluir os links primeiro. + +Tem certeza de que quer excluir estes items? +		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> +	</notification>  	<notification name="ConfirmObjectDeleteLock">  		Pelo menos um dos itens que você selecionou está trancado. @@ -1103,6 +1117,42 @@ Pressione a tecla F1 para ajuda ou aprender mais sobre [SECOND_LIFE].  Por favor, escolha se o seu avatar é feminino ou masculino. Você pode mudar de idéia depois.  		<usetemplate name="okcancelbuttons" notext="Feminino" yestext="Masculino"/>  	</notification> +	<notification name="CantTeleportToGrid"> +		Não foi possível ir para [SLURL], que fica em outro grid ([GRID]) em relação ao grid atual, ([CURRENT_GRID]).  Feche o Visualizador e tente novamente. +		<usetemplate name="okbutton" yestext="OK"/> +	</notification> +	<notification name="GeneralCertificateError"> +		Falha de conexão com o servidor. +[REASON] + +SubjectName: [SUBJECT_NAME_STRING] +IssuerName: [ISSUER_NAME_STRING] +Válido de: [VALID_FROM] +Válido até: [VALID_TO] +MD5 Fingerprint: [SHA1_DIGEST] +Impressão digital SHA1: [MD5_DIGEST] +Uso da chave: [KEYUSAGE] +Uso estendido da chave: [EXTENDEDKEYUSAGE] +Identificador chave de assunto: [SUBJECTKEYIDENTIFIER] +		<usetemplate name="okbutton" yestext="OK"/> +	</notification> +	<notification name="TrustCertificateError"> +		A autoridade de certificação deste servidor é desconhecida. + +Dados do certificado: +SubjectName: [SUBJECT_NAME_STRING] +IssuerName: [ISSUER_NAME_STRING] +Válido de: [VALID_FROM] +Válido até: [VALID_TO] +MD5 Fingerprint: [SHA1_DIGEST] +Impressão digital SHA1: [MD5_DIGEST] +Uso da chave: [KEYUSAGE] +Uso estendido da chave: [EXTENDEDKEYUSAGE] +Identificador chave de assunto: [SUBJECTKEYIDENTIFIER] + +Confiar nesta autoridade? +		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Confiança"/> +	</notification>  	<notification name="NotEnoughCurrency">  		[NAME] L$ [PRICE] Você não possui suficientes L$ para fazer isso.  	</notification> @@ -1493,9 +1543,9 @@ Ir para o Banco de Conhecimento para maiores informações sobre Classificaçõe  		Você não é permitido nesta região devido à sua Classificação de maturidade.  	</notification>  	<notification name="RegionEntryAccessBlocked_Change"> -		Você não pode entrar nessa região devido à sua seleção de maturidade.  +		Você não pode entrar nessa região devido à sua seleção de maturidade. -Clique em 'Mudar preferência' para aumentar o nível de maturidade e entrar nessa região.  De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] .  Para modificar esta configuração, vá à Eu > Preferências > Geral. +Clique em 'Mudar preferência' para aumentar seu nível de maturidade e ganhar acesso imediato. Você então poderá fazer buscas e acessar conteúdo [REGIONMATURITY]. Para modificar o nível de maturidade, use o menu Eu > Preferências > Gerais.  		<form name="form">  			<button name="OK" text="Mudar preferência"/>  			<button default="true" name="Cancel" text="Fechar"/> @@ -2262,15 +2312,6 @@ Por favor, tente novamente em alguns instantes.  			<button name="Mute" text="Bloquear"/>  		</form>  	</notification> -	<notification name="ObjectGiveItemUnknownUser"> -		Um objeto chamado [OBJECTFROMNAME] de (residente desconhecido) lhe deu [OBJECTTYPE]: -[ITEM_SLURL] -		<form name="form"> -			<button name="Keep" text="Segure"/> -			<button name="Discard" text="Descarte"/> -			<button name="Mute" text="Bloquear"/> -		</form> -	</notification>  	<notification name="UserGiveItem">  		[NAME_SLURL] lhe deu [OBJECTTYPE]:  [ITEM_SLURL] @@ -2583,8 +2624,52 @@ O botão será exibido quando houver espaço suficente.  	<notification name="ShareNotification">  		Arraste itens do inventário para uma pessoa no seletor de residentes  	</notification> +	<notification name="DeedToGroupFail"> +		Ocorreu uma falha durante a doação ao grupo. +	</notification>  	<notification name="AvatarRezNotification"> -		O avatar de '[NAME]' renderizou em [TIME] s. +		( [EXISTENCE] segundos de vida ) +O avatar de '[NAME]' emergiu em [TIME] segundos. +	</notification> +	<notification name="AvatarRezSelfNotification"> +		( [EXISTENCE] segundos de vida ) +Você confeccionou seu look em [TIME] segundos. +	</notification> +	<notification name="AvatarRezCloudNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' transformou-se em nuvem. +	</notification> +	<notification name="AvatarRezArrivedNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' surgiu. +	</notification> +	<notification name="AvatarRezLeftCloudNotification"> +		( [EXISTENCE] segundos de vida ) +O avatar de '[NAME]' transformou-se em nuvem depois de [TIME] segundos. +	</notification> +	<notification name="AvatarRezEnteredAppearanceNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' entrou no modo aparência. +	</notification> +	<notification name="AvatarRezLeftAppearanceNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' sair do modo aparecer. +	</notification> +	<notification name="AvatarRezLeftNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' saiu totalmente carregado. +	</notification> +	<notification name="ConfirmLeaveCall"> +		Tem certeza de que quer sair desta ligação? +		<usetemplate ignoretext="Confirmar antes de deixar ligação" name="okcancelignore" notext="Não" yestext="Sim"/> +	</notification> +	<notification name="ConfirmMuteAll"> +		Você silenciou todos os participantes de uma ligação de grupo. +Todos os demais residentes que entrarem na ligação mais tarde também serão silenciados, mesmo se você sair da ligação. + + +Silenciar todos? +		<usetemplate ignoretext="Confirmar antes de silenciar todos os participantes em ligações de grupo." name="okcancelignore" notext="OK" yestext="Cancelar"/>  	</notification>  	<global name="UnsupportedCPU">  		- A velocidade da sua CPU não suporta os requisitos mínimos exigidos. diff --git a/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml new file mode 100644 index 0000000000..de764d8025 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml new file mode 100644 index 0000000000..094a03553b --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> +	<button label="Trocar" name="switch_btn"/> +	<button label="Comprar >" name="bodyparts_shop_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml index 092135bd42..9fd7da55df 100644 --- a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml @@ -1,11 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="bottom_tray"> -	<string name="SpeakBtnToolTip"> -		Liga e desliga o microfone -	</string> -	<string name="VoiceControlBtnToolTip"> -		Mostra/oculta os controles de voz -	</string> +	<string name="SpeakBtnToolTip" value="Liga e desliga o microfone"/> +	<string name="VoiceControlBtnToolTip" value="Mostra/oculta os controles de voz"/>  	<layout_stack name="toolbar_stack">  		<layout_panel name="speak_panel">  			<talk_button name="talk"> @@ -24,6 +20,21 @@  		<layout_panel name="snapshot_panel">  			<button label="" name="snapshots" tool_tip="Tirar foto"/>  		</layout_panel> +		<layout_panel name="sidebar_btn_panel"> +			<button label="Barra lateral" name="sidebar_btn" tool_tip="Mostra/oculta a barra lateral"/> +		</layout_panel> +		<layout_panel name="build_btn_panel"> +			<button label="Construir" name="build_btn" tool_tip="Mostra/oculta ferramentas de Construção"/> +		</layout_panel> +		<layout_panel name="search_btn_panel"> +			<button label="Busca" name="search_btn" tool_tip="Mostra/oculta os gestos"/> +		</layout_panel> +		<layout_panel name="world_map_btn_panel"> +			<button label="Mapa" name="world_map_btn" tool_tip="Mostra/oculta o Mapa Múndi"/> +		</layout_panel> +		<layout_panel name="mini_map_btn_panel"> +			<button label="Mini Mapa" name="mini_map_btn" tool_tip="Mostra/oculta o Mini Mapa"/> +		</layout_panel>  		<layout_panel name="im_well_panel">  			<chiclet_im_well name="im_well">  				<button name="Unread IM messages" tool_tip="Conversas"/> diff --git a/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml new file mode 100644 index 0000000000..bfdc7290d2 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> +	<button label="Adicionar +" name="add_btn"/> +	<button label="Comprar >" name="clothing_shop_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml new file mode 100644 index 0000000000..de764d8025 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml b/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml new file mode 100644 index 0000000000..3e4b12b001 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="cof_wearables"> +	<accordion name="cof_wearables_accordion"> +		<accordion_tab name="tab_attachments" title="Anexos"/> +		<accordion_tab name="tab_clothing" title="Vestuário"/> +		<accordion_tab name="tab_body_parts" title="Corpo"/> +	</accordion> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml new file mode 100644 index 0000000000..91d90a5660 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="deletable_wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml new file mode 100644 index 0000000000..6af84de0c7 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="dummy_clothing_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shape.xml b/indra/newview/skins/default/xui/pt/panel_edit_shape.xml index 504486c3bb..6b9ac94cac 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_shape.xml @@ -1,14 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="edit_shape_panel"> -	<panel name="avatar_sex_panel"> -		<text name="gender_text"> -			Sexo: -		</text> -		<radio_group name="sex_radio"> -			<radio_item label="Feminino" name="radio"/> -			<radio_item label="Masculino" name="radio2"/> -		</radio_group> -	</panel> +	<text name="avatar_height"> +		[HEIGHT] metros de altura +	</text>  	<panel label="Camisa" name="accordion_panel">  		<accordion name="wearable_accordion">  			<accordion_tab name="shape_body_tab" title="Corpo"/> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml index 23cde50acc..f85bb3c499 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml @@ -4,5 +4,6 @@  		<texture_picker label="Tatuagem de cabeça" name="Head Tattoo" tool_tip="Clique para escolher uma foto"/>  		<texture_picker label="Tatuagem superior" name="Upper Tattoo" tool_tip="Selecione uma foto"/>  		<texture_picker label="Tatuagem inferior" name="Lower Tattoo" tool_tip="Selecione uma foto"/> +		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>  	</panel>  </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml index a78539f274..f14a04f440 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml @@ -93,6 +93,12 @@  	<text name="edit_wearable_title" value="Editando forma"/>  	<panel label="Camisa" name="wearable_type_panel">  		<text name="description_text" value="Forma:"/> +		<radio_group name="sex_radio"> +			<radio_item label="" name="sex_male" tool_tip="Masculino" value="1"/> +			<radio_item label="" name="sex_female" tool_tip="Feminino" value="0"/> +		</radio_group> +		<icon name="male_icon" tool_tip="Masculino"/> +		<icon name="female_icon" tool_tip="Feminino"/>  	</panel>  	<panel label="gear_buttom_panel" name="gear_buttom_panel">  		<button name="friends_viewsort_btn" tool_tip="Opções"/> diff --git a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml index 6f21b78b10..e57a85a726 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml @@ -6,6 +6,9 @@  	<panel.string name="cant_view_group_land_text">  		Você não está autorizado a acessar terrenos de grupos  	</panel.string> +	<panel.string name="epmty_view_group_land_text"> +		Nada consta +	</panel.string>  	<panel.string name="cant_view_group_accounting_text">  		Você não está autorizado a acessar os dados de contabilidade do grupo.  	</panel.string> diff --git a/indra/newview/skins/default/xui/pt/panel_group_notices.xml b/indra/newview/skins/default/xui/pt/panel_group_notices.xml index 4b5a00c761..9ccb85cdf6 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_notices.xml @@ -39,6 +39,7 @@ Cada grupo pode enviar no máximo 200 avisos/dia  		<text name="string">  			Arrastar e soltar o item aqui para anexá-lo:  		</text> +		<button label="Inventário" name="open_inventory" tool_tip="Inventário aberto"/>  		<button label="Tirar" label_selected="Remover o anexo" name="remove_attachment" tool_tip="Remover anexo da notificação."/>  		<button label="Enviar" label_selected="Enviar" name="send_notice"/>  		<group_drop_target name="drop_target" tool_tip="Arrastar um item do inventário para a caixa para enviá-lo com o aviso. É preciso ter autorização de cópia e transferência do item para anexá-lo ao aviso."/> diff --git a/indra/newview/skins/default/xui/pt/panel_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml index 588b8deaa3..94a885960a 100644 --- a/indra/newview/skins/default/xui/pt/panel_login.xml +++ b/indra/newview/skins/default/xui/pt/panel_login.xml @@ -8,18 +8,15 @@  	</panel.string>  	<layout_stack name="login_widgets">  		<layout_panel name="login"> -			<text name="first_name_text"> -				Primeiro nome: +			<text name="username_text"> +				Nome de usuário:  			</text> -			<line_editor label="Nome" name="first_name_edit" tool_tip="[SECOND_LIFE] First Name"/> -			<text name="last_name_text"> -				Sobrenome: -			</text> -			<line_editor label="Sobrenome" name="last_name_edit" tool_tip="[SECOND_LIFE] Last Name"/> +			<line_editor label="Nome de usuário" name="username_edit" tool_tip="[SECOND_LIFE] Nome de usuário"/>  			<text name="password_text">  				Senha:  			</text>  			<check_box label="Lembrar senha" name="remember_check"/> +			<button label="conectar" name="connect_btn"/>  			<text name="start_location_text">  				Começar em:  			</text> @@ -27,7 +24,6 @@  				<combo_box.item label="Última posição" name="MyLastLocation"/>  				<combo_box.item label="Meu início" name="MyHome"/>  			</combo_box> -			<button label="conectar" name="connect_btn"/>  		</layout_panel>  		<layout_panel name="links">  			<text name="create_new_account_text"> diff --git a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml index 104c3bface..dbf8e4fa52 100644 --- a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml @@ -9,62 +9,20 @@  	<text name="ItemcountText">  		Itens:  	</text> -	<menu_bar name="Inventory Menu"> -		<menu label="Arquivo" name="File"> -			<menu_item_call label="Abrir" name="Open"/> -			<menu label="Upload" name="upload"> -				<menu_item_call label="Imagem (L$[COST])..." name="Upload Image"/> -				<menu_item_call label="Som (L$[COST])..." name="Upload Sound"/> -				<menu_item_call label="Animação (L$[COST])..." name="Upload Animation"/> -				<menu_item_call label="Volume (L$[COST] per file)..." name="Bulk Upload"/> -			</menu> -			<menu_item_call label="Nova janela" name="New Window"/> -			<menu_item_call label="Mostrar filtros" name="Show Filters"/> -			<menu_item_call label="Restabelecer filtros" name="Reset Current"/> -			<menu_item_call label="Fechar todas as pastas" name="Close All Folders"/> -			<menu_item_call label="Esvaziar lixeira" name="Empty Trash"/> -			<menu_item_call label="Esvaziar achados e perdidos" name="Empty Lost And Found"/> -		</menu> -		<menu label="Crie" name="Create"> -			<menu_item_call label="Nova pasta" name="New Folder"/> -			<menu_item_call label="Novo script" name="New Script"/> -			<menu_item_call label="Nova anotação" name="New Note"/> -			<menu_item_call label="Novo gesto" name="New Gesture"/> -			<menu label="Novas roupas" name="New Clothes"> -				<menu_item_call label="Nova camisa" name="New Shirt"/> -				<menu_item_call label="Novas calças" name="New Pants"/> -				<menu_item_call label="Novos sapatos" name="New Shoes"/> -				<menu_item_call label="Novas meias" name="New Socks"/> -				<menu_item_call label="Nova blusa" name="New Jacket"/> -				<menu_item_call label="Nova saia" name="New Skirt"/> -				<menu_item_call label="Novas luvas" name="New Gloves"/> -				<menu_item_call label="Nova camiseta" name="New Undershirt"/> -				<menu_item_call label="Novas roupa de baixo" name="New Underpants"/> -				<menu_item_call label="Novo alpha" name="New Alpha"/> -				<menu_item_call label="Nova tatuagem" name="New Tattoo"/> -			</menu> -			<menu label="Nova parte do corpo" name="New Body Parts"> -				<menu_item_call label="Nova forma" name="New Shape"/> -				<menu_item_call label="Nova pele" name="New Skin"/> -				<menu_item_call label="Novo cabelo" name="New Hair"/> -				<menu_item_call label="Novos olhos" name="New Eyes"/> -			</menu> -		</menu> -		<menu label="Classificar" name="Sort"> -			<menu_item_check label="Por nome" name="By Name"/> -			<menu_item_check label="Por data" name="By Date"/> -			<menu_item_check label="Pastas sempre por nome" name="Folders Always By Name"/> -			<menu_item_check label="Pastas do sistema no topo" name="System Folders To Top"/> -		</menu> -	</menu_bar>  	<filter_editor label="Filtro" name="inventory search editor"/>  	<tab_container name="inventory filter tabs">  		<inventory_panel label="Todos os itens" name="All Items"/> -		<inventory_panel label="Itens recentes" name="Recent Items"/> +		<recent_inventory_panel label="Itens recentes" name="Recent Items"/>  	</tab_container> -	<panel name="bottom_panel"> -		<button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/> -		<button name="add_btn" tool_tip="Adicionar novo item"/> -		<dnd_button name="trash_btn" tool_tip="Remover item selecionado"/> -	</panel> +	<layout_stack name="bottom_panel"> +		<layout_panel name="options_gear_btn_panel"> +			<button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/> +		</layout_panel> +		<layout_panel name="add_btn_panel"> +			<button name="add_btn" tool_tip="Adicionar novo item"/> +		</layout_panel> +		<layout_panel name="trash_btn_panel"> +			<dnd_button name="trash_btn" tool_tip="Remover item selecionado"/> +		</layout_panel> +	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml b/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml index 3dc8b4cc75..61e470586e 100644 --- a/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml @@ -2,6 +2,8 @@  <!-- Side tray Outfit Edit panel -->  <panel label="Editar look" name="outfit_edit">  	<string name="No Outfit" value="Nenhum"/> +	<string name="unsaved_changes" value="Mudanças não salvas"/> +	<string name="now_editing" value="Editando..."/>  	<panel.string name="not_available">  		(N\A)  	</panel.string> @@ -21,18 +23,13 @@  	</panel>  	<layout_stack name="im_panels">  		<layout_panel label="Painel de controle de MIs" name="outfit_wearables_panel"> -			<scroll_list name="look_items_list"> -				<scroll_list.columns label="Ver item" name="look_item"/> -				<scroll_list.columns label="Ordenar itens" name="look_item_sort"/> -			</scroll_list>  			<panel label="bottom_panel" name="edit_panel"/>  		</layout_panel>  		<layout_panel name="add_wearables_panel"> -			<filter_editor label="Filtro" name="look_item_filter"/> +			<text name="add_to_outfit_label" value="Adicionar ao look:"/>  			<layout_stack name="filter_panels"> -				<layout_panel label="Painel de controle de MIs" name="filter_button_panel"> -					<text name="add_to_outfit_label" value="Adicionar ao look:"/> -					<button label="O" name="filter_button"/> +				<layout_panel label="Painel de controle de MIs" name="filter_panel"> +					<filter_editor label="Filtro" name="look_item_filter"/>  				</layout_panel>  			</layout_stack>  			<panel label="add_wearables_button_bar" name="add_wearables_button_bar"> diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml index 17f5b6cbac..efeea89fa9 100644 --- a/indra/newview/skins/default/xui/pt/panel_people.xml +++ b/indra/newview/skins/default/xui/pt/panel_people.xml @@ -2,9 +2,9 @@  <!-- Side tray panel -->  <panel label="Pessoas" name="people_panel">  	<string name="no_recent_people" value="Ninguém, recentemente. Em busca de alguém para conversar? Use a [secondlife:///app/search/people Busca] ou o [secondlife:///app/worldmap Mapa-Múndi]."/> -	<string name="no_filtered_recent_people" value="Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]."/> +	<string name="no_filtered_recent_people" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]."/>  	<string name="no_one_near" value="Ninguém por perto Em busca de alguém para conversar? Use a [secondlife:///app/search/people Busca] ou o [secondlife:///app/worldmap Mapa-Múndi]."/> -	<string name="no_one_filtered_near" value="Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]."/> +	<string name="no_one_filtered_near" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]."/>  	<string name="no_friends_online" value="Nenhum amigo online"/>  	<string name="no_friends" value="Nenhum amigo"/>  	<string name="no_friends_msg"> @@ -12,11 +12,11 @@  Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-Múndi].  	</string>  	<string name="no_filtered_friends_msg"> -		Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]. +		Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search].  	</string>  	<string name="people_filter_label" value="Filtro de pessoas"/>  	<string name="groups_filter_label" value="Filtro de grupos"/> -	<string name="no_filtered_groups_msg" value="Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]."/> +	<string name="no_filtered_groups_msg" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search]."/>  	<string name="no_groups_msg" value="À procura de grupos interessantes? Tente fazer uma [secondlife:///app/search/groups Busca]."/>  	<filter_editor label="Filtro" name="filter_input"/>  	<tab_container name="tabs"> @@ -55,8 +55,8 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-  		<button label="Perfil" name="view_profile_btn" tool_tip="Exibir fotografia, grupos e outras informações dos residentes" width="50"/>  		<button label="MI" name="im_btn" tool_tip="Iniciar MI" width="24"/>  		<button label="Chamada" name="call_btn" tool_tip="Ligar para este residente" width="61"/> -		<button label="Compartilhar" name="share_btn" width="82"/> -		<button label="Teletransporte" name="teleport_btn" tool_tip="Oferecer teletransporte"  width="86"/> +		<button label="Compartilhar" name="share_btn" tool_tip="Compartilhar item de inventário" width="82"/> +		<button label="Teletransporte" name="teleport_btn" tool_tip="Oferecer teletransporte" width="86"/>  		<button label="Perfil do grupo" name="group_info_btn" tool_tip="Exibir informação de grupo"/>  		<button label="Bate-papo de grupo" name="chat_btn" tool_tip="Iniciar bate-papo"/>  		<button label="Ligar para o grupo" name="group_call_btn" tool_tip="Ligar para este grupo"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml index 6f2cae0476..885aafc350 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml @@ -13,6 +13,7 @@  	</text>  	<check_box label="Construção/Edição" name="edit_camera_movement" tool_tip="Use o posicionamento automático da câmera quando entrar e sair do modo de edição"/>  	<check_box label="Aparência" name="appearance_camera_movement" tool_tip="Use o posicionamento automático da câmera quando em modo de edição"/> +	<check_box initial_value="1" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar posicionamento automático da câmera na barra lateral"/>  	<check_box label="Mostre-me em visão de mouse" name="first_person_avatar_visible"/>  	<check_box label="Teclas de seta sempre me movem" name="arrow_keys_move_avatar_check"/>  	<check_box label="Dê dois toques e pressione para correr" name="tap_tap_hold_to_run"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml index e566fde27c..02b0ef35fe 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml @@ -45,6 +45,7 @@  	</text>  	<check_box initial_value="true" label="Executar animação digitada quando estiver conversando" name="play_typing_animation"/>  	<check_box label="Enviar MIs por email se estiver desconectado" name="send_im_to_email"/> +	<check_box label="Ativar MIs e bate-papos de texto simples" name="plain_text_chat_history"/>  	<text name="show_ims_in_label">  		Mostrar MIs em:  	</text> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index eb38323940..ccf213099e 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -1,8 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel label="Gráficos" name="Display panel"> -	<text name="UI Size:"> -		Interface: -	</text>  	<text name="QualitySpeed">  		Qualidade e velocidade:  	</text> @@ -53,6 +50,10 @@ rápido  			m  		</text>  		<slider label="Contador máx. de partículas:" name="MaxParticleCount"/> +		<slider label="Distância máx. desenho avatar:" name="MaxAvatarDrawDistance"/> +		<text name="DrawDistanceMeterText3"> +			m +		</text>  		<slider label="Qualidade de Pós-processamento:" name="RenderPostProcess"/>  		<text name="MeshDetailText">  			Detalhes de Malha: diff --git a/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml b/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml index b8bbb4051a..f075f45b8f 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml @@ -1,9 +1,13 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel label="Looks" name="appearance panel">  	<string name="No Outfit" value="Nenhum"/> +	<string name="Unsaved Changes" value="Mudanças não salvas"/> +	<string name="Now Wearing" value="Look atual..."/>  	<panel name="panel_currentlook"> -		<text name="currentlook_title"> -			(não salvo) +		<button label="E" name="editappearance_btn"/> +		<button label="O" name="openoutfit_btn"/> +		<text name="currentlook_status"> +			(Status)  		</text>  	</panel>  	<filter_editor label="Filtrar looks" name="Filter"/> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml index f634236cd2..31c96cad4c 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml @@ -4,6 +4,7 @@  		<panel name="button_panel">  			<button label="Perfil" name="info_btn"/>  			<button label="Compartilhar" name="share_btn"/> +			<button label="Comprar" name="shop_btn"/>  			<button label="Vestir" name="wear_btn"/>  			<button label="Tocar" name="play_btn"/>  			<button label="Teletransportar" name="teleport_btn"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 51b6581d42..f865124009 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -88,6 +88,24 @@  	<string name="LoginDownloadingClothing">  		Baixando roupas...  	</string> +	<string name="InvalidCertificate"> +		O servidor respondeu com um certificado inválido ou corrompido. Por favor contate o administrador do Grid. +	</string> +	<string name="CertInvalidHostname"> +		Um hostname inválido foi usado para acessar o servidor. Verifique o SLURL ou hostname do Grid. +	</string> +	<string name="CertExpired"> +		O certificado dado pelo Grid parece estar vencido.  Verifique o relógio do sistema ou contate o administrador do Grid. +	</string> +	<string name="CertKeyUsage"> +		O certificado dado pelo servidor não pôde ser usado para SSL.  Por favor contate o administrador do Grid. +	</string> +	<string name="CertBasicConstraints"> +		A cadeia de certificados do servidor tinha certificados demais.  Por favor contate o administrador do Grid. +	</string> +	<string name="CertInvalidSignature"> +		A assinatura do certificado dado pelo servidor do Grid não pôde ser verificada.  Por favor contate o administrador do Grid. +	</string>  	<string name="LoginFailedNoNetwork">  		Erro de rede: Não foi possível estabelecer a conexão, verifique sua conexão de rede.  	</string> @@ -819,6 +837,42 @@  	<string name="invalid">  		Inválido  	</string> +	<string name="shirt_not_worn"> +		Camisa não vestida +	</string> +	<string name="pants_not_worn"> +		Calças não vestidas +	</string> +	<string name="shoes_not_worn"> +		Sapatos não calçados +	</string> +	<string name="socks_not_worn"> +		Meias não calçadas +	</string> +	<string name="jacket_not_worn"> +		Jaqueta não vestida +	</string> +	<string name="gloves_not_worn"> +		Luvas não calçadas +	</string> +	<string name="undershirt_not_worn"> +		Camiseta não vestida +	</string> +	<string name="underpants_not_worn"> +		Roupa de baixo não vestida +	</string> +	<string name="skirt_not_worn"> +		Saia não vestida +	</string> +	<string name="alpha_not_worn"> +		Alpha não vestido +	</string> +	<string name="tattoo_not_worn"> +		Tatuagem não usada +	</string> +	<string name="invalid_not_worn"> +		inválido +	</string>  	<string name="NewWearable">  		Novo [WEARABLE_ITEM]  	</string> @@ -889,7 +943,10 @@  		Pressione ESC para retornar para visão do mundo  	</string>  	<string name="InventoryNoMatchingItems"> -		Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]. +		Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]. +	</string> +	<string name="PlacesNoMatchingItems"> +		Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search].  	</string>  	<string name="FavoritesNoMatchingItems">  		Arraste um marco para adicioná-lo aos seus favoritos. @@ -919,6 +976,7 @@  	<string name="Wave" value="Acenar"/>  	<string name="HelloAvatar" value="Olá, avatar!"/>  	<string name="ViewAllGestures" value="Ver todos>>"/> +	<string name="GetMoreGestures" value="Mais >>"/>  	<string name="Animations" value="Animações,"/>  	<string name="Calling Cards" value="Cartões de visitas,"/>  	<string name="Clothing" value="Vestuário,"/> @@ -1542,6 +1600,9 @@  	<string name="MuteGroup">  		(grupo)  	</string> +	<string name="MuteExternal"> +		(Externo) +	</string>  	<string name="RegionNoCovenant">  		Não foi definido um contrato para essa região.  	</string> @@ -3299,11 +3360,14 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	<string name="answered_call">  		Ligação atendida  	</string> -	<string name="started_call"> -		Iniciou uma ligação de voz +	<string name="you_started_call"> +		Você iniciou uma ligação de voz +	</string> +	<string name="you_joined_call"> +		Você entrou na ligação  	</string> -	<string name="joined_call"> -		Entrou na ligação +	<string name="name_started_call"> +		[NAME] iniciou uma ligação de voz  	</string>  	<string name="ringing-im">  		Entrando em ligação de voz... @@ -3502,6 +3566,90 @@ Denunciar abuso  	<string name="Contents">  		Conteúdo  	</string> +	<string name="Gesture"> +		Gesto +	</string> +	<string name="Male Gestures"> +		Gestos masculinos +	</string> +	<string name="Female Gestures"> +		Gestos femininos +	</string> +	<string name="Other Gestures"> +		Outros gestos +	</string> +	<string name="Speech Gestures"> +		Gestos da fala +	</string> +	<string name="Common Gestures"> +		Gestos comuns +	</string> +	<string name="Male - Excuse me"> +		Perdão - masculino +	</string> +	<string name="Male - Get lost"> +		Deixe-me em paz - masculino +	</string> +	<string name="Male - Blow kiss"> +		Mandar beijo - masculino +	</string> +	<string name="Male - Boo"> +		Vaia - masculino +	</string> +	<string name="Male - Bored"> +		Maçante - masculino +	</string> +	<string name="Male - Hey"> +		Ôpa! - masculino +	</string> +	<string name="Male - Laugh"> +		Risada - masculino +	</string> +	<string name="Male - Repulsed"> +		Quero distância! - masculino +	</string> +	<string name="Male - Shrug"> +		Encolher de ombros - masculino +	</string> +	<string name="Male - Stick tougue out"> +		Mostrar a língua - masculino +	</string> +	<string name="Male - Wow"> +		Wow - masculino +	</string> +	<string name="FeMale - Excuse me"> +		Perdão - masc/fem +	</string> +	<string name="FeMale - Get lost"> +		Deixe-me em paz - feminino +	</string> +	<string name="FeMale - Blow kiss"> +		Mandar beijo - masc/fem +	</string> +	<string name="FeMale - Boo"> +		Vaia - masc/fem +	</string> +	<string name="Female - Bored"> +		Maçante - feminino +	</string> +	<string name="Female - Hey"> +		Ôpa - feminino +	</string> +	<string name="Female - Laugh"> +		Risada - feminina +	</string> +	<string name="Female - Repulsed"> +		Quero distância! - feminino +	</string> +	<string name="Female - Shrug"> +		Encolher ombros - feminino +	</string> +	<string name="Female - Stick tougue out"> +		Mostrar a língua - feminino +	</string> +	<string name="Female - Wow"> +		Wow - feminino +	</string>  	<string name="AvatarBirthDateFormat">  		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]  	</string> diff --git a/install.xml b/install.xml index 8387372400..80641d29e6 100644 --- a/install.xml +++ b/install.xml @@ -962,9 +962,9 @@ anguage Infrstructure (CLI) international standard</string>            <key>windows</key>            <map>              <key>md5sum</key> -            <string>1d9697fed57084eea7b3dc250e9c66f7</string> +            <string>d682ed6232193b4eab3170657a54ebf9</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-windows-qt4.6-20100525.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-windows-qt4.6-20100519.tar.bz2</uri>            </map>          </map>        </map>  | 
