diff options
Diffstat (limited to 'indra')
298 files changed, 5747 insertions, 1707 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 2a70263446..c356feb13a 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -192,13 +192,13 @@ endif (DARWIN)  if (LINUX OR DARWIN) -  set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor -Woverloaded-virtual") +  set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs")    if (NOT GCC_DISABLE_FATAL_WARNINGS)      set(GCC_WARNINGS "${GCC_WARNINGS} -Werror")    endif (NOT GCC_DISABLE_FATAL_WARNINGS) -  set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder") +  set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor -Woverloaded-virtual")    set(CMAKE_C_FLAGS "${GCC_WARNINGS} ${CMAKE_C_FLAGS}")    set(CMAKE_CXX_FLAGS "${GCC_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}") diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake new file mode 100644 index 0000000000..ca5a8034ba --- /dev/null +++ b/indra/cmake/GoogleMock.cmake @@ -0,0 +1,27 @@ +# -*- cmake -*- +include(Prebuilt) +include(Linking) + +use_prebuilt_binary(googlemock) + +set(GOOGLEMOCK_INCLUDE_DIRS  +    ${LIBS_PREBUILT_DIR}/include) + +if (LINUX) +    set(GOOGLEMOCK_LIBRARIES  +        gmock   +        gtest) +elseif(WINDOWS) +    set(GOOGLEMOCK_LIBRARIES  +        gmock) +    set(GOOGLEMOCK_INCLUDE_DIRS  +        ${LIBS_PREBUILT_DIR}/include +        ${LIBS_PREBUILT_DIR}/include/gmock +        ${LIBS_PREBUILT_DIR}/include/gmock/boost/tr1/tr1) +elseif(DARWIN) +    set(GOOGLEMOCK_LIBRARIES +        gmock +        gtest) +endif(LINUX) + + diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 7d6ef9ab1a..373ad4d4e9 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -13,6 +13,8 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)    #    # WARNING: do NOT modify this code without working with poppy or daveh -    # there is another branch that will conflict heavily with any changes here. +INCLUDE(GoogleMock) +    IF(LL_TEST_VERBOSE)      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") @@ -32,8 +34,10 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)      ${LLMATH_INCLUDE_DIRS}      ${LLCOMMON_INCLUDE_DIRS}      ${LIBS_OPEN_DIR}/test +    ${GOOGLEMOCK_INCLUDE_DIRS}      )    SET(alltest_LIBRARIES +    ${GOOGLEMOCK_LIBRARIES}      ${PTHREAD_LIBRARY}      ${WINDOWS_LIBRARIES}      ) @@ -42,6 +46,11 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)      ${CMAKE_SOURCE_DIR}/test/test.h      ) +  # Use the default flags +  if (LINUX) +    SET(CMAKE_EXE_LINKER_FLAGS "") +  endif (LINUX) +    # start the source test executable definitions    SET(${project}_TEST_OUTPUT "")    FOREACH (source ${sources}) @@ -84,9 +93,9 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)        MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")      ENDIF(LL_TEST_VERBOSE) +      # Setup target      ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) -      #      # Per-codefile additional / external project dep and lib dep property extraction      # diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py index 1190d88663..4527b115f9 100644 --- a/indra/lib/python/indra/base/llsd.py +++ b/indra/lib/python/indra/base/llsd.py @@ -238,7 +238,7 @@ class LLSDXMLFormatter(object):      def MAP(self, v):          return self.elt(              'map', -            ''.join(["%s%s" % (self.elt('key', key), self.generate(value)) +            ''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value))               for key, value in v.items()]))      typeof = type diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py index aceea29cd2..1cdd8e915b 100644 --- a/indra/lib/python/indra/base/lluuid.py +++ b/indra/lib/python/indra/base/lluuid.py @@ -26,8 +26,14 @@ THE SOFTWARE.  $/LicenseInfo$  """ -import md5, random, socket, string, time, re +import random, socket, string, time, re  import uuid +try: +    # Python 2.6 +    from hashlib import md5 +except ImportError: +    # Python 2.5 and earlier +    from md5 import new as md5  def _int2binstr(i,l):      s='' @@ -196,7 +202,7 @@ class UUID(object):          from c++ implementation for portability reasons.          Returns self.          """ -        m = md5.new() +        m = md5()          m.update(uuid.uuid1().bytes)          self._bits = m.digest()          return self diff --git a/indra/lib/python/indra/util/llsubprocess.py b/indra/lib/python/indra/util/llsubprocess.py index c4c40739ec..7e0e115d14 100644 --- a/indra/lib/python/indra/util/llsubprocess.py +++ b/indra/lib/python/indra/util/llsubprocess.py @@ -90,6 +90,17 @@ all the output, and get the result.                      child.tochild.close()          result = child.poll()          if result != -1: +            # At this point, the child process has exited and result +            # is the return value from the process. Between the time +            # we called select() and poll() the process may have +            # exited so read all the data left on the child process +            # stdout and stderr. +            last = child.fromchild.read() +            if last: +                out.append(last) +            last = child.childerr.read() +            if last: +                err.append(last)              child.tochild.close()              child.fromchild.close()              child.childerr.close() diff --git a/indra/lib/python/indra/util/llversion.py b/indra/lib/python/indra/util/llversion.py index 770b861ddc..2718a85f41 100644 --- a/indra/lib/python/indra/util/llversion.py +++ b/indra/lib/python/indra/util/llversion.py @@ -1,7 +1,7 @@  """@file llversion.py  @brief Utility for parsing llcommon/llversion${server}.h         for the version string and channel string -       Utility that parses svn info for branch and revision +       Utility that parses hg or svn info for branch and revision  $LicenseInfo:firstyear=2006&license=mit$ @@ -79,8 +79,8 @@ def get_svn_status_matching(regular_expression):      status, output = commands.getstatusoutput('svn info %s' % get_src_root())      m = regular_expression.search(output)      if not m: -        print "Failed to parse svn info output, resultfollows:" -        print output +        print >> sys.stderr, "Failed to parse svn info output, result follows:" +        print >> sys.stderr, output          raise Exception, "No matching svn status in "+src_root      return m.group(1) @@ -92,4 +92,35 @@ def get_svn_revision():      last_rev_re = re.compile('Last Changed Rev: (\d+)')      return get_svn_status_matching(last_rev_re) - +def get_hg_repo(): +    status, output = commands.getstatusoutput('hg showconfig paths.default') +    if status: +        print >> sys.stderr, output +        sys.exit(1) +    if not output: +        print >> sys.stderr, 'ERROR: cannot find repo we cloned from' +        sys.exit(1) +    return output + +def get_hg_changeset(): +    # The right thing to do: +    # status, output = commands.getstatusoutput('hg id -i') +    # if status: +    #     print >> sys.stderr, output +    #    sys.exit(1) + +    # The temporary hack: +    status, output = commands.getstatusoutput('hg parents --template "{rev}"') +    if status: +        print >> sys.stderr, output +        sys.exit(1) +    lines = output.splitlines() +    if len(lines) > 1: +        print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines) +    return lines[0] + +def using_svn(): +    return os.path.isdir(os.path.join(get_src_root(), '.svn')) + +def using_hg(): +    return os.path.isdir(os.path.join(get_src_root(), '.hg')) diff --git a/indra/lib/python/indra/util/named_query.py b/indra/lib/python/indra/util/named_query.py index 693b483f79..5c19368240 100644 --- a/indra/lib/python/indra/util/named_query.py +++ b/indra/lib/python/indra/util/named_query.py @@ -48,8 +48,8 @@ from indra.base import llsd  from indra.base import config  DEBUG = False -NQ_FILE_SUFFIX = None -NQ_FILE_SUFFIX_LEN = None +NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq') +NQ_FILE_SUFFIX_LEN  = len(NQ_FILE_SUFFIX)  _g_named_manager = None diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 1d42298f4d..1ae0ddeea0 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -190,7 +190,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask)  	if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD)  	{  		mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation(); -		mLastGoodPelvisRotation.normQuat(); +		mLastGoodPelvisRotation.normalize();  		mTrackAnkles = TRUE;  	}  	else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index bc4e44d7e6..138dc85459 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -240,7 +240,7 @@ SET(llcommon_TEST_SOURCE_FILES  LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}")  #set(TEST_DEBUG on) -set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) +set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES} ${GOOGLEMOCK_LIBRARIES})  # Have to treat lllazy test as an integration test until this issue is resolved:  # https://jira.lindenlab.com/jira/browse/DEV-29456  LL_ADD_INTEGRATION_TEST(lllazy lllazy.cpp "${test_libs}") diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 5d7672b378..78aa6f4f37 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -289,6 +289,7 @@ bool LLAssetType::lookupIsEnsembleCategoryType(EType asset_type)  			asset_type <= AT_FOLDER_ENSEMBLE_END);  } +  // static. Generate a good default description  void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type,  										 std::string& description) diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 5e51188541..880b7a19b5 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -150,6 +150,7 @@ public:  		AT_COUNT = 49, +  			// +*********************************************************+  			// |  TO ADD AN ELEMENT TO THIS ENUM:                        |  			// +*********************************************************+ diff --git a/indra/llcommon/llcursortypes.cpp b/indra/llcommon/llcursortypes.cpp index 7444115aa1..23ede97af3 100644 --- a/indra/llcommon/llcursortypes.cpp +++ b/indra/llcommon/llcursortypes.cpp @@ -30,6 +30,8 @@   * $/LicenseInfo$   */ +#include "linden_common.h" +  #include "llcursortypes.h"  ECursorType getCursorFromString(const std::string& cursor_string) @@ -66,10 +68,6 @@ ECursorType getCursorFromString(const std::string& cursor_string)  		cursor_string_table["UI_CURSOR_TOOLPAN"] = UI_CURSOR_TOOLPAN;  		cursor_string_table["UI_CURSOR_TOOLZOOMIN"] = UI_CURSOR_TOOLZOOMIN;  		cursor_string_table["UI_CURSOR_TOOLPICKOBJECT3"] = UI_CURSOR_TOOLPICKOBJECT3; -		cursor_string_table["UI_CURSOR_TOOLSIT"] = UI_CURSOR_TOOLSIT; -		cursor_string_table["UI_CURSOR_TOOLBUY"] = UI_CURSOR_TOOLBUY; -		cursor_string_table["UI_CURSOR_TOOLPAY"] = UI_CURSOR_TOOLPAY; -		cursor_string_table["UI_CURSOR_TOOLOPEN"] = UI_CURSOR_TOOLOPEN;  		cursor_string_table["UI_CURSOR_TOOLPLAY"] = UI_CURSOR_TOOLPLAY;  		cursor_string_table["UI_CURSOR_TOOLPAUSE"] = UI_CURSOR_TOOLPAUSE;  		cursor_string_table["UI_CURSOR_TOOLMEDIAOPEN"] = UI_CURSOR_TOOLMEDIAOPEN; diff --git a/indra/llcommon/llcursortypes.h b/indra/llcommon/llcursortypes.h index bea70351b7..35dbeaf16e 100644 --- a/indra/llcommon/llcursortypes.h +++ b/indra/llcommon/llcursortypes.h @@ -33,8 +33,6 @@  #ifndef LL_LLCURSORTYPES_H  #define LL_LLCURSORTYPES_H -#include "linden_common.h" -  // If you add types here, add them in LLCursor::getCursorFromString  enum ECursorType {  	UI_CURSOR_ARROW, @@ -66,10 +64,6 @@ enum ECursorType {  	UI_CURSOR_TOOLPAN,  	UI_CURSOR_TOOLZOOMIN,  	UI_CURSOR_TOOLPICKOBJECT3, -	UI_CURSOR_TOOLSIT, -	UI_CURSOR_TOOLBUY, -	UI_CURSOR_TOOLPAY, -	UI_CURSOR_TOOLOPEN,  	UI_CURSOR_TOOLPLAY,  	UI_CURSOR_TOOLPAUSE,  	UI_CURSOR_TOOLMEDIAOPEN, diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 0d89353dee..c2f23f6ff6 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -114,8 +114,9 @@ public:  		// recursive call to gather total time from children  		static void accumulateTimings(); -		// called once per frame by LLFastTimer -		static void processFrame(); +		// updates cumulative times and hierarchy,  +		// can be called multiple times in a frame, at any point +		static void processTimes();  		static void buildHierarchy();  		static void resetFrame(); @@ -178,8 +179,9 @@ public:  	{  #if FAST_TIMER_ON  		NamedTimer::FrameState* frame_state = mFrameState; -		frame_state->mLastStartTime = get_cpu_clock_count(); -		mStartSelfTime = frame_state->mLastStartTime; +		U64 cur_time = get_cpu_clock_count(); +		frame_state->mLastStartTime = cur_time; +		mStartSelfTime = cur_time;  		frame_state->mActiveCount++;  		frame_state->mCalls++; @@ -215,6 +217,10 @@ public:  	// call this once a frame to reset timers  	static void nextFrame(); +	// dumps current cumulative frame stats to log +	// call nextFrame() to reset timers +	static void dumpCurTimes();  +  	// call this to reset timer hierarchy, averages, etc.  	static void reset(); diff --git a/indra/llcommon/llkeythrottle.h b/indra/llcommon/llkeythrottle.h index 873f50a65e..7544ab1d11 100644 --- a/indra/llcommon/llkeythrottle.h +++ b/indra/llcommon/llkeythrottle.h @@ -118,6 +118,63 @@ public:  		THROTTLE_BLOCKED,		// rate exceed, block key  	}; +	F64 getActionCount(const T& id) +	{ +		U64 now = 0; +		if ( mIsRealtime ) +		{ +			now = LLKeyThrottleImpl<T>::getTime(); +		} +		else +		{ +			now = LLKeyThrottleImpl<T>::getFrame(); +		} + +		if (now >= (m.startTime + m.intervalLength)) +		{ +			if (now < (m.startTime + 2 * m.intervalLength)) +			{ +				// prune old data +				delete m.prevMap; +				m.prevMap = m.currMap; +				m.currMap = new typename LLKeyThrottleImpl<T>::EntryMap; + +				m.startTime += m.intervalLength; +			} +			else +			{ +				// lots of time has passed, all data is stale +				delete m.prevMap; +				delete m.currMap; +				m.prevMap = new typename LLKeyThrottleImpl<T>::EntryMap; +				m.currMap = new typename LLKeyThrottleImpl<T>::EntryMap; + +				m.startTime = now; +			} +		} + +		U32 prevCount = 0; + +		typename LLKeyThrottleImpl<T>::EntryMap::const_iterator prev = m.prevMap->find(id); +		if (prev != m.prevMap->end()) +		{ +			prevCount = prev->second.count; +		} + +		typename LLKeyThrottleImpl<T>::Entry& curr = (*m.currMap)[id]; + +		// curr.count is the number of keys in +		// this current 'time slice' from the beginning of it until now +		// prevCount is the number of keys in the previous +		// time slice scaled to be one full time slice back from the current  +		// (now) time. + +		// compute current, windowed rate +		F64 timeInCurrent = ((F64)(now - m.startTime) / m.intervalLength); +		F64 averageCount = curr.count + prevCount * (1.0 - timeInCurrent); +		return averageCount; +	} +  	// call each time the key wants use  	State noteAction(const T& id, S32 weight = 1)  	{ diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index c12ca350de..7e1c2e35e0 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -37,6 +37,7 @@  #include <deque>  #include "apr_base64.h" +#include <boost/regex.hpp>  extern "C"  { @@ -777,10 +778,17 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)  		case ELEMENT_BINARY:  		{ -			S32 len = apr_base64_decode_len(mCurrentContent.c_str()); +			// Regex is expensive, but only fix for whitespace in base64, +			// created by python and other non-linden systems - DEV-39358 +			// Fortunately we have very little binary passing now, +			// so performance impact shold be negligible. + poppy 2009-09-04 +			boost::regex r; +			r.assign("\\s"); +			std::string stripped = boost::regex_replace(mCurrentContent, r, ""); +			S32 len = apr_base64_decode_len(stripped.c_str());  			std::vector<U8> data;  			data.resize(len); -			len = apr_base64_decode_binary(&data[0], mCurrentContent.c_str()); +			len = apr_base64_decode_binary(&data[0], stripped.c_str());  			data.resize(len);  			value = data;  			break; diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 90dae11793..0bd2609f4a 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -43,7 +43,7 @@  // statics -BOOL            LLPerfBlock::sStatsEnabled = FALSE;    // Flag for detailed information +S32	            LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS;       // Control what is being recorded  LLPerfBlock::stat_map_t    LLPerfBlock::sStatMap;    // Map full path string to LLStatTime objects, tracks all active objects  std::string        LLPerfBlock::sCurrentStatPath = "";    // Something like "/total_time/physics/physics step"  LLStat::stat_map_t LLStat::sStatList; @@ -130,6 +130,7 @@ bool LLStatsConfigFile::loadFile()      F32 duration = 0.f;      F32 interval = 0.f; +	S32 flags = LLPerfBlock::LLSTATS_BASIC_STATS;      const char * w = "duration";      if (stats_config.has(w)) @@ -141,8 +142,18 @@ bool LLStatsConfigFile::loadFile()      {          interval = (F32)stats_config[w].asReal();      }  +    w = "flags"; +    if (stats_config.has(w)) +    { +		flags = (S32)stats_config[w].asInteger(); +		if (flags == LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS && +			duration > 0) +		{   // No flags passed in, but have a duration, so reset to basic stats +			flags = LLPerfBlock::LLSTATS_BASIC_STATS; +		} +    }  -    mStatsp->setReportPerformanceDuration( duration ); +    mStatsp->setReportPerformanceDuration( duration, flags );      mStatsp->setReportPerformanceInterval( interval );      if ( duration > 0 ) @@ -254,13 +265,14 @@ void LLPerfStats::dumpIntervalPerformanceStats()      }  } -// Set length of performance stat recording -void    LLPerfStats::setReportPerformanceDuration( F32 seconds ) +// Set length of performance stat recording.   +// If turning stats on, caller must provide flags +void    LLPerfStats::setReportPerformanceDuration( F32 seconds, S32 flags /* = LLSTATS_NO_OPTIONAL_STATS */ )  {   	if ( seconds <= 0.f )  	{  		mReportPerformanceStatEnd = 0.0; -		LLPerfBlock::setStatsEnabled( FALSE ); +		LLPerfBlock::setStatsFlags(LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS);		// Make sure all recording is off  		mFrameStatsFile.close();  		LLPerfBlock::clearDynamicStats();  	} @@ -269,8 +281,8 @@ void    LLPerfStats::setReportPerformanceDuration( F32 seconds )  		mReportPerformanceStatEnd = LLFrameTimer::getElapsedSeconds() + ((F64) seconds);  		// Clear failure flag to try and create the log file once  		mFrameStatsFileFailure = FALSE; -		LLPerfBlock::setStatsEnabled( TRUE );  		mSkipFirstFrameStats = TRUE;		// Skip the first report (at the end of this frame) +		LLPerfBlock::setStatsFlags(flags);  	}  } @@ -612,11 +624,26 @@ LLPerfBlock::LLPerfBlock(LLStatTime* stat ) : mPredefinedStat(stat), mDynamicSta      }  } -// Use this constructor for dynamically created LLStatTime objects (not pre-defined) with a multi-part key. -// These are also turned on or off via the switch passed in -LLPerfBlock::LLPerfBlock( const char* key1, const char* key2 ) : mPredefinedStat(NULL), mDynamicStat(NULL) +// Use this constructor for normal, optional LLPerfBlock time slices +LLPerfBlock::LLPerfBlock( const char* key ) : mPredefinedStat(NULL), mDynamicStat(NULL)  { -    if (!sStatsEnabled) return; +    if ((sStatsFlags & LLSTATS_BASIC_STATS) == 0) +	{	// These are off unless the base set is enabled +		return; +	} + +	initDynamicStat(key); +} + +	 +// Use this constructor for dynamically created LLPerfBlock time slices +// that are only enabled by specific control flags +LLPerfBlock::LLPerfBlock( const char* key1, const char* key2, S32 flags ) : mPredefinedStat(NULL), mDynamicStat(NULL) +{ +    if ((sStatsFlags & flags) == 0) +	{ +		return; +	}      if (NULL == key2 || strlen(key2) == 0)      { @@ -630,10 +657,12 @@ LLPerfBlock::LLPerfBlock( const char* key1, const char* key2 ) : mPredefinedStat      }  } +// Set up the result data map if dynamic stats are enabled  void LLPerfBlock::initDynamicStat(const std::string& key)  {      // Early exit if dynamic stats aren't enabled. -    if (!sStatsEnabled) return; +    if (sStatsFlags == LLSTATS_NO_OPTIONAL_STATS)  +		return;      mLastPath = sCurrentStatPath;		// Save and restore current path      sCurrentStatPath += "/" + key;		// Add key to current path diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index bad18f46a0..76aa3963f4 100644 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h @@ -192,14 +192,23 @@ public:  	// Use this constructor for pre-defined LLStatTime objects  	LLPerfBlock(LLStatTime* stat); -	// Use this constructor for dynamically created LLStatTime objects (not pre-defined) with a multi-part key -	LLPerfBlock( const char* key1, const char* key2 = NULL); +	// Use this constructor for normal, optional LLPerfBlock time slices +	LLPerfBlock( const char* key ); +	// Use this constructor for dynamically created LLPerfBlock time slices +	// that are only enabled by specific control flags +	LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS );  	~LLPerfBlock(); -	static void setStatsEnabled( BOOL enable )		{ sStatsEnabled = enable;	}; -	static S32  getStatsEnabled()					{ return sStatsEnabled;		}; +	enum +	{	// Stats bitfield flags +		LLSTATS_NO_OPTIONAL_STATS	= 0x00,		// No optional stats gathering, just pre-defined LLStatTime objects +		LLSTATS_BASIC_STATS			= 0x01,		// Gather basic optional runtime stats +		LLSTATS_SCRIPT_FUNCTIONS	= 0x02,		// Include LSL function calls +	}; +	static void setStatsFlags( S32 flags )	{ sStatsFlags = flags;	}; +	static S32  getStatsFlags()				{ return sStatsFlags;	};  	static void clearDynamicStats();		// Reset maps to clear out dynamic objects  	static void addStatsToLLSDandReset( LLSD & stats,		// Get current information and clear time bin @@ -213,7 +222,7 @@ private:  	LLStatTime * 			mPredefinedStat;		// LLStatTime object to get data  	StatEntry *				mDynamicStat;   		// StatEntryobject to get data -	static BOOL				sStatsEnabled;			// Normally FALSE +	static S32				sStatsFlags;			// Control what is being recorded      static stat_map_t		sStatMap;				// Map full path string to LLStatTime objects  	static std::string		sCurrentStatPath;		// Something like "frame/physics/physics step"  }; @@ -236,7 +245,7 @@ public:      BOOL    frameStatsIsRunning()                                { return (mReportPerformanceStatEnd > 0.);        };      F32     getReportPerformanceInterval() const                { return mReportPerformanceStatInterval;        };      void    setReportPerformanceInterval( F32 interval )        { mReportPerformanceStatInterval = interval;    }; -    void    setReportPerformanceDuration( F32 seconds ); +    void    setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS );      void    setProcessName(const std::string& process_name) { mProcessName = process_name; }      void    setProcessPID(S32 process_pid) { mProcessPID = process_pid; } diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h index 888361b0b9..5c4831cc2b 100644 --- a/indra/llcommon/llstringtable.h +++ b/indra/llcommon/llstringtable.h @@ -48,10 +48,12 @@  //# define STRING_TABLE_HASH_MAP 1  #endif -#if LL_WINDOWS -#include <hash_map> -#else -#include <ext/hash_map> +#if STRING_TABLE_HASH_MAP +# if LL_WINDOWS +#  include <hash_map> +# else +#  include <ext/hash_map> +# endif  #endif  const U32 MAX_STRINGS_LENGTH = 256; diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index 23e39ceb08..77a03879bf 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -34,9 +34,9 @@  #define LL_LLVERSIONSERVER_H  const S32 LL_VERSION_MAJOR = 1; -const S32 LL_VERSION_MINOR = 29; +const S32 LL_VERSION_MINOR = 31;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 0; +const S32 LL_VERSION_BUILD = 2639;  const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 2c3e9c7333..e69ca7eec5 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -36,7 +36,7 @@  const S32 LL_VERSION_MAJOR = 2;  const S32 LL_VERSION_MINOR = 0;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 0; +const S32 LL_VERSION_BUILD = 2639;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llcommon/metapropertyt.h b/indra/llcommon/metapropertyt.h index 79a536a224..5ad230d1d5 100644 --- a/indra/llcommon/metapropertyt.h +++ b/indra/llcommon/metapropertyt.h @@ -94,6 +94,13 @@ inline const LLReflective* LLMetaPropertyT<LLUUID>::get(const LLReflective* obje  }  template <> +inline const LLReflective* LLMetaPropertyT<bool>::get(const LLReflective* object) const +{ +	checkObjectClass(object); +	return NULL; +} + +template <>  inline LLSD LLMetaPropertyT<S32>::getLLSD(const LLReflective* object) const  {  	return *(getProperty(object)); @@ -111,6 +118,12 @@ inline LLSD LLMetaPropertyT<LLUUID>::getLLSD(const LLReflective* object) const  	return *(getProperty(object));  } +template <> +inline LLSD LLMetaPropertyT<bool>::getLLSD(const LLReflective* object) const +{ +	return *(getProperty(object)); +} +  template<class TObject, class TProperty>  class LLMetaPropertyTT : public LLMetaPropertyT<TProperty>  { diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 363486fb9c..2352c8edd7 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -178,8 +178,8 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  							mMaxBytes(0),  							mRawDiscardLevel(-1),  							mRate(0.0f), -							mReversible(FALSE) -	 +							mReversible(FALSE), +							mAreaUsedForDataSizeCalcs(0)  {  	//We assume here that if we wanted to create via  	//a dynamic library that the approriate open calls were made @@ -195,6 +195,12 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  	}  	mImpl = j2cimpl_create_func(); + +	// Clear data size table +	for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++) +	{	// Array size is MAX_DISCARD_LEVEL+1 +		mDataSizes[i] = 0; +	}  }  // virtual @@ -367,9 +373,45 @@ S32 LLImageJ2C::calcHeaderSize()  	return calcHeaderSizeJ2C();  } + +// calcDataSize() returns how many bytes to read  +// to load discard_level (including header and higher discard levels)  S32 LLImageJ2C::calcDataSize(S32 discard_level)  { -	return calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), discard_level, mRate); +	discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); + +	if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())  +		|| mDataSizes[0] == 0) +	{ +		mAreaUsedForDataSizeCalcs = getHeight() * getWidth(); +		 +		S32 level = MAX_DISCARD_LEVEL;	// Start at the highest discard +		while ( level >= 0 ) +		{ +			mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); +			level--; +		} + +		/* This is technically a more correct way to calculate the size required +		   for each discard level, since they should include the size needed for +		   lower levels.   Unfortunately, this doesn't work well and will lead to  +		   download stalls.  The true correct way is to parse the header.  This will +		   all go away with http textures at some point. + +		// Calculate the size for each discard level.   Lower levels (higher quality) +		// contain the cumulative size of higher levels		 +		S32 total_size = calcHeaderSizeJ2C(); + +		S32 level = MAX_DISCARD_LEVEL;	// Start at the highest discard +		while ( level >= 0 ) +		{	// Add in this discard level and all before it +			total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); +			mDataSizes[level] = total_size; +			level--; +		} +		*/ +	} +	return mDataSizes[discard_level];  }  S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes) diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 23f6ef5fd1..55df7f4429 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -87,6 +87,10 @@ protected:  	void updateRawDiscardLevel();  	S32 mMaxBytes; // Maximum number of bytes of data to use... +	 +	S32 mDataSizes[MAX_DISCARD_LEVEL+1];		// Size of data required to reach a given level +	U32 mAreaUsedForDataSizeCalcs;				// Height * width used to calculate mDataSizes +  	S8  mRawDiscardLevel;  	F32 mRate;  	BOOL mReversible; diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index e2a77f1d1e..5d3fbe5128 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -458,6 +458,39 @@ void LLInventoryItem::setCreationDate(time_t creation_date_utc)  	mCreationDate = creation_date_utc;  } +void LLInventoryItem::accumulatePermissionSlamBits(const LLInventoryItem& old_item) +{ +	// Remove any pre-existing II_FLAGS_PERM_OVERWRITE_MASK flags  +	// because we now detect when they should be set. +	setFlags( old_item.getFlags() | (getFlags() & ~(LLInventoryItem::II_FLAGS_PERM_OVERWRITE_MASK)) ); + +	// Enforce the PERM_OVERWRITE flags for any masks that are different +	// but only for AT_OBJECT's since that is the only asset type that can  +	// exist in-world (instead of only in-inventory or in-object-contents). +	if (LLAssetType::AT_OBJECT == getType()) +	{ +		LLPermissions old_permissions = old_item.getPermissions(); +		U32 flags_to_be_set = 0; +		if(old_permissions.getMaskNextOwner() != getPermissions().getMaskNextOwner()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_SLAM_PERM; +		} +		if(old_permissions.getMaskEveryone() != getPermissions().getMaskEveryone()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; +		} +		if(old_permissions.getMaskGroup() != getPermissions().getMaskGroup()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; +		} +		LLSaleInfo old_sale_info = old_item.getSaleInfo(); +		if(old_sale_info != getSaleInfo()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_SLAM_SALE; +		} +		setFlags(getFlags() | flags_to_be_set); +	} +}  const LLSaleInfo& LLInventoryItem::getSaleInfo() const  { diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 64af6c94f5..bd581e860f 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -93,7 +93,6 @@ public:  	virtual const LLUUID& getUUID() const;  	const LLUUID& getParentUUID() const;  	virtual const LLUUID& getLinkedUUID() const; // get the inventoryID that this item points to, else this item's inventoryID -  	virtual const std::string& getName() const;  	virtual LLAssetType::EType getType() const;  	LLAssetType::EType getActualType() const; // bypasses indirection for linked items @@ -263,6 +262,10 @@ public:  	void setInventoryType(LLInventoryType::EType inv_type);  	void setFlags(U32 flags);  	void setCreationDate(time_t creation_date_utc); + +	// Check for changes in permissions masks and sale info +	// and set the corresponding bits in mFlags +	void accumulatePermissionSlamBits(const LLInventoryItem& old_item);  	// This is currently only used in the Viewer to handle calling cards  	// where the creator is actually used to store the target. diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index aa8391230c..2a9a596912 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -136,9 +136,9 @@ class LLSD;  class LLAccessEntry  {  public: -	LLUUID		mID; -	S32			mTime; -	U32			mFlags; +	LLUUID		mID;		// Agent ID +	S32			mTime;		// Time (unix seconds) when entry expires +	U32			mFlags;		// Not used - currently should always be zero  };  typedef std::map<LLUUID,LLAccessEntry>::iterator access_map_iterator; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 0babf26457..d2e5034734 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -288,6 +288,17 @@ BOOL LLPermissions::setOwnerAndGroup(  	return allowed;  } +//Fix for DEV-33917, last owner isn't used much and has little impact on +//permissions so it's reasonably safe to do this, however, for now,  +//limiting the functionality of this routine to objects which are  +//group owned. +void LLPermissions::setLastOwner(const LLUUID& last_owner) +{ +	if (isGroupOwned()) +		mLastOwner = last_owner; +} + +   // only call this if you know what you're doing  // there are usually perm-bit consequences when the   // ownerhsip changes @@ -895,6 +906,8 @@ void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class)  {  	reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator);  	reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner); +	reflectProperty(meta_class, "mGroup", &LLPermissions::mGroup); +	reflectProperty(meta_class, "mIsGroupOwned", &LLPermissions::mIsGroupOwned);  }  // virtual diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 864088148f..d5a0881c8f 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -232,6 +232,10 @@ public:  	// ownerhsip changes  	void yesReallySetOwner(const LLUUID& owner, bool group_owned); +	// Last owner doesn't have much in the way of permissions so it's  +	//not too dangerous to do this.  +	void setLastOwner(const LLUUID& last_owner); +  	// saves last owner, sets owner to uuid null, sets group  	// owned. group_id must be the group of the object (that's who it  	// is being deeded to) and the object must be group diff --git a/indra/llinventory/lltransactiontypes.h b/indra/llinventory/lltransactiontypes.h index 1cb7308bd4..2c699bcb87 100644 --- a/indra/llinventory/lltransactiontypes.h +++ b/indra/llinventory/lltransactiontypes.h @@ -69,6 +69,12 @@ const S32 TRANS_PARCEL_DIR_FEE		= 2003;  const S32 TRANS_GROUP_TAX		    = 2004; // Taxes incurred as part of group membership  const S32 TRANS_CLASSIFIED_RENEW	= 2005; +// Codes 2100-2999 reserved for recurring billing services +// New codes can be created through an admin interface so may not +// automatically end up in the list below :-( +// So make sure you check the transaction_description table +const S32 TRANS_RECURRING_GENERIC  = 2100; +  // Codes 3000-3999 reserved for inventory transactions  const S32 TRANS_GIVE_INVENTORY		= 3000; @@ -84,6 +90,12 @@ const S32 TRANS_DWELL_BONUS			= 5007;  const S32 TRANS_PAY_OBJECT			= 5008;  const S32 TRANS_OBJECT_PAYS			= 5009; +// Codes 5100-5999 reserved for recurring billing transfers between users +// New codes can be created through an admin interface so may not +// automatically end up in the list below :-( +// So make sure you check the transaction_description table +const S32 TRANS_RECURRING_GENERIC_USER  = 5100; +  // Codes 6000-6999 reserved for group transactions  //const S32 TRANS_GROUP_JOIN		    = 6000;  //reserved for future use  const S32 TRANS_GROUP_LAND_DEED		= 6001; diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index cfd6183ec4..fdcc19d657 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -121,7 +121,7 @@ void	LLQuaternion::quantize16(F32 lower, F32 upper)  	mQ[VZ] = z;  	mQ[VS] = s; -	normQuat(); +	normalize();  }  void	LLQuaternion::quantize8(F32 lower, F32 upper) @@ -131,7 +131,7 @@ void	LLQuaternion::quantize8(F32 lower, F32 upper)  	mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper);  	mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper); -	normQuat(); +	normalize();  }  // LLVector3 Magnitude and Normalization Functions @@ -346,7 +346,7 @@ const LLQuaternion&	LLQuaternion::setQuat(const LLMatrix4 &mat)  //    mQ[VZ] = (F32)(cosX*cosY*sinZ - sinX*sinY*cosZ);  //#endif  // -//	normQuat(); +//	normalize();  //	return (*this);  } diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index 5db9c5be2e..0769f29f23 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -469,20 +469,30 @@ inline const LLQuaternion&	operator*=(LLQuaternion &a, const LLQuaternion &b)  	return a;  } +const F32 ONE_PART_IN_A_MILLION = 0.000001f; +  inline F32	LLQuaternion::normalize()  {  	F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]);  	if (mag > FP_MAG_THRESHOLD)  	{ -		F32 oomag = 1.f/mag; -		mQ[VX] *= oomag; -		mQ[VY] *= oomag; -		mQ[VZ] *= oomag; -		mQ[VS] *= oomag; +		// Floating point error can prevent some quaternions from achieving +		// exact unity length.  When trying to renormalize such quaternions we +		// can oscillate between multiple quantized states.  To prevent such +		// drifts we only renomalize if the length is far enough from unity. +		if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) +		{ +			F32 oomag = 1.f/mag; +			mQ[VX] *= oomag; +			mQ[VY] *= oomag; +			mQ[VZ] *= oomag; +			mQ[VS] *= oomag; +		}  	}  	else  	{ +		// we were given a very bad quaternion so we set it to identity  		mQ[VX] = 0.f;  		mQ[VY] = 0.f;  		mQ[VZ] = 0.f; @@ -499,11 +509,15 @@ inline F32	LLQuaternion::normQuat()  	if (mag > FP_MAG_THRESHOLD)  	{ -		F32 oomag = 1.f/mag; -		mQ[VX] *= oomag; -		mQ[VY] *= oomag; -		mQ[VZ] *= oomag; -		mQ[VS] *= oomag; +		if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) +		{ +			// only renormalize if length not close enough to 1.0 already +			F32 oomag = 1.f/mag; +			mQ[VX] *= oomag; +			mQ[VY] *= oomag; +			mQ[VZ] *= oomag; +			mQ[VS] *= oomag; +		}  	}  	else  	{ diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 1e8b5517e4..453286b83d 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -3,6 +3,7 @@  project(llmessage)  include(00-Common) +include(GoogleMock)  include(LLAddBuildTest)  include(LLCommon)  include(LLMath) @@ -221,6 +222,7 @@ IF (NOT LINUX AND VIEWER)        # llhttpclientadapter.cpp        lltrustedmessageservice.cpp        lltemplatemessagedispatcher.cpp +      llregionpresenceverifier.cpp        )  #    set(TEST_DEBUG on)      set(test_libs @@ -229,6 +231,7 @@ IF (NOT LINUX AND VIEWER)        ${LLVFS_LIBRARIES}        ${LLMATH_LIBRARIES}        ${LLCOMMON_LIBRARIES} +      ${GOOGLEMOCK_LIBRARIES}        )      LL_ADD_INTEGRATION_TEST( @@ -241,3 +244,4 @@ IF (NOT LINUX AND VIEWER)      LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}")  ENDIF (NOT LINUX AND VIEWER) + diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index 47d49076f4..c044b3d80d 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -100,7 +100,6 @@ public:  	// LEGACY  	boost::signals2::connection get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data); -  	// This method needs to be called from time to time to send out  	// requests.  	void processPending(); diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index a4af8e989b..5ff41322b7 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -131,7 +131,7 @@ void LLCurl::Responder::errorWithContent(  // virtual  void LLCurl::Responder::error(U32 status, const std::string& reason)  { -	llinfos << status << ": " << reason << llendl; +	llinfos << mURL << " [" << status << "]: " << reason << llendl;  }  // virtual @@ -139,6 +139,11 @@ void LLCurl::Responder::result(const LLSD& content)  {  } +void LLCurl::Responder::setURL(const std::string& url) +{ +	mURL = url; +} +  // virtual  void LLCurl::Responder::completedRaw(  	U32 status, @@ -148,7 +153,11 @@ void LLCurl::Responder::completedRaw(  {  	LLSD content;  	LLBufferStream istr(channels, buffer.get()); -	LLSDSerialize::fromXML(content, istr); +	if (!LLSDSerialize::fromXML(content, istr)) +	{ +		llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl; +	} +  	completed(status, reason, content);  } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index fbd3077cbf..0b58e7c4a5 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -120,8 +120,14 @@ public:  			// of the header can be parsed.  In the ::completed call above only the body is contained in the LLSD.  			virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content); +			// Used internally to set the url for debugging later. +			void setURL(const std::string& url); +  	public: /* but not really -- don't touch this */  		U32 mReferenceCount; + +	private: +		std::string mURL;  	};  	typedef boost::intrusive_ptr<Responder>	ResponderPtr; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 8b90a4c5ca..12ecbb36eb 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -265,6 +265,11 @@ static void request(  		}  	} +	if (responder) +	{ +		responder->setURL(url); +	} +  	req->setCallback(new LLHTTPClientURLAdaptor(responder));  	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem) diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp index b6988224ce..9d3c83f828 100644 --- a/indra/llmessage/llhttpclientadapter.cpp +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -1,5 +1,5 @@  /**  - * @file  + * @file llhttpclientadapter.cpp   * @brief    *   * $LicenseInfo:firstyear=2009&license=viewergpl$ diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h index 7f76390d0c..a205a2f260 100644 --- a/indra/llmessage/llhttpclientadapter.h +++ b/indra/llmessage/llhttpclientadapter.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llhttpclientadepter.h   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h index 42a8e5cd0a..085a59cf27 100644 --- a/indra/llmessage/llhttpclientinterface.h +++ b/indra/llmessage/llhttpclientinterface.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llhttpclientinterface.h   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index a00dbd1809..97134bd336 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -521,7 +521,7 @@ protected:  	 * seek orfor string assignment.  	 * @returns Returns true if a line was found.  	 */ -	bool readLine( +	bool readHeaderLine(  		const LLChannelDescriptors& channels,  		buffer_ptr_t buffer,  		U8* dest, @@ -592,7 +592,7 @@ LLHTTPResponder::~LLHTTPResponder()  	//lldebugs << "destroying LLHTTPResponder" << llendl;  } -bool LLHTTPResponder::readLine( +bool LLHTTPResponder::readHeaderLine(  	const LLChannelDescriptors& channels,  	buffer_ptr_t buffer,  	U8* dest, @@ -670,7 +670,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  #endif  		PUMP_DEBUG; -		if(readLine(channels, buffer, (U8*)buf, len)) +		if(readHeaderLine(channels, buffer, (U8*)buf, len))  		{  			bool read_next_line = false;  			bool parse_all = true; @@ -734,7 +734,13 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  					if(read_next_line)  					{  						len = HEADER_BUFFER_SIZE;	 -						readLine(channels, buffer, (U8*)buf, len); +						if (!readHeaderLine(channels, buffer, (U8*)buf, len)) +						{ +							// Failed to read the header line, probably too long. +							// readHeaderLine already marked the channel/buffer as bad. +							keep_parsing = false; +							break; +						}  					}  					if(0 == len)  					{ diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index d52ff6c7e8..ce206d8d7d 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -265,7 +265,7 @@ std::string LLMail::buildSMTPTransaction(  // static  bool LLMail::send(  	const std::string& header, -	const std::string& message, +	const std::string& raw_message,  	const char* from_address,  	const char* to_address)  { @@ -276,8 +276,20 @@ bool LLMail::send(  		return false;  	} -	// *FIX: this translation doesn't deal with a single period on a -	// line by itself. +	// remove any "." SMTP commands to prevent injection (DEV-35777) +	// we don't need to worry about "\r\n.\r\n" because of the  +	// "\n" --> "\n\n" conversion going into rfc2822_msg below +	std::string message = raw_message; +	std::string bad_string = "\n.\n"; +	std::string good_string = "\n..\n"; +	while (1) +	{ +		int index = message.find(bad_string); +		if (index == std::string::npos) break; +		message.replace(index, bad_string.size(), good_string); +	} + +	// convert all "\n" into "\r\n"  	std::ostringstream rfc2822_msg;  	for(U32 i = 0; i < message.size(); ++i)  	{ diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h index 119eb1d7f7..af6733fa05 100644 --- a/indra/llmessage/llmessagesenderinterface.h +++ b/indra/llmessage/llmessagesenderinterface.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llmessagesenderinterface.h   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp index 0527d5cb8d..e02c735ce7 100644 --- a/indra/llmessage/llregionpresenceverifier.cpp +++ b/indra/llmessage/llregionpresenceverifier.cpp @@ -1,5 +1,5 @@  /**  - * @file  + * @file llregionpresenceverifier.cpp   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ @@ -36,11 +36,40 @@  #include "net.h"  #include "message.h" +namespace boost +{ +	void intrusive_ptr_add_ref(LLRegionPresenceVerifier::Response* p) +	{ +		++p->mReferenceCount; +	} +	 +	void intrusive_ptr_release(LLRegionPresenceVerifier::Response* p) +	{ +		if(p && 0 == --p->mReferenceCount) +		{ +			delete p; +		} +	} +}; -LLRegionPresenceVerifier::RegionResponder::RegionResponder(ResponsePtr data) : mSharedData(data) +LLRegionPresenceVerifier::Response::~Response()  {  } +LLRegionPresenceVerifier::RegionResponder::RegionResponder(const std::string& +														   uri, +														   ResponsePtr data, +														   S32 retry_count) : +	mUri(uri), +	mSharedData(data), +	mRetryCount(retry_count) +{ +} + +//virtual +LLRegionPresenceVerifier::RegionResponder::~RegionResponder() +{ +}  void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content)  { @@ -49,30 +78,36 @@ void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content)  	LLHost destination(host, port);  	LLUUID id = content["region_id"]; -	llinfos << "Verifying " << destination.getString() << " is region " << id << llendl; +	lldebugs << "Verifying " << destination.getString() << " is region " << id << llendl;  	std::stringstream uri;  	uri << "http://" << destination.getString() << "/state/basic/"; -	mSharedData->getHttpClient().get(uri.str(), new VerifiedDestinationResponder(mSharedData, content)); +	mSharedData->getHttpClient().get( +		uri.str(), +		new VerifiedDestinationResponder(mUri, mSharedData, content, mRetryCount));  } -void LLRegionPresenceVerifier::RegionResponder::completed( -	U32 status, -	const std::string& reason, -	const LLSD& content) +void LLRegionPresenceVerifier::RegionResponder::error(U32 status, +													 const std::string& reason)  { -	LLHTTPClient::Responder::completed(status, reason, content); -	 -	mSharedData->onCompletedRegionRequest(); +	// TODO: babbage: distinguish between region presence service and +	// region verification errors? +	mSharedData->onRegionVerificationFailed();  } - -LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(ResponsePtr data, const LLSD& content) : mSharedData(data), mContent(content) +LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(const std::string& uri, ResponsePtr data, const LLSD& content, +	S32 retry_count): +	mUri(uri), +	mSharedData(data), +	mContent(content), +	mRetryCount(retry_count)   {  } - - +//virtual +LLRegionPresenceVerifier::VerifiedDestinationResponder::~VerifiedDestinationResponder() +{ +}  void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD& content)  { @@ -87,13 +122,14 @@ void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD&  	{  		mSharedData->onRegionVerified(mContent);  	} -	else if (mSharedData->shouldRetry()) +	else if (mRetryCount > 0)  	{  		retry();  	}  	else  	{ -		llwarns << "Could not correctly look up region from region presence service. Region: " << mSharedData->getRegionUri() << llendl; +		llwarns << "Simulator verification failed. Region: " << mUri << llendl; +		mSharedData->onRegionVerificationFailed();  	}  } @@ -101,13 +137,21 @@ void LLRegionPresenceVerifier::VerifiedDestinationResponder::retry()  {  	LLSD headers;  	headers["Cache-Control"] = "no-cache, max-age=0"; -	llinfos << "Requesting region information, get uncached for region " << mSharedData->getRegionUri() << llendl; -	mSharedData->decrementRetries(); -	mSharedData->getHttpClient().get(mSharedData->getRegionUri(), new RegionResponder(mSharedData), headers); +	llinfos << "Requesting region information, get uncached for region " +			<< mUri << llendl; +	--mRetryCount; +	mSharedData->getHttpClient().get(mUri, new RegionResponder(mUri, mSharedData, mRetryCount), headers);  }  void LLRegionPresenceVerifier::VerifiedDestinationResponder::error(U32 status, const std::string& reason)  { -	retry(); +	if(mRetryCount > 0) +	{ +		retry(); +	} +	else +	{ +		llwarns << "Failed to contact simulator for verification. Region: " << mUri << llendl; +		mSharedData->onRegionVerificationFailed(); +	}  } - diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h index 54ad6226d6..f57a62a731 100644 --- a/indra/llmessage/llregionpresenceverifier.h +++ b/indra/llmessage/llregionpresenceverifier.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llregionpresenceverifier.cpp   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ @@ -37,7 +37,7 @@  #include "llhttpclient.h"  #include <string>  #include "llsd.h" -#include <boost/shared_ptr.hpp> +#include <boost/intrusive_ptr.hpp>  class LLHTTPClientInterface; @@ -47,49 +47,58 @@ public:  	class Response  	{  	public: -		virtual ~Response() {} +		virtual ~Response() = 0;  		virtual bool checkValidity(const LLSD& content) const = 0;  		virtual void onRegionVerified(const LLSD& region_details) = 0; - -		virtual void decrementRetries() = 0; +		virtual void onRegionVerificationFailed() = 0;  		virtual LLHTTPClientInterface& getHttpClient() = 0; -		virtual std::string getRegionUri() const = 0; -		virtual bool shouldRetry() const = 0; -		virtual void onCompletedRegionRequest() {} +	public: /* but not really -- don't touch this */ +		U32 mReferenceCount;		  	}; -	typedef boost::shared_ptr<Response> ResponsePtr; +	typedef boost::intrusive_ptr<Response> ResponsePtr;  	class RegionResponder : public LLHTTPClient::Responder  	{  	public: -		RegionResponder(ResponsePtr data); +		RegionResponder(const std::string& uri, ResponsePtr data, +						S32 retry_count); +		virtual ~RegionResponder();   		virtual void result(const LLSD& content); -		virtual void completed( -			U32 status, -			const std::string& reason, -			const LLSD& content); +		virtual void error(U32 status, const std::string& reason);  	private:  		ResponsePtr mSharedData; +		std::string mUri; +		S32 mRetryCount;  	};  	class VerifiedDestinationResponder : public LLHTTPClient::Responder  	{  	public: -		VerifiedDestinationResponder(ResponsePtr data, const LLSD& content); +		VerifiedDestinationResponder(const std::string& uri, ResponsePtr data, +									 const LLSD& content, S32 retry_count); +		virtual ~VerifiedDestinationResponder();  		virtual void result(const LLSD& content);  		virtual void error(U32 status, const std::string& reason); +		  	private:  		void retry();  		ResponsePtr mSharedData;  		LLSD mContent; +		std::string mUri; +		S32 mRetryCount;  	};  }; +namespace boost +{ +	void intrusive_ptr_add_ref(LLRegionPresenceVerifier::Response* p); +	void intrusive_ptr_release(LLRegionPresenceVerifier::Response* p); +};  #endif //LL_LLREGIONPRESENCEVERIFIER_H diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp index 32cbb15cb3..d6b2f45d04 100644 --- a/indra/llmessage/llstoredmessage.cpp +++ b/indra/llmessage/llstoredmessage.cpp @@ -1,5 +1,5 @@  /**  - * @file  + * @file llstoredmessage.cpp   * @brief    *   * $LicenseInfo:firstyear=2009&license=viewergpl$ diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h index 5069c2cb2e..359e4c5aea 100644 --- a/indra/llmessage/llstoredmessage.h +++ b/indra/llmessage/llstoredmessage.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llstoredmessage.h   * @brief    *   * $LicenseInfo:firstyear=2009&license=viewergpl$ diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp index 70279a3c62..0872efba50 100644 --- a/indra/llmessage/llthrottle.cpp +++ b/indra/llmessage/llthrottle.cpp @@ -265,6 +265,31 @@ BOOL LLThrottleGroup::setNominalBPS(F32* throttle_vec)  	return changed;  } +// Return bits available in the channel +S32		LLThrottleGroup::getAvailable(S32 throttle_cat) +{ +	S32 retval = 0; + +	F32 category_bps = mCurrentBPS[throttle_cat]; +	F32 lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; + +	// use a temporary bits_available +	// since we don't want to change mBitsAvailable every time +	F32 elapsed_time = (F32)(LLMessageSystem::getMessageTimeSeconds() - mLastSendTime[throttle_cat]); +	F32 bits_available = mBitsAvailable[throttle_cat] + (category_bps * elapsed_time); + +	if (bits_available >= lookahead_bits) +	{ +		retval = (S32) gThrottleMaximumBPS[throttle_cat]; +	} +	else  +	{ +		retval = (S32) bits_available; +	} +	 +	return retval; +} +  BOOL LLThrottleGroup::checkOverflow(S32 throttle_cat, F32 bits)  { diff --git a/indra/llmessage/llthrottle.h b/indra/llmessage/llthrottle.h index 7d1679beb2..47a7c653b2 100644 --- a/indra/llmessage/llthrottle.h +++ b/indra/llmessage/llthrottle.h @@ -84,6 +84,8 @@ public:  	BOOL	dynamicAdjust();		// Shift bandwidth from idle channels to busy channels, TRUE if adjustment occurred  	BOOL	setNominalBPS(F32* throttle_vec);				// TRUE if any value was different, resets adjustment system if was different +	S32		getAvailable(S32 throttle_cat);					// Return bits available in the channel +  	void packThrottle(LLDataPacker &dp) const;  	void unpackThrottle(LLDataPacker &dp);  public: diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp index 5a1cd95ffc..41f3f3f607 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -270,7 +270,6 @@ bool is_asset_fetch_by_id_allowed(LLAssetType::EType type)  		case LLAssetType::AT_BODYPART:  		case LLAssetType::AT_ANIMATION:  		case LLAssetType::AT_GESTURE: -		case LLAssetType::AT_FAVORITE:  			rv = true;  			break;  		default: diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 3ab8057abb..81b7761ed5 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -51,6 +51,7 @@ static const U32 HTTP_STATUS_PIPE_ERROR = 499;   * String constants   */  const std::string CONTEXT_DEST_URI_SD_LABEL("dest_uri"); +const std::string CONTEXT_TRANSFERED_BYTES("transfered_bytes");  static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); @@ -247,7 +248,29 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);  	//llinfos << "LLURLRequest::process_impl()" << llendl; -	if(!buffer) return STATUS_ERROR; +	if (!buffer) return STATUS_ERROR; +	 +	// we're still waiting or prcessing, check how many +	// bytes we have accumulated. +	const S32 MIN_ACCUMULATION = 100000; +	if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION)) +	{ +		 // This is a pretty sloppy calculation, but this +		 // tries to make the gross assumption that if data +		 // is coming in at 56kb/s, then this transfer will +		 // probably succeed. So, if we're accumlated +		 // 100,000 bytes (MIN_ACCUMULATION) then let's +		 // give this client another 2s to complete. +		 const F32 TIMEOUT_ADJUSTMENT = 2.0f; +		 mDetail->mByteAccumulator = 0; +		 pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT); +		 lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl; +		 if (mState == STATE_INITIALIZED) +		 { +			  llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl; +		 } +	} +  	switch(mState)  	{  	case STATE_INITIALIZED: @@ -286,27 +309,14 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  			bool newmsg = mDetail->mCurlRequest->getResult(&result);  			if(!newmsg)  			{ -				// we're still waiting or prcessing, check how many -				// bytes we have accumulated. -				const S32 MIN_ACCUMULATION = 100000; -				if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION)) -				{ -					// This is a pretty sloppy calculation, but this -					// tries to make the gross assumption that if data -					// is coming in at 56kb/s, then this transfer will -					// probably succeed. So, if we're accumlated -					// 100,000 bytes (MIN_ACCUMULATION) then let's -					// give this client another 2s to complete. -					const F32 TIMEOUT_ADJUSTMENT = 2.0f; -					mDetail->mByteAccumulator = 0; -					pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT); -				} -  				// keep processing  				break;  			}  			mState = STATE_HAVE_RESPONSE; +			context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; +			context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes; +			lldebugs << this << "Setting context to " << context << llendl;  			switch(result)  			{  				case CURLE_OK: @@ -353,10 +363,16 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  		// we already stuffed everything into channel in in the curl  		// callback, so we are done.  		eos = true; +		context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; +		context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes; +		lldebugs << this << "Setting context to " << context << llendl;  		return STATUS_DONE;  	default:  		PUMP_DEBUG; +		context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; +		context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes; +		lldebugs << this << "Setting context to " << context << llendl;  		return STATUS_ERROR;  	}  } @@ -369,6 +385,8 @@ void LLURLRequest::initialize()  	mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);  	mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);  	mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this); +	mRequestTransferedBytes = 0; +	mResponseTransferedBytes = 0;  }  bool LLURLRequest::configure() @@ -471,6 +489,7 @@ size_t LLURLRequest::downCallback(  		req->mDetail->mChannels.out(),  		(U8*)data,  		bytes); +	req->mResponseTransferedBytes += bytes;  	req->mDetail->mByteAccumulator += bytes;  	return bytes;  } @@ -494,6 +513,7 @@ size_t LLURLRequest::upCallback(  		req->mDetail->mLastRead,  		(U8*)data,  		bytes); +	req->mRequestTransferedBytes += bytes;  	return bytes;  } diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index 86ef71f085..cb3c466440 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -45,6 +45,12 @@  #include "llchainio.h"  #include "llerror.h" + +extern const std::string CONTEXT_REQUEST; +extern const std::string CONTEXT_DEST_URI_SD_LABEL; +extern const std::string CONTEXT_RESPONSE; +extern const std::string CONTEXT_TRANSFERED_BYTES; +  class LLURLRequestDetail;  class LLURLRequestComplete; @@ -208,6 +214,8 @@ protected:  	ERequestAction mAction;  	LLURLRequestDetail* mDetail;  	LLIOPipe::ptr_t mCompletionCallback; +	 S32 mRequestTransferedBytes; +	 S32 mResponseTransferedBytes;  private:  	/**  diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 08c9192c9f..209bdb2249 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -760,30 +760,36 @@ static bool remove_prefix(std::string& filename, const std::string& prefix)  static bool verify_cache_filename(const std::string& filename)  {  	//NOTE: This routine is only used to check file names that our own -	// code places in the cache directory.  As such, it can be limited -	// to this very restrictive file name pattern.  It does not need to -	// handle other characters. - +	// code places in the cache directory.	As such, it can be limited +	// to this very restrictive file name pattern.	It does not need to +	// handle other characters. The only known uses of this are (with examples): +	//	sim to sim object pass:			fc0b72d8-9456-63d9-a802-a557ef847313.tmp +	//	sim to viewer mute list:		mute_b78eacd0-1244-448e-93ca-28ede242f647.tmp +	//	sim to viewer task inventory:	inventory_d8ab59d2-baf0-0e79-c4c2-a3f99b9fcf45.tmp +	 +	//IMPORTANT: Do not broaden the filenames accepted by this routine +	// without careful analysis. Anything allowed by this function can +	// be downloaded by the viewer. +	  	size_t len = filename.size(); -	//const boost::regex expr("[a-zA-Z0-9][-_.a-zA-Z0-9]<0,49>"); -	if (len < 1 || len > 50) -	{ +	//const boost::regex expr("[0-9a-zA-Z_-]<1,46>\.tmp"); +	if (len < 5 || len > 50) +	{	  		return false;  	} -	for(unsigned i=0; i<len; ++i) -	{ +	for(size_t i=0; i<(len-4); ++i) +	{	  		char c = filename[i]; -		bool ok = isalnum(c); -		if (!ok && i > 0) -		{ -			ok = '_'==c || '-'==c || '.'==c; -		} +		bool ok = isalnum(c) || '_'==c || '-'==c;  		if (!ok)  		{  			return false;  		}  	} -	return true; +	return filename[len-4] == '.' +		&& filename[len-3] == 't' +		&& filename[len-2] == 'm' +		&& filename[len-1] == 'p';  }  void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/) diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp index 5dc5932fde..e6a5ad9946 100644 --- a/indra/llmessage/tests/llcurl_stub.cpp +++ b/indra/llmessage/tests/llcurl_stub.cpp @@ -22,6 +22,7 @@  #include "linden_common.h"  LLCurl::Responder::Responder() +	: mReferenceCount(0)  {  } diff --git a/indra/llmessage/tests/llmockhttpclient.h b/indra/llmessage/tests/llmockhttpclient.h new file mode 100644 index 0000000000..2f55e97fcc --- /dev/null +++ b/indra/llmessage/tests/llmockhttpclient.h @@ -0,0 +1,61 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement 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$ + */ + +/* Macro Definitions */ +#ifndef LL_LLMOCKHTTPCLIENT_H +#define LL_LLMOCKHTTPCLIENT_H + +#include "linden_common.h" +#include "llhttpclientinterface.h" + +#include <gmock/gmock.h> + +class LLMockHTTPClient : public LLHTTPClientInterface +{ +public: +  MOCK_METHOD2(get, void(const std::string& url, LLCurl::ResponderPtr responder)); +  MOCK_METHOD3(get, void(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)); +  MOCK_METHOD3(put, void(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)); +}; + +// A helper to match responder types +template<typename T> +struct ResponderType +{ +	bool operator()(LLCurl::ResponderPtr ptr) const +	{ +		T* p = dynamic_cast<T*>(ptr.get()); +		return p != NULL; +	} +}; + +inline bool operator==(const LLSD& l, const LLSD& r) +{ +	std::ostringstream ls, rs; +	ls << l; +	rs << r; +	return ls.str() == rs.str(); + +} + + +#endif //LL_LLMOCKHTTPCLIENT_H + diff --git a/indra/llmessage/tests/llregionpresenceverifier_test.cpp b/indra/llmessage/tests/llregionpresenceverifier_test.cpp new file mode 100644 index 0000000000..b7602ef15c --- /dev/null +++ b/indra/llmessage/tests/llregionpresenceverifier_test.cpp @@ -0,0 +1,111 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "../test/lltut.h" +#include "llregionpresenceverifier.h" +#include "llcurl_stub.cpp" +#include "llhost.cpp" +#include "net.cpp" +#include "lltesthttpclientadapter.cpp" + +class LLTestResponse : public LLRegionPresenceVerifier::Response +{ +public: + +	virtual bool checkValidity(const LLSD& content) const +	{ +		return true; +	} + +	virtual void onRegionVerified(const LLSD& region_details) +	{ +	} + +	virtual void onRegionVerificationFailed() +	{ +	} +	 +	virtual LLHTTPClientInterface& getHttpClient() +	{ +		return mHttpInterface; +	} + +	LLTestHTTPClientAdapter mHttpInterface; +}; + +namespace tut +{ +	struct LLRegionPresenceVerifierData +	{ +		LLRegionPresenceVerifierData() : +			mResponse(new LLTestResponse()), +			mResponder("", LLRegionPresenceVerifier::ResponsePtr(mResponse), +					   LLSD(), 3) +		{ +		} +		 +		LLTestResponse* mResponse; +		LLRegionPresenceVerifier::VerifiedDestinationResponder mResponder; +	}; + +	typedef test_group<LLRegionPresenceVerifierData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLRegionPresenceVerifier test"); +} + +namespace tut +{ +	// Test that VerifiedDestinationResponder does retry +    // on error when shouldRetry returns true. +	template<> template<> +	void object::test<1>() +	{ +		mResponder.error(500, "Internal server error"); +		ensure_equals(mResponse->mHttpInterface.mGetUrl.size(), 1); +	} + +	// Test that VerifiedDestinationResponder only retries +	// on error until shouldRetry returns false. +	template<> template<> +	void object::test<2>() +	{ +		mResponder.error(500, "Internal server error"); +		mResponder.error(500, "Internal server error"); +		mResponder.error(500, "Internal server error"); +		mResponder.error(500, "Internal server error"); +		ensure_equals(mResponse->mHttpInterface.mGetUrl.size(), 3); +	} +} + diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 7299ede22d..e019cdcf21 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -884,6 +884,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)  }  /* virtual */  +void LLPluginClassMedia::pluginLaunchFailed() +{ +	mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH); +} + +/* virtual */   void LLPluginClassMedia::pluginDied()  {  	mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED); diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 331ca5f6dc..97f2a11ef2 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -135,6 +135,7 @@ public:  	// Inherited from LLPluginProcessParentOwner  	/* virtual */ void receivePluginMessage(const LLPluginMessage &message); +	/* virtual */ void pluginLaunchFailed();  	/* virtual */ void pluginDied(); diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index df6de0925e..cfee847080 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -56,7 +56,8 @@ public:  		MEDIA_EVENT_CLICK_LINK_HREF,		// I'm not entirely sure what the semantics of these two are  		MEDIA_EVENT_CLICK_LINK_NOFOLLOW, -		MEDIA_EVENT_PLUGIN_FAILED			// The plugin failed to launch or died unexpectedly +		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch  +		MEDIA_EVENT_PLUGIN_FAILED			// The plugin died unexpectedly  	} EMediaEvent; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 41784a713c..f3b4c6bdc6 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -83,6 +83,14 @@ void LLPluginProcessParent::killSockets(void)  	mSocket.reset();  } +void LLPluginProcessParent::errorState(void) +{ +	if(mState < STATE_RUNNING) +		setState(STATE_LAUNCH_FAILURE); +	else +		setState(STATE_ERROR); +} +  void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename)  {	  	mProcess.setExecutable(launcher_filename); @@ -132,7 +140,7 @@ bool LLPluginProcessParent::accept()  		ll_apr_warn_status(status);  		// Some other error. -		setState(STATE_ERROR); +		errorState();  	}  	return result;	 @@ -150,15 +158,15 @@ void LLPluginProcessParent::idle(void)  			if(!mMessagePipe->pump())  			{  //				LL_WARNS("Plugin") << "Message pipe hit an error state" << LL_ENDL; -				setState(STATE_ERROR); +				errorState();  			}  		} -		if((mSocketError != APR_SUCCESS) && (mState < STATE_ERROR)) +		if((mSocketError != APR_SUCCESS) && (mState <= STATE_RUNNING))  		{  			// The socket is in an error state -- the plugin is gone.  			LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; -			setState(STATE_ERROR); +			errorState();  		}	  		// If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). @@ -191,7 +199,7 @@ void LLPluginProcessParent::idle(void)  				if(ll_apr_warn_status(status))  				{  					killSockets(); -					setState(STATE_ERROR); +					errorState();  					break;  				} @@ -202,7 +210,7 @@ void LLPluginProcessParent::idle(void)  				if(ll_apr_warn_status(status))  				{  					killSockets(); -					setState(STATE_ERROR); +					errorState();  					break;  				} @@ -212,7 +220,7 @@ void LLPluginProcessParent::idle(void)  					if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket())))  					{  						killSockets(); -						setState(STATE_ERROR); +						errorState();  						break;  					}  					mBoundPort = bound_addr->port;	 @@ -222,7 +230,7 @@ void LLPluginProcessParent::idle(void)  						LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL;  						killSockets(); -						setState(STATE_ERROR); +						errorState();  						break;  					}  				} @@ -234,7 +242,7 @@ void LLPluginProcessParent::idle(void)  				if(ll_apr_warn_status(status))  				{  					killSockets(); -					setState(STATE_ERROR); +					errorState();  					break;  				} @@ -242,7 +250,7 @@ void LLPluginProcessParent::idle(void)  				if(ll_apr_warn_status(status))  				{  					killSockets(); -					setState(STATE_ERROR); +					errorState();  					break;  				} @@ -255,7 +263,7 @@ void LLPluginProcessParent::idle(void)  				if(ll_apr_warn_status(status))  				{  					killSockets(); -					setState(STATE_ERROR); +					errorState();  					break;  				} @@ -274,7 +282,7 @@ void LLPluginProcessParent::idle(void)  				mProcess.addArgument(stream.str());  				if(mProcess.launch() != 0)  				{ -					setState(STATE_ERROR); +					errorState();  				}  				else  				{ @@ -290,7 +298,7 @@ void LLPluginProcessParent::idle(void)  				// waiting for the plugin to connect  				if(pluginLockedUpOrQuit())  				{ -					setState(STATE_ERROR); +					errorState();  				}  				else  				{ @@ -309,7 +317,7 @@ void LLPluginProcessParent::idle(void)  				if(pluginLockedUpOrQuit())  				{ -					setState(STATE_ERROR); +					errorState();  				}  			break; @@ -330,14 +338,14 @@ void LLPluginProcessParent::idle(void)  				// The load_plugin_response message will kick us from here into STATE_RUNNING  				if(pluginLockedUpOrQuit())  				{ -					setState(STATE_ERROR); +					errorState();  				}  			break;  			case STATE_RUNNING:  				if(pluginLockedUpOrQuit())  				{ -					setState(STATE_ERROR); +					errorState();  				}  			break; @@ -349,8 +357,16 @@ void LLPluginProcessParent::idle(void)  				else if(pluginLockedUp())  				{  					LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << llendl; -					setState(STATE_ERROR); +					errorState(); +				} +			break; + +			case STATE_LAUNCH_FAILURE: +				if(mOwner != NULL) +				{ +					mOwner->pluginLaunchFailed();  				} +				setState(STATE_CLEANUP);  			break;  			case STATE_ERROR: @@ -467,7 +483,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)  			else  			{  				LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; -				setState(STATE_ERROR); +				errorState();  			}  		} @@ -477,6 +493,9 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)  			{  				// Plugin has been loaded.  +				mPluginVersionString = message.getValue("plugin_version"); +				LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; +  				// Check which message classes/versions the plugin supports.  				// TODO: check against current versions  				// TODO: kill plugin on major mismatches? @@ -487,8 +506,6 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)  					LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL;  				} -				mPluginVersionString = message.getValue("plugin_version"); -				  				// Send initial sleep time  				setSleepTime(mSleepTime, true);			 @@ -497,7 +514,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)  			else  			{  				LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; -				setState(STATE_ERROR); +				errorState();  			}  		}  		else if(message_name == "heartbeat") diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 0d0b047c88..754ebeb946 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -45,6 +45,7 @@ public:  	virtual ~LLPluginProcessParentOwner();  	virtual void receivePluginMessage(const LLPluginMessage &message) = 0;  	// This will only be called when the plugin has died unexpectedly  +	virtual void pluginLaunchFailed() {};  	virtual void pluginDied() {};  }; @@ -68,6 +69,9 @@ public:  	bool isDone(void);	  	void killSockets(void); +	 +	// Go to the proper error state +	void errorState(void);  	void setSleepTime(F64 sleep_time, bool force_send = false);  	F64 getSleepTime(void) const { return mSleepTime; }; @@ -110,6 +114,7 @@ private:  		STATE_HELLO,			// first message from the plugin process has been received  		STATE_LOADING,			// process has been asked to load the plugin  		STATE_RUNNING,			//  +		STATE_LAUNCH_FAILURE,	// Failure before plugin loaded  		STATE_ERROR,			// generic bailout state  		STATE_CLEANUP,			// clean everything up  		STATE_EXITING,			// Tried to kill process, waiting for it to exit diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index b102254b62..d307d4bbfb 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -746,16 +746,201 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai  	U32 old_face_mask = mVolumep->mFaceMask; +	S32 face_bit = 0; +	S32 cur_mask = 0; + +	// Grab copies of the old faces from the original shape, ordered by type. +	// We will use these to figure out what old texture info gets mapped to new +	// faces in the new shape. +	std::vector<LLProfile::Face> old_faces;  +	for (S32 face = 0; face < mVolumep->getNumFaces(); face++) +	{ +		old_faces.push_back(mVolumep->getProfile().mFaces[face]); +	} + +	// Copy the old texture info off to the side, but not in the order in which +	// they live in the mTextureList, rather in order of ther "face id" which +	// is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. +	// +	// Hence, some elements of old_tes::mEntryList will be invalid.  It is +	// initialized to a size of 9 (max number of possible faces on a volume?) +	// and only the ones with valid types are filled in. +	LLPrimTextureList old_tes; +	old_tes.setSize(9); +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		cur_mask = 0x1 << face_bit; +		if (old_face_mask & cur_mask) +		{ +			S32 te_index = face_index_from_id(cur_mask, old_faces); +			old_tes.copyTexture(face_bit, *(getTE(te_index))); +			//llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl; +		} +	} + +  	// build the new object  	sVolumeManager->unrefVolume(mVolumep);  	mVolumep = volumep;  	U32 new_face_mask = mVolumep->mFaceMask; -	if (old_face_mask != new_face_mask)  +	S32 i; + +	if (old_face_mask == new_face_mask)   	{ +		// nothing to do +		return TRUE; +	} + +	if (mVolumep->getNumFaces() == 0 && new_face_mask != 0) +	{ +		llwarns << "Object with 0 faces found...INCORRECT!" << llendl;  		setNumTEs(mVolumep->getNumFaces()); +		return TRUE; +	} + +	// initialize face_mapping +	S32 face_mapping[9]; +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		face_mapping[face_bit] = face_bit; +	} + +	// The new shape may have more faces than the original, but we can't just +	// add them to the end -- the ordering matters and it may be that we must +	// insert the new faces in the middle of the list.  When we add a face it +	// will pick up the texture/color info of one of the old faces an so we +	// now figure out which old face info gets mapped to each new face, and  +	// store in the face_mapping lookup table. +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		cur_mask = 0x1 << face_bit; +		if (!(new_face_mask & cur_mask)) +		{ +			// Face doesn't exist in new map. +			face_mapping[face_bit] = -1; +			continue; +		} +		else if (old_face_mask & cur_mask) +		{ +			// Face exists in new and old map. +			face_mapping[face_bit] = face_bit; +			continue; +		} + +		// OK, how we've got a mismatch, where we have to fill a new face with one from +		// the old face. +		if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) +		{ +			// It's a top/bottom/hollow interior face. +			if (old_face_mask & LL_FACE_PATH_END) +			{ +				face_mapping[face_bit] = 1; +				continue; +			} +			else +			{ +				S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; +				for (i = 0; i < 4; i++) +				{ +					if (old_face_mask & cur_outer_mask) +					{ +						face_mapping[face_bit] = 5 + i; +						break; +					} +					cur_outer_mask <<= 1; +				} +				if (i == 4) +				{ +					llwarns << "No path end or outer face in volume!" << llendl; +				} +				continue; +			} +		} + +		if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) +		{ +			// A cut slice.  Use the hollow interior if we have it. +			if (old_face_mask & LL_FACE_INNER_SIDE) +			{ +				face_mapping[face_bit] = 2; +				continue; +			} + +			// No interior, use the bottom face. +			// Could figure out which of the outer faces was nearest, but that would be harder. +			if (old_face_mask & LL_FACE_PATH_END) +			{ +				face_mapping[face_bit] = 1; +				continue; +			} +			else +			{ +				S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; +				for (i = 0; i < 4; i++) +				{ +					if (old_face_mask & cur_outer_mask) +					{ +						face_mapping[face_bit] = 5 + i; +						break; +					} +					cur_outer_mask <<= 1; +				} +				if (i == 4) +				{ +					llwarns << "No path end or outer face in volume!" << llendl; +				} +				continue; +			} +		} + +		// OK, the face that's missing is an outer face... +		// Pull from the nearest adjacent outer face (there's always guaranteed to be one... +		S32 cur_outer = face_bit - 5; +		S32 min_dist = 5; +		S32 min_outer_bit = -1; +		S32 i; +		for (i = 0; i < 4; i++) +		{ +			if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) +			{ +				S32 dist = abs(i - cur_outer); +				if (dist < min_dist) +				{ +					min_dist = dist; +					min_outer_bit = i + 5; +				} +			} +		} +		if (-1 == min_outer_bit) +		{ +			llinfos << (LLVolume *)mVolumep << llendl; +			llwarns << "Bad!  No outer faces, impossible!" << llendl; +		} +		face_mapping[face_bit] = min_outer_bit;  	} +	 +	setNumTEs(mVolumep->getNumFaces()); +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		// For each possible face type on the new shape we check to see if that +		// face exists and if it does we create a texture entry that is a copy +		// of one of the originals.  Since the originals might not have a +		// matching face, we use the face_mapping lookup table to figure out +		// which face information to copy. +		cur_mask = 0x1 << face_bit; +		if (new_face_mask & cur_mask) +		{ +			if (-1 == face_mapping[face_bit]) +			{ +				llwarns << "No mapping from old face to new face!" << llendl; +			} + +			S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); +			setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); +		} +	}  	return TRUE;  } @@ -1715,10 +1900,10 @@ LLSD LLLightImageParams::asLLSD() const  bool LLLightImageParams::fromLLSD(LLSD& sd)  { -	if (sd.has("texture") && sd.has("params") && sd["params"].size() == 3) +	if (sd.has("texture"))  	{  		setLightTexture( sd["texture"] ); -		setParams( LLVector3(sd["params"][0].asReal(), sd["params"][1].asReal(), sd["params"][2].asReal()) ); +		setParams( LLVector3( sd["params"] ) );  		return true;  	}  diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index d03150fc78..1c7de95975 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -135,13 +135,12 @@ S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te)  {  	if (S32(index) >= mEntryList.size())  	{ -		// TODO -- assert here  		S32 current_size = mEntryList.size(); -		llerrs << "index = " << S32(index) << "  current_size = " << current_size << llendl; +		llwarns << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << llendl;  		return TEM_CHANGE_NONE;  	} -	// we're changing an existing entry +		// we're changing an existing entry  	llassert(mEntryList[index]);  	delete (mEntryList[index]);  	if  (&te) @@ -387,8 +386,18 @@ void LLPrimTextureList::setSize(S32 new_size)  		mEntryList.resize(new_size);  		for (S32 index = current_size; index < new_size; ++index)  		{ -			LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); -			mEntryList[index] = new_entry; +			if (current_size > 0 +				&& mEntryList[current_size - 1]) +			{ +				// copy the last valid entry for the new one +				mEntryList[index] = mEntryList[current_size - 1]->newCopy(); +			} +			else +			{ +				// no valid enries to copy, so we new one up +				LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); +				mEntryList[index] = new_entry; +			}  		}  	}  	else if (new_size < current_size) diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index b534939dfc..8f7cd68834 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -646,3 +646,9 @@ LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &versi      }      return id;  } + +//static +bool LLTextureEntry::isMediaVersionString(const std::string &version_string) +{ +	return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX); +} diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 8d2834f78c..d6366b9bb2 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -171,7 +171,9 @@ public:      static U32 getVersionFromMediaVersionString(const std::string &version_string);      // Given a media version string, return the UUID of the agent      static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string); - +	// Return whether or not the given string is actually a media version +	static bool isMediaVersionString(const std::string &version_string); +	  	// Media flags  	enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 4525f0a45b..c512ef25be 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -91,6 +91,16 @@ void LLDockableFloater::setVisible(BOOL visible)  	LLFloater::setVisible(visible);  } +void LLDockableFloater::onDockHidden() +{ +	setCanDock(FALSE); +} + +void LLDockableFloater::onDockShown() +{ +	setCanDock(TRUE); +} +  void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)  {  	if (mDockControl.get() != NULL && mDockControl.get()->isDockVisible()) diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index ed90567ad3..7d91d007ee 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -68,6 +68,9 @@ public:  	 */  	/*virtual*/ void setVisible(BOOL visible); +	virtual void onDockHidden(); +	virtual void onDockShown(); +  private:  	/**  	 * Provides unique of dockable floater. diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index 146c7a969a..cdcd823b1c 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -33,6 +33,7 @@  #include "linden_common.h"  #include "lldockcontrol.h" +#include "lldockablefloater.h"  LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,  		const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) : @@ -91,8 +92,8 @@ void LLDockControl::repositionDockable()  	// recalculate dockable position if dock position changed, dock visibility changed,  	// root view rect changed or recalculation is forced -	if (mEnabled && (mPrevDockRect != dockRect  || prev_visibility != mDockWidget->getVisible() -			|| mRootRect != rootRect || mRecalculateDocablePosition)) +	if (mPrevDockRect != dockRect  || prev_visibility != mDockWidget->getVisible() +			|| mRootRect != rootRect || mRecalculateDocablePosition)  	{  		// undock dockable and off() if dock not visible  		if (!isDockVisible()) @@ -100,10 +101,25 @@ void LLDockControl::repositionDockable()  			mDockableFloater->setDocked(false);  			// force off() since dockable may not have dockControll at this time  			off(); +			LLDockableFloater* dockable_floater = +					dynamic_cast<LLDockableFloater*> (mDockableFloater); +			if(dockable_floater != NULL) +			{ +				dockable_floater->onDockHidden(); +			}  		}  		else  		{ -			moveDockable(); +			if(mEnabled) +			{ +				moveDockable(); +			} +			LLDockableFloater* dockable_floater = +					dynamic_cast<LLDockableFloater*> (mDockableFloater); +			if(dockable_floater != NULL) +			{ +				dockable_floater->onDockShown(); +			}  		}  		mPrevDockRect = dockRect; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 564e4d748f..b7a15a2b33 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -664,7 +664,8 @@ void LLFloater::closeFloater(bool app_quitting)  		dirtyRect(); -		// Close callback +		// Close callbacks +		onClose(app_quitting);  		mCloseSignal(this, LLSD(app_quitting));  		// Hide or Destroy diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 1dc5177f81..17ffc94014 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -208,8 +208,8 @@ public:  	virtual BOOL	handleMiddleMouseDown(S32 x, S32 y, MASK mask);  	virtual void	draw(); -	// *TODO: Eliminate this in favor of mOpenSignal  	virtual void	onOpen(const LLSD& key) {} +	virtual void	onClose(bool app_quitting) {}  	// This cannot be "const" until all derived floater canClose()  	// methods are const as well.  JC @@ -293,11 +293,18 @@ private:  	void			addResizeCtrls();  	void 			addDragHandle(); +public: +	// Called when floater is opened, passes mKey +	// Public so external views or floaters can watch for this floater opening +	commit_signal_t mOpenSignal; + +	// Called when floater is closed, passes app_qitting as LLSD() +	// Public so external views or floaters can watch for this floater closing +	commit_signal_t mCloseSignal;		 +  protected:  	std::string		mRectControl;  	std::string		mVisibilityControl; -	commit_signal_t mOpenSignal;		// Called when floater is opened, passes mKey -	commit_signal_t mCloseSignal;		// Called when floater is closed, passes app_qitting as LLSD()  	LLSD			mKey;				// Key used for retrieving instances; set (for now) by LLFLoaterReg  	LLDragHandle*	mDragHandle; diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 2bb6749c83..8dbcd6e229 100644 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -83,6 +83,12 @@ void LLMenuButton::toggleMenu()  } +void LLMenuButton::hideMenu()  +{  +	mMenu->setVisible(FALSE);  +} + +  BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )  {  	if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h index 94b0e4355d..02eb9d3806 100644 --- a/indra/llui/llmenubutton.h +++ b/indra/llui/llmenubutton.h @@ -54,6 +54,7 @@ public:  	/*virtual*/ void draw();  	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); +	void hideMenu();  protected:  	friend class LLUICtrlFactory; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 1695aee2b8..69ff3dddc3 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -522,7 +522,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu  		// be built/added. JC  		if (parent)  		{ -			S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1; +			S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : parent->getLastTabGroup();  			parent->addChild(this, tab_group);  		} diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 62f03f47e6..3dacf979c7 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -807,6 +807,9 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)  			++cur_seg_iter;  		}  	} + +	// layout potentially changed +	needsReflow();  }  BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 8f5c029816..c55273cacf 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -38,6 +38,7 @@  // Library includes  #include "lltextbox.h"  #include "lliconctrl.h" +#include "llmenugl.h"       // hideMenus()  #include "llui.h"			// positionViewNearMouse()  #include "llwindow.h" @@ -94,7 +95,16 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolTipView::handleMouseDown(S32 x, S32 y, MASK mask)  {  	LLToolTipMgr::instance().blockToolTips(); -	return LLView::handleMouseDown(x, y, mask); + +	if (LLView::handleMouseDown(x, y, mask)) +	{ +		// If we are handling the mouse event menu holder  +		// won't get a chance to close menus so do this here  +		LLMenuGL::sMenuContainer->hideMenus(); +		return TRUE; +	} + +	return FALSE;  }  BOOL LLToolTipView::handleMiddleMouseDown(S32 x, S32 y, MASK mask) @@ -189,7 +199,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)  		addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_params));  		// move text over to fit image in -		mTextBox->translate(TOOLTIP_ICON_SIZE,0); +		mTextBox->translate(TOOLTIP_ICON_SIZE + mPadding, 0);  	}  	if (p.click_callback.isProvided()) diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index e47010c316..3c77c655b8 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -321,7 +321,7 @@ fail:  	static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block);  private: -	//static void setCtrlValue(LLView* view, LLXMLNodePtr node); +	// this exists to get around dependency on llview  	static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);  	// Avoid directly using LLUI and LLDir in the template code diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp index 93ac120302..315baa001d 100755 --- a/indra/llvfs/llpidlock.cpp +++ b/indra/llvfs/llpidlock.cpp @@ -62,7 +62,7 @@ class LLPidLockFile  			mSaving(FALSE), mWaiting(FALSE),   			mClean(TRUE), mPID(getpid())  		{ -			mLockName = gDirUtilp->getTempDir() + "/savelock"; +			mLockName = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + "savelock";  		}  		bool requestLock(LLNameTable<void *> *name_table, bool autosave,  						bool force_immediate=FALSE, F32 timeout=300.0); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index d2760e3d59..7137c93476 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -2763,10 +2763,6 @@ const char* cursorIDToName(int id)  		case UI_CURSOR_TOOLPAN:			return "UI_CURSOR_TOOLPAN";  		case UI_CURSOR_TOOLZOOMIN:		return "UI_CURSOR_TOOLZOOMIN";  		case UI_CURSOR_TOOLPICKOBJECT3:	return "UI_CURSOR_TOOLPICKOBJECT3"; -		case UI_CURSOR_TOOLSIT:			return "UI_CURSOR_TOOLSIT"; -		case UI_CURSOR_TOOLBUY:			return "UI_CURSOR_TOOLBUY"; -		case UI_CURSOR_TOOLPAY:			return "UI_CURSOR_TOOLPAY"; -		case UI_CURSOR_TOOLOPEN:		return "UI_CURSOR_TOOLOPEN";  		case UI_CURSOR_TOOLPLAY:		return "UI_CURSOR_TOOLPLAY";  		case UI_CURSOR_TOOLPAUSE:		return "UI_CURSOR_TOOLPAUSE";  		case UI_CURSOR_TOOLMEDIAOPEN:	return "UI_CURSOR_TOOLMEDIAOPEN"; @@ -2862,10 +2858,6 @@ void LLWindowMacOSX::setCursor(ECursorType cursor)  	case UI_CURSOR_TOOLPAN:  	case UI_CURSOR_TOOLZOOMIN:  	case UI_CURSOR_TOOLPICKOBJECT3: -	case UI_CURSOR_TOOLSIT: -	case UI_CURSOR_TOOLBUY: -	case UI_CURSOR_TOOLPAY: -	case UI_CURSOR_TOOLOPEN:  	case UI_CURSOR_TOOLPLAY:  	case UI_CURSOR_TOOLPAUSE:  	case UI_CURSOR_TOOLMEDIAOPEN: @@ -2907,10 +2899,6 @@ void LLWindowMacOSX::initCursors()  	initPixmapCursor(UI_CURSOR_TOOLPAN, 7, 6);  	initPixmapCursor(UI_CURSOR_TOOLZOOMIN, 7, 6);  	initPixmapCursor(UI_CURSOR_TOOLPICKOBJECT3, 1, 1); -	initPixmapCursor(UI_CURSOR_TOOLSIT, 1, 1); -	initPixmapCursor(UI_CURSOR_TOOLBUY, 1, 1); -	initPixmapCursor(UI_CURSOR_TOOLPAY, 1, 1); -	initPixmapCursor(UI_CURSOR_TOOLOPEN, 1, 1);  	initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1);  	initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1);  	initPixmapCursor(UI_CURSOR_TOOLMEDIAOPEN, 1, 1); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index ecda880c1f..00a8d429ba 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1981,10 +1981,6 @@ void LLWindowSDL::initCursors()  	mSDLCursors[UI_CURSOR_TOOLPAN] = makeSDLCursorFromBMP("lltoolpan.BMP",7,5);  	mSDLCursors[UI_CURSOR_TOOLZOOMIN] = makeSDLCursorFromBMP("lltoolzoomin.BMP",7,5);  	mSDLCursors[UI_CURSOR_TOOLPICKOBJECT3] = makeSDLCursorFromBMP("toolpickobject3.BMP",0,0); -	mSDLCursors[UI_CURSOR_TOOLSIT] = makeSDLCursorFromBMP("toolsit.BMP",0,0); -	mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",0,0); -	mSDLCursors[UI_CURSOR_TOOLPAY] = makeSDLCursorFromBMP("toolpay.BMP",0,0); -	mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",0,0);  	mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP("toolplay.BMP",0,0);  	mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0);  	mSDLCursors[UI_CURSOR_TOOLMEDIAOPEN] = makeSDLCursorFromBMP("toolmediaopen.BMP",0,0); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 0faa3e93ff..c608c21d05 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1527,10 +1527,6 @@ void LLWindowWin32::initCursors()  	mCursor[ UI_CURSOR_PIPETTE ] = LoadCursor(module, TEXT("TOOLPIPETTE"));  	// Color cursors -	mCursor[UI_CURSOR_TOOLSIT] = loadColorCursor(TEXT("TOOLSIT")); -	mCursor[UI_CURSOR_TOOLBUY] = loadColorCursor(TEXT("TOOLBUY")); -	mCursor[UI_CURSOR_TOOLPAY] = loadColorCursor(TEXT("TOOLPAY")); -	mCursor[UI_CURSOR_TOOLOPEN] = loadColorCursor(TEXT("TOOLOPEN"));  	mCursor[UI_CURSOR_TOOLPLAY] = loadColorCursor(TEXT("TOOLPLAY"));  	mCursor[UI_CURSOR_TOOLPAUSE] = loadColorCursor(TEXT("TOOLPAUSE"));  	mCursor[UI_CURSOR_TOOLMEDIAOPEN] = loadColorCursor(TEXT("TOOLMEDIAOPEN")); diff --git a/indra/lscript/lscript_byteformat.h b/indra/lscript/lscript_byteformat.h index ba2c46bef2..a54ebd5831 100644 --- a/indra/lscript/lscript_byteformat.h +++ b/indra/lscript/lscript_byteformat.h @@ -556,7 +556,7 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =  // http_request string constants  extern const char* URL_REQUEST_GRANTED;  extern const char* URL_REQUEST_DENIED; -extern const U64 LSL_HTTP_REQUEST_TIMEOUT; +extern const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC;  #endif diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp index 98146d6f2b..3b8bbbe805 100644 --- a/indra/lscript/lscript_compile/lscript_tree.cpp +++ b/indra/lscript/lscript_compile/lscript_tree.cpp @@ -631,9 +631,7 @@ static void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetTy  		switch(targetType)  		{  		case LST_INTEGER: -			//fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)\n"); -			fprintf(fp, "conv.i4\n"); // TODO replace this line with the above -			// we the entire grid is > 1.25.1 +			fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)\n");  			break;  		case LST_STRING:  			fprintf(fp, "call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ToString(float32)\n"); @@ -8375,10 +8373,18 @@ void LLScriptStateChange::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp  			chunk->addInteger(mIdentifier->mScopeEntry->mCount);  		}  		break; +	case LSCP_TYPE: +		mReturnType = basetype; +		break;  	case LSCP_EMIT_CIL_ASSEMBLY:  		fprintf(fp, "ldarg.0\n");  		fprintf(fp, "ldstr \"%s\"\n", mIdentifier->mName);  		fprintf(fp, "call instance void class [LslUserScript]LindenLab.SecondLife.LslUserScript::ChangeState(string)\n"); +		// We are doing a state change. In the LSL interpreter, this is basically a longjmp. We emulate it +		// here using a call to the ChangeState followed by a short cut return of the current method. To +		// maintain type safety we need to push an arbitrary variable of the current method's return type +		// onto the stack before returning. This will be ignored and discarded. +		print_cil_init_variable(fp, mReturnType);  		fprintf(fp, "ret\n");  		break;  	default: diff --git a/indra/lscript/lscript_compile/lscript_tree.h b/indra/lscript/lscript_compile/lscript_tree.h index 12c16908af..a667e1eb5b 100644 --- a/indra/lscript/lscript_compile/lscript_tree.h +++ b/indra/lscript/lscript_compile/lscript_tree.h @@ -1888,6 +1888,7 @@ public:  	S32 getSize();  	LLScriptIdentifier *mIdentifier; +	LSCRIPTType mReturnType;  };  class LLScriptJump : public LLScriptStatement diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h index 245fc320d1..96855abea0 100644 --- a/indra/lscript/lscript_execute.h +++ b/indra/lscript/lscript_execute.h @@ -371,8 +371,7 @@ class LLScriptExecute  {  public:  	LLScriptExecute(); -	virtual ~LLScriptExecute() {;} - +	virtual ~LLScriptExecute()  = 0;  	virtual S32 getVersion() const = 0;  	virtual void deleteAllEvents() = 0;  	virtual void addEvent(LLScriptDataCollection* event) = 0; diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index 2fd81210c0..e849fa9a6e 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -41,6 +41,8 @@  #include "lscript_library.h"  #include "lscript_heapruntime.h"  #include "lscript_alloc.h" +#include "llstat.h" +  // Static  const	S32	DEFAULT_SCRIPT_TIMER_CHECK_SKIP = 4; @@ -72,7 +74,7 @@ const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";  const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED";  // HTTP Requests to LSL scripts will time out after 25 seconds. -const U64 LSL_HTTP_REQUEST_TIMEOUT = 25 * USEC_PER_SEC;  +const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC = 25 * USEC_PER_SEC;   LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)  { @@ -110,6 +112,7 @@ LLScriptExecuteLSL2::LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size)  	init();  } +LLScriptExecute::~LLScriptExecute() {}  LLScriptExecuteLSL2::~LLScriptExecuteLSL2()  {  	delete[] mBuffer; @@ -4234,19 +4237,16 @@ S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer)  	return 4;  } -BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) + +// Shared code for run_calllib() and run_calllib_two_byte() +BOOL run_calllib_common(U8 *buffer, S32 &offset, const LLUUID &id, U16 arg)  { -	if (b_print) -		printf("[0x%X]\tCALLLIB ", offset); -	offset++; -	U8 arg = safe_instruction_bytestream2byte(buffer, offset); -	if (arg >= (U8)gScriptLibrary.mFunctions.size()) +	if (arg >= gScriptLibrary.mFunctions.size())  	{  		set_fault(buffer, LSRF_BOUND_CHECK_ERROR);  		return FALSE;  	} -	if (b_print) -		printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg].mName); +	LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];  	// pull out the arguments and the return values  	LLScriptLibData	*arguments = NULL; @@ -4254,14 +4254,14 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  	S32 i, number; -	if (gScriptLibrary.mFunctions[arg].mReturnType) +	if (function.mReturnType)  	{  		returnvalue = new LLScriptLibData;  	} -	if (gScriptLibrary.mFunctions[arg].mArgs) +	if (function.mArgs)  	{ -		number = (S32)strlen(gScriptLibrary.mFunctions[arg].mArgs);		/*Flawfinder: ignore*/ +		number = (S32)strlen(function.mArgs);		//Flawfinder: ignore  		arguments = new LLScriptLibData[number];  	}  	else @@ -4271,23 +4271,18 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  	for (i = number - 1; i >= 0; i--)  	{ -		lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg].mArgs[i]); +		lscript_pop_variable(&arguments[i], buffer, function.mArgs[i]);  	} -	if (b_print) -	{ -		printf("See LSLTipText_%s in strings.xml for usage\n", gScriptLibrary.mFunctions[arg].mName); -	} +	// Actually execute the function call +	function.mExecFunc(returnvalue, arguments, id); -	{ -		gScriptLibrary.mFunctions[arg].mExecFunc(returnvalue, arguments, id); -	} -	add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg].mEnergyUse); -	add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg].mSleepTime); +	add_register_fp(buffer, LREG_ESR, -(function.mEnergyUse)); +	add_register_fp(buffer, LREG_SLR, function.mSleepTime);  	if (returnvalue)  	{ -		returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg].mReturnType); +		returnvalue->mType = char2type(*function.mReturnType);  		lscript_push_return_variable(returnvalue, buffer);  	} @@ -4304,71 +4299,32 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  } -BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) +BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  { -	if (b_print) -		printf("[0x%X]\tCALLLIB ", offset);  	offset++; -	U16 arg = safe_instruction_bytestream2u16(buffer, offset); -	if (arg >= (U16)gScriptLibrary.mFunctions.size()) +	U16 arg = (U16) safe_instruction_bytestream2byte(buffer, offset); +	if (b_print && +		arg < gScriptLibrary.mFunctions.size())  	{ -		set_fault(buffer, LSRF_BOUND_CHECK_ERROR); -		return FALSE; -	} -	if (b_print) -		printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg].mName); - -	// pull out the arguments and the return values -	LLScriptLibData	*arguments = NULL; -	LLScriptLibData	*returnvalue = NULL; - -	S32 i, number; - -	if (gScriptLibrary.mFunctions[arg].mReturnType) -	{ -		returnvalue = new LLScriptLibData; -	} - -	if (gScriptLibrary.mFunctions[arg].mArgs) -	{ -		number = (S32)strlen(gScriptLibrary.mFunctions[arg].mArgs);		/*Flawfinder: ignore*/ -		arguments = new LLScriptLibData[number]; -	} -	else -	{ -		number = 0; -	} - -	for (i = number - 1; i >= 0; i--) -	{ -		lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg].mArgs[i]); -	} - -	if (b_print) -	{ -		printf("See LSLTipText_%s in strings.xml for usage\n", gScriptLibrary.mFunctions[arg].mName); -	} - -	{ -		gScriptLibrary.mFunctions[arg].mExecFunc(returnvalue, arguments, id); +		printf("[0x%X]\tCALLLIB ", offset); +		LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg]; +		printf("%d (%s)\n", (U32)arg, function.mName); +		//printf("%s\n", function.mDesc);  	} -	add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg].mEnergyUse); -	add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg].mSleepTime); +	return run_calllib_common(buffer, offset, id, arg); +} -	if (returnvalue) +BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) +{ +	offset++; +	U16 arg = safe_instruction_bytestream2u16(buffer, offset); +	if (b_print && +		arg < gScriptLibrary.mFunctions.size())  	{ -		returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg].mReturnType); -		lscript_push_return_variable(returnvalue, buffer); +		printf("[0x%X]\tCALLLIB ", (offset-1)); +		LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg]; +		printf("%d (%s)\n", (U32)arg, function.mName); +		//printf("%s\n", function.mDesc);  	} - -	delete [] arguments; -	delete returnvalue; - -	// reset the BP after calling the library files -	S32 bp = lscript_pop_int(buffer); -	set_bp(buffer, bp); - -	// pop off the spot for the instruction pointer -	lscript_poparg(buffer, 4); -	return FALSE; +	return run_calllib_common(buffer, offset, id, arg);  } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 14a37981a6..e0ca0a760f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -187,6 +187,7 @@ set(viewer_SOURCE_FILES      llfloaternotificationsconsole.cpp      llfloateropenobject.cpp      llfloaterparcel.cpp +    llfloaterpay.cpp      llfloaterperms.cpp      llfloaterpostcard.cpp      llfloaterpostprocess.cpp @@ -218,7 +219,6 @@ set(viewer_SOURCE_FILES      llfollowcam.cpp      llfriendcard.cpp      llgesturemgr.cpp -    llgivemoney.cpp      llglsandbox.cpp      llgroupactions.cpp      llgrouplist.cpp @@ -264,8 +264,7 @@ set(viewer_SOURCE_FILES      llmaniptranslate.cpp      llmapresponders.cpp      llmediactrl.cpp -    llmediadataresponder.cpp -    llmediadatafetcher.cpp +    llmediadataclient.cpp      llmediaremotectrl.cpp      llmemoryview.cpp      llmenucommands.cpp @@ -659,6 +658,7 @@ set(viewer_HEADER_FILES      llfloaternotificationsconsole.h      llfloateropenobject.h      llfloaterparcel.h +    llfloaterpay.h      llfloaterpostcard.h      llfloaterpostprocess.h      llfloaterpreference.h @@ -691,7 +691,6 @@ set(viewer_HEADER_FILES      llfollowcam.h      llfriendcard.h      llgesturemgr.h -    llgivemoney.h      llgroupactions.h      llgrouplist.h      llgroupmgr.h @@ -735,8 +734,7 @@ set(viewer_HEADER_FILES      llmanipscale.h      llmaniptranslate.h      llmapresponders.h -    llmediadataresponder.h -    llmediadatafetcher.h +    llmediadataclient.h      llmediaremotectrl.h      llmemoryview.h      llmenucommands.h @@ -1105,14 +1103,10 @@ if (WINDOWS)          res/ll_icon.BMP          res/ll_icon.ico          res/resource.h -        res/toolbuy.cur -        res/toolopen.cur -        res/toolpay.cur          res/toolpickobject.cur          res/toolpickobject2.cur          res/toolpickobject3.cur          res/toolpipette.cur -        res/toolsit.cur          )      set_source_files_properties(${viewer_RESOURCE_FILES} @@ -1546,6 +1540,7 @@ include(LLAddBuildTest)  SET(viewer_TEST_SOURCE_FILES    llagentaccess.cpp    lldateutil.cpp +  llmediadataclient.cpp    llviewerhelputil.cpp    )  set_source_files_properties( @@ -1563,6 +1558,7 @@ set(test_libs    ${LLVFS_LIBRARIES}    ${LLMATH_LIBRARIES}    ${LLCOMMON_LIBRARIES}  +  ${GOOGLEMOCK_LIBRARIES}    )  LL_ADD_INTEGRATION_TEST(llcapabilitylistener  diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 735424c647..0e685c818a 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 2.0.0.0"; -CFBundleGetInfoString = "Second Life version 2.0.0.0, Copyright 2004-2009 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 2.0.0.2639"; +CFBundleGetInfoString = "Second Life version 2.0.0.2639, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 7264044d37..0c1d6ea105 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>2.0.0.0</string> +	<string>2.0.0.2639</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index a49ccb77b4..0524834747 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -25,6 +25,7 @@  							<string>AppCache</string>  							<string>Window</string>  							<string>RenderInit</string> +							<string>MediaOnAPrim</string>  						</array>  				</map>  				<map> @@ -40,7 +41,6 @@  						</array>  					<key>tags</key>  						<array> -              <string>ShaderLoading</string>  						</array>  				</map>  			</array> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94a5f5c52b..dc0e5ffa1d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5294,7 +5294,18 @@        <key>Value</key>  	  <integer>13</integer>      </map> -    <key>PrimMediaFetchQueueDelay</key> +    <key>PrimMediaMaxRetries</key> +    <map> +      <key>Comment</key> +      <string>Maximum number of retries for media queries.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>U32</string> +      <key>Value</key> +      <integer>4</integer> +    </map> +    <key>PrimMediaRequestQueueDelay</key>      <map>        <key>Comment</key>        <string>Timer delay for fetching media from the queue (in seconds).</string> @@ -6117,6 +6128,18 @@      <real>1.0</real>    </map> +  <key>RenderHighlightEnable</key> +  <map> +    <key>Comment</key> +    <string>Show glow effect when hovering on interactive objects.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +    <key>RenderHighlightFadeTime</key>    <map>      <key>Comment</key> diff --git a/indra/newview/character/avatar_eye.llm b/indra/newview/character/avatar_eye.llm Binary files differnew file mode 100644 index 0000000000..8c6e74e1de --- /dev/null +++ b/indra/newview/character/avatar_eye.llm diff --git a/indra/newview/character/avatar_eye_1.llm b/indra/newview/character/avatar_eye_1.llm Binary files differnew file mode 100644 index 0000000000..7a3b0d6f28 --- /dev/null +++ b/indra/newview/character/avatar_eye_1.llm diff --git a/indra/newview/character/avatar_eyelashes.llm b/indra/newview/character/avatar_eyelashes.llm Binary files differnew file mode 100644 index 0000000000..99995b5758 --- /dev/null +++ b/indra/newview/character/avatar_eyelashes.llm diff --git a/indra/newview/character/avatar_hair.llm b/indra/newview/character/avatar_hair.llm Binary files differnew file mode 100644 index 0000000000..df99de8db7 --- /dev/null +++ b/indra/newview/character/avatar_hair.llm diff --git a/indra/newview/character/avatar_hair_1.llm b/indra/newview/character/avatar_hair_1.llm Binary files differnew file mode 100644 index 0000000000..6de31fdc23 --- /dev/null +++ b/indra/newview/character/avatar_hair_1.llm diff --git a/indra/newview/character/avatar_hair_2.llm b/indra/newview/character/avatar_hair_2.llm Binary files differnew file mode 100644 index 0000000000..47d02ba9ce --- /dev/null +++ b/indra/newview/character/avatar_hair_2.llm diff --git a/indra/newview/character/avatar_hair_3.llm b/indra/newview/character/avatar_hair_3.llm Binary files differnew file mode 100644 index 0000000000..107f9e2a53 --- /dev/null +++ b/indra/newview/character/avatar_hair_3.llm diff --git a/indra/newview/character/avatar_hair_4.llm b/indra/newview/character/avatar_hair_4.llm Binary files differnew file mode 100644 index 0000000000..1b9a12a0ca --- /dev/null +++ b/indra/newview/character/avatar_hair_4.llm diff --git a/indra/newview/character/avatar_hair_5.llm b/indra/newview/character/avatar_hair_5.llm Binary files differnew file mode 100644 index 0000000000..1b9a12a0ca --- /dev/null +++ b/indra/newview/character/avatar_hair_5.llm diff --git a/indra/newview/character/avatar_head.llm b/indra/newview/character/avatar_head.llm Binary files differnew file mode 100644 index 0000000000..8d8b5e0442 --- /dev/null +++ b/indra/newview/character/avatar_head.llm diff --git a/indra/newview/character/avatar_head_1.llm b/indra/newview/character/avatar_head_1.llm Binary files differnew file mode 100644 index 0000000000..26291e6584 --- /dev/null +++ b/indra/newview/character/avatar_head_1.llm diff --git a/indra/newview/character/avatar_head_2.llm b/indra/newview/character/avatar_head_2.llm Binary files differnew file mode 100644 index 0000000000..c2b808b1a6 --- /dev/null +++ b/indra/newview/character/avatar_head_2.llm diff --git a/indra/newview/character/avatar_head_3.llm b/indra/newview/character/avatar_head_3.llm Binary files differnew file mode 100644 index 0000000000..a0676b1f1c --- /dev/null +++ b/indra/newview/character/avatar_head_3.llm diff --git a/indra/newview/character/avatar_head_4.llm b/indra/newview/character/avatar_head_4.llm Binary files differnew file mode 100644 index 0000000000..5035585770 --- /dev/null +++ b/indra/newview/character/avatar_head_4.llm diff --git a/indra/newview/character/avatar_lower_body.llm b/indra/newview/character/avatar_lower_body.llm Binary files differnew file mode 100644 index 0000000000..0420899739 --- /dev/null +++ b/indra/newview/character/avatar_lower_body.llm diff --git a/indra/newview/character/avatar_lower_body_1.llm b/indra/newview/character/avatar_lower_body_1.llm Binary files differnew file mode 100644 index 0000000000..1394eb848b --- /dev/null +++ b/indra/newview/character/avatar_lower_body_1.llm diff --git a/indra/newview/character/avatar_lower_body_2.llm b/indra/newview/character/avatar_lower_body_2.llm Binary files differnew file mode 100644 index 0000000000..0da9c1249e --- /dev/null +++ b/indra/newview/character/avatar_lower_body_2.llm diff --git a/indra/newview/character/avatar_lower_body_3.llm b/indra/newview/character/avatar_lower_body_3.llm Binary files differnew file mode 100644 index 0000000000..f3c49a1568 --- /dev/null +++ b/indra/newview/character/avatar_lower_body_3.llm diff --git a/indra/newview/character/avatar_lower_body_4.llm b/indra/newview/character/avatar_lower_body_4.llm Binary files differnew file mode 100644 index 0000000000..e71721063e --- /dev/null +++ b/indra/newview/character/avatar_lower_body_4.llm diff --git a/indra/newview/character/avatar_skirt.llm b/indra/newview/character/avatar_skirt.llm Binary files differnew file mode 100644 index 0000000000..08ce3d1700 --- /dev/null +++ b/indra/newview/character/avatar_skirt.llm diff --git a/indra/newview/character/avatar_skirt_1.llm b/indra/newview/character/avatar_skirt_1.llm Binary files differnew file mode 100644 index 0000000000..88076c321f --- /dev/null +++ b/indra/newview/character/avatar_skirt_1.llm diff --git a/indra/newview/character/avatar_skirt_2.llm b/indra/newview/character/avatar_skirt_2.llm Binary files differnew file mode 100644 index 0000000000..73b3effbc6 --- /dev/null +++ b/indra/newview/character/avatar_skirt_2.llm diff --git a/indra/newview/character/avatar_skirt_3.llm b/indra/newview/character/avatar_skirt_3.llm Binary files differnew file mode 100644 index 0000000000..ded546fdea --- /dev/null +++ b/indra/newview/character/avatar_skirt_3.llm diff --git a/indra/newview/character/avatar_skirt_4.llm b/indra/newview/character/avatar_skirt_4.llm Binary files differnew file mode 100644 index 0000000000..b9d5cb945e --- /dev/null +++ b/indra/newview/character/avatar_skirt_4.llm diff --git a/indra/newview/character/avatar_upper_body.llm b/indra/newview/character/avatar_upper_body.llm Binary files differnew file mode 100644 index 0000000000..da7d990540 --- /dev/null +++ b/indra/newview/character/avatar_upper_body.llm diff --git a/indra/newview/character/avatar_upper_body_1.llm b/indra/newview/character/avatar_upper_body_1.llm Binary files differnew file mode 100644 index 0000000000..31e104cc20 --- /dev/null +++ b/indra/newview/character/avatar_upper_body_1.llm diff --git a/indra/newview/character/avatar_upper_body_2.llm b/indra/newview/character/avatar_upper_body_2.llm Binary files differnew file mode 100644 index 0000000000..c1f4199b9c --- /dev/null +++ b/indra/newview/character/avatar_upper_body_2.llm diff --git a/indra/newview/character/avatar_upper_body_3.llm b/indra/newview/character/avatar_upper_body_3.llm Binary files differnew file mode 100644 index 0000000000..9e89ed8b3e --- /dev/null +++ b/indra/newview/character/avatar_upper_body_3.llm diff --git a/indra/newview/character/avatar_upper_body_4.llm b/indra/newview/character/avatar_upper_body_4.llm Binary files differnew file mode 100644 index 0000000000..ec836d1dc3 --- /dev/null +++ b/indra/newview/character/avatar_upper_body_4.llm diff --git a/indra/newview/character/blush_alpha.tga b/indra/newview/character/blush_alpha.tga Binary files differnew file mode 100644 index 0000000000..05be7e7e3d --- /dev/null +++ b/indra/newview/character/blush_alpha.tga diff --git a/indra/newview/character/body_skingrain.tga b/indra/newview/character/body_skingrain.tga Binary files differnew file mode 100644 index 0000000000..7264baac14 --- /dev/null +++ b/indra/newview/character/body_skingrain.tga diff --git a/indra/newview/character/bodyfreckles_alpha.tga b/indra/newview/character/bodyfreckles_alpha.tga Binary files differnew file mode 100644 index 0000000000..d30ab3d122 --- /dev/null +++ b/indra/newview/character/bodyfreckles_alpha.tga diff --git a/indra/newview/character/bump_face_wrinkles.tga b/indra/newview/character/bump_face_wrinkles.tga Binary files differnew file mode 100644 index 0000000000..54bf7a55be --- /dev/null +++ b/indra/newview/character/bump_face_wrinkles.tga diff --git a/indra/newview/character/bump_head_base.tga b/indra/newview/character/bump_head_base.tga Binary files differnew file mode 100644 index 0000000000..fa3568573a --- /dev/null +++ b/indra/newview/character/bump_head_base.tga diff --git a/indra/newview/character/bump_lowerbody_base.tga b/indra/newview/character/bump_lowerbody_base.tga Binary files differnew file mode 100644 index 0000000000..498ea3c721 --- /dev/null +++ b/indra/newview/character/bump_lowerbody_base.tga diff --git a/indra/newview/character/bump_pants_wrinkles.tga b/indra/newview/character/bump_pants_wrinkles.tga Binary files differnew file mode 100644 index 0000000000..cca72415e8 --- /dev/null +++ b/indra/newview/character/bump_pants_wrinkles.tga diff --git a/indra/newview/character/bump_shirt_wrinkles.tga b/indra/newview/character/bump_shirt_wrinkles.tga Binary files differnew file mode 100644 index 0000000000..9e0d757a48 --- /dev/null +++ b/indra/newview/character/bump_shirt_wrinkles.tga diff --git a/indra/newview/character/bump_upperbody_base.tga b/indra/newview/character/bump_upperbody_base.tga Binary files differnew file mode 100644 index 0000000000..e57d6352e6 --- /dev/null +++ b/indra/newview/character/bump_upperbody_base.tga diff --git a/indra/newview/character/eyebrows_alpha.tga b/indra/newview/character/eyebrows_alpha.tga Binary files differnew file mode 100644 index 0000000000..c363e482e1 --- /dev/null +++ b/indra/newview/character/eyebrows_alpha.tga diff --git a/indra/newview/character/eyeliner_alpha.tga b/indra/newview/character/eyeliner_alpha.tga Binary files differnew file mode 100644 index 0000000000..1611eb3355 --- /dev/null +++ b/indra/newview/character/eyeliner_alpha.tga diff --git a/indra/newview/character/eyeshadow_inner_alpha.tga b/indra/newview/character/eyeshadow_inner_alpha.tga Binary files differnew file mode 100644 index 0000000000..37d7919395 --- /dev/null +++ b/indra/newview/character/eyeshadow_inner_alpha.tga diff --git a/indra/newview/character/eyeshadow_outer_alpha.tga b/indra/newview/character/eyeshadow_outer_alpha.tga Binary files differnew file mode 100644 index 0000000000..00eef9d9f7 --- /dev/null +++ b/indra/newview/character/eyeshadow_outer_alpha.tga diff --git a/indra/newview/character/eyewhite.tga b/indra/newview/character/eyewhite.tga Binary files differnew file mode 100644 index 0000000000..a720496988 --- /dev/null +++ b/indra/newview/character/eyewhite.tga diff --git a/indra/newview/character/facehair_chincurtains_alpha.tga b/indra/newview/character/facehair_chincurtains_alpha.tga Binary files differnew file mode 100644 index 0000000000..b10397063c --- /dev/null +++ b/indra/newview/character/facehair_chincurtains_alpha.tga diff --git a/indra/newview/character/facehair_moustache_alpha.tga b/indra/newview/character/facehair_moustache_alpha.tga Binary files differnew file mode 100644 index 0000000000..4068c4f2b1 --- /dev/null +++ b/indra/newview/character/facehair_moustache_alpha.tga diff --git a/indra/newview/character/facehair_sideburns_alpha.tga b/indra/newview/character/facehair_sideburns_alpha.tga Binary files differnew file mode 100644 index 0000000000..acddc2d9bd --- /dev/null +++ b/indra/newview/character/facehair_sideburns_alpha.tga diff --git a/indra/newview/character/facehair_soulpatch_alpha.tga b/indra/newview/character/facehair_soulpatch_alpha.tga Binary files differnew file mode 100644 index 0000000000..687091a29f --- /dev/null +++ b/indra/newview/character/facehair_soulpatch_alpha.tga diff --git a/indra/newview/character/freckles_alpha.tga b/indra/newview/character/freckles_alpha.tga Binary files differnew file mode 100644 index 0000000000..a9a4ec0735 --- /dev/null +++ b/indra/newview/character/freckles_alpha.tga diff --git a/indra/newview/character/glove_length_alpha.tga b/indra/newview/character/glove_length_alpha.tga Binary files differnew file mode 100644 index 0000000000..db89ad57e7 --- /dev/null +++ b/indra/newview/character/glove_length_alpha.tga diff --git a/indra/newview/character/gloves_fingers_alpha.tga b/indra/newview/character/gloves_fingers_alpha.tga Binary files differnew file mode 100644 index 0000000000..dba2eec277 --- /dev/null +++ b/indra/newview/character/gloves_fingers_alpha.tga diff --git a/indra/newview/character/head_alpha.tga b/indra/newview/character/head_alpha.tga Binary files differnew file mode 100644 index 0000000000..8164525353 --- /dev/null +++ b/indra/newview/character/head_alpha.tga diff --git a/indra/newview/character/head_color.tga b/indra/newview/character/head_color.tga Binary files differnew file mode 100644 index 0000000000..74b1b3078b --- /dev/null +++ b/indra/newview/character/head_color.tga diff --git a/indra/newview/character/head_hair.tga b/indra/newview/character/head_hair.tga Binary files differnew file mode 100644 index 0000000000..5321f35204 --- /dev/null +++ b/indra/newview/character/head_hair.tga diff --git a/indra/newview/character/head_highlights_alpha.tga b/indra/newview/character/head_highlights_alpha.tga Binary files differnew file mode 100644 index 0000000000..8dc5239f97 --- /dev/null +++ b/indra/newview/character/head_highlights_alpha.tga diff --git a/indra/newview/character/head_shading_alpha.tga b/indra/newview/character/head_shading_alpha.tga Binary files differnew file mode 100644 index 0000000000..e8ea490109 --- /dev/null +++ b/indra/newview/character/head_shading_alpha.tga diff --git a/indra/newview/character/head_skingrain.tga b/indra/newview/character/head_skingrain.tga Binary files differnew file mode 100644 index 0000000000..b42dee0809 --- /dev/null +++ b/indra/newview/character/head_skingrain.tga diff --git a/indra/newview/character/jacket_length_lower_alpha.tga b/indra/newview/character/jacket_length_lower_alpha.tga Binary files differnew file mode 100644 index 0000000000..722bc192a8 --- /dev/null +++ b/indra/newview/character/jacket_length_lower_alpha.tga diff --git a/indra/newview/character/jacket_length_upper_alpha.tga b/indra/newview/character/jacket_length_upper_alpha.tga Binary files differnew file mode 100644 index 0000000000..e9db7e7b1f --- /dev/null +++ b/indra/newview/character/jacket_length_upper_alpha.tga diff --git a/indra/newview/character/jacket_open_lower_alpha.tga b/indra/newview/character/jacket_open_lower_alpha.tga Binary files differnew file mode 100644 index 0000000000..db0c2fb0e3 --- /dev/null +++ b/indra/newview/character/jacket_open_lower_alpha.tga diff --git a/indra/newview/character/jacket_open_upper_alpha.tga b/indra/newview/character/jacket_open_upper_alpha.tga Binary files differnew file mode 100644 index 0000000000..71b8a0b805 --- /dev/null +++ b/indra/newview/character/jacket_open_upper_alpha.tga diff --git a/indra/newview/character/lipgloss_alpha.tga b/indra/newview/character/lipgloss_alpha.tga Binary files differnew file mode 100644 index 0000000000..78ceecaf85 --- /dev/null +++ b/indra/newview/character/lipgloss_alpha.tga diff --git a/indra/newview/character/lips_mask.tga b/indra/newview/character/lips_mask.tga Binary files differnew file mode 100644 index 0000000000..ae1401c006 --- /dev/null +++ b/indra/newview/character/lips_mask.tga diff --git a/indra/newview/character/lipstick_alpha.tga b/indra/newview/character/lipstick_alpha.tga Binary files differnew file mode 100644 index 0000000000..2795f1bd40 --- /dev/null +++ b/indra/newview/character/lipstick_alpha.tga diff --git a/indra/newview/character/lowerbody_color.tga b/indra/newview/character/lowerbody_color.tga Binary files differnew file mode 100644 index 0000000000..a63aa12fca --- /dev/null +++ b/indra/newview/character/lowerbody_color.tga diff --git a/indra/newview/character/lowerbody_highlights_alpha.tga b/indra/newview/character/lowerbody_highlights_alpha.tga Binary files differnew file mode 100644 index 0000000000..ae3413ac8b --- /dev/null +++ b/indra/newview/character/lowerbody_highlights_alpha.tga diff --git a/indra/newview/character/lowerbody_shading_alpha.tga b/indra/newview/character/lowerbody_shading_alpha.tga Binary files differnew file mode 100644 index 0000000000..0242663a7d --- /dev/null +++ b/indra/newview/character/lowerbody_shading_alpha.tga diff --git a/indra/newview/character/nailpolish_alpha.tga b/indra/newview/character/nailpolish_alpha.tga Binary files differnew file mode 100644 index 0000000000..91af762902 --- /dev/null +++ b/indra/newview/character/nailpolish_alpha.tga diff --git a/indra/newview/character/pants_length_alpha.tga b/indra/newview/character/pants_length_alpha.tga Binary files differnew file mode 100644 index 0000000000..3c4f21c0f2 --- /dev/null +++ b/indra/newview/character/pants_length_alpha.tga diff --git a/indra/newview/character/pants_waist_alpha.tga b/indra/newview/character/pants_waist_alpha.tga Binary files differnew file mode 100644 index 0000000000..35658c0896 --- /dev/null +++ b/indra/newview/character/pants_waist_alpha.tga diff --git a/indra/newview/character/rosyface_alpha.tga b/indra/newview/character/rosyface_alpha.tga Binary files differnew file mode 100644 index 0000000000..a0c8513da2 --- /dev/null +++ b/indra/newview/character/rosyface_alpha.tga diff --git a/indra/newview/character/rouge_alpha.tga b/indra/newview/character/rouge_alpha.tga Binary files differnew file mode 100644 index 0000000000..a0c8513da2 --- /dev/null +++ b/indra/newview/character/rouge_alpha.tga diff --git a/indra/newview/character/shirt_bottom_alpha.tga b/indra/newview/character/shirt_bottom_alpha.tga Binary files differnew file mode 100644 index 0000000000..7cce03dbe0 --- /dev/null +++ b/indra/newview/character/shirt_bottom_alpha.tga diff --git a/indra/newview/character/shirt_collar_alpha.tga b/indra/newview/character/shirt_collar_alpha.tga Binary files differnew file mode 100644 index 0000000000..f55f635473 --- /dev/null +++ b/indra/newview/character/shirt_collar_alpha.tga diff --git a/indra/newview/character/shirt_collar_back_alpha.tga b/indra/newview/character/shirt_collar_back_alpha.tga Binary files differnew file mode 100644 index 0000000000..43a6453107 --- /dev/null +++ b/indra/newview/character/shirt_collar_back_alpha.tga diff --git a/indra/newview/character/shirt_sleeve_alpha.tga b/indra/newview/character/shirt_sleeve_alpha.tga Binary files differnew file mode 100644 index 0000000000..e3b18f4fc6 --- /dev/null +++ b/indra/newview/character/shirt_sleeve_alpha.tga diff --git a/indra/newview/character/shoe_height_alpha.tga b/indra/newview/character/shoe_height_alpha.tga Binary files differnew file mode 100644 index 0000000000..d08dd750f3 --- /dev/null +++ b/indra/newview/character/shoe_height_alpha.tga diff --git a/indra/newview/character/skirt_length_alpha.tga b/indra/newview/character/skirt_length_alpha.tga Binary files differnew file mode 100644 index 0000000000..c86799469d --- /dev/null +++ b/indra/newview/character/skirt_length_alpha.tga diff --git a/indra/newview/character/skirt_slit_back_alpha.tga b/indra/newview/character/skirt_slit_back_alpha.tga Binary files differnew file mode 100644 index 0000000000..0e49688b14 --- /dev/null +++ b/indra/newview/character/skirt_slit_back_alpha.tga diff --git a/indra/newview/character/skirt_slit_front_alpha.tga b/indra/newview/character/skirt_slit_front_alpha.tga Binary files differnew file mode 100644 index 0000000000..888bbf71a1 --- /dev/null +++ b/indra/newview/character/skirt_slit_front_alpha.tga diff --git a/indra/newview/character/skirt_slit_left_alpha.tga b/indra/newview/character/skirt_slit_left_alpha.tga Binary files differnew file mode 100644 index 0000000000..210feac1ea --- /dev/null +++ b/indra/newview/character/skirt_slit_left_alpha.tga diff --git a/indra/newview/character/skirt_slit_right_alpha.tga b/indra/newview/character/skirt_slit_right_alpha.tga Binary files differnew file mode 100644 index 0000000000..ce11c64bf6 --- /dev/null +++ b/indra/newview/character/skirt_slit_right_alpha.tga diff --git a/indra/newview/character/underpants_trial_female.tga b/indra/newview/character/underpants_trial_female.tga Binary files differnew file mode 100644 index 0000000000..96bf732351 --- /dev/null +++ b/indra/newview/character/underpants_trial_female.tga diff --git a/indra/newview/character/underpants_trial_male.tga b/indra/newview/character/underpants_trial_male.tga Binary files differnew file mode 100644 index 0000000000..095695ca1c --- /dev/null +++ b/indra/newview/character/underpants_trial_male.tga diff --git a/indra/newview/character/undershirt_trial_female.tga b/indra/newview/character/undershirt_trial_female.tga Binary files differnew file mode 100644 index 0000000000..e17a309531 --- /dev/null +++ b/indra/newview/character/undershirt_trial_female.tga diff --git a/indra/newview/character/upperbody_color.tga b/indra/newview/character/upperbody_color.tga Binary files differnew file mode 100644 index 0000000000..85fcc41142 --- /dev/null +++ b/indra/newview/character/upperbody_color.tga diff --git a/indra/newview/character/upperbody_highlights_alpha.tga b/indra/newview/character/upperbody_highlights_alpha.tga Binary files differnew file mode 100644 index 0000000000..2d8102b583 --- /dev/null +++ b/indra/newview/character/upperbody_highlights_alpha.tga diff --git a/indra/newview/character/upperbody_shading_alpha.tga b/indra/newview/character/upperbody_shading_alpha.tga Binary files differnew file mode 100644 index 0000000000..b420506b3e --- /dev/null +++ b/indra/newview/character/upperbody_shading_alpha.tga diff --git a/indra/newview/character/upperbodyfreckles_alpha.tga b/indra/newview/character/upperbodyfreckles_alpha.tga Binary files differnew file mode 100644 index 0000000000..76c7ce8849 --- /dev/null +++ b/indra/newview/character/upperbodyfreckles_alpha.tga diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif Binary files differdeleted file mode 100644 index 39d89987aa..0000000000 --- a/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif +++ /dev/null diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif Binary files differdeleted file mode 100644 index 864c8dee7a..0000000000 --- a/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif +++ /dev/null diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif Binary files differdeleted file mode 100644 index d6d835a90b..0000000000 --- a/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif +++ /dev/null diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 92b2768f39..2b5e2369bb 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -48,7 +48,7 @@  #include "llfloatergroupinvite.h"  #include "llfloatergroups.h"  #include "llfloaterreg.h" -#include "llgivemoney.h" +#include "llfloaterpay.h"  #include "llinventorymodel.h"	// for gInventory.findCategoryUUIDForType  #include "llimview.h"			// for gIMMgr  #include "llmutelist.h" @@ -306,7 +306,7 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response,  		gAgent.clearBusy();  	} -	LLFloaterPay::payDirectly(&give_money, avatar_id, /*is_group=*/FALSE); +	LLFloaterPayUtil::payDirectly(&give_money, avatar_id, /*is_group=*/false);  	return false;  } diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 28c124d1c6..2467356018 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -45,7 +45,7 @@ public:  	:	LLTextSegment(start, end),  		mEditor(editor),  		mStyle(style), -		mMoreText(more_text) +		mExpanderLabel(more_text)  	{}  	/*virtual*/ S32		getWidth(S32 first_char, S32 num_chars) const  @@ -61,7 +61,15 @@ public:  	/*virtual*/ F32		draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)  	{  		F32 right_x; -		mStyle->getFont()->renderUTF8(mMoreText, start, draw_rect.mRight, draw_rect.mTop, mStyle->getColor(), LLFontGL::RIGHT, LLFontGL::TOP, 0, mStyle->getShadowType(), end - start, draw_rect.getWidth(), &right_x, mEditor.getUseEllipses()); +		mStyle->getFont()->renderUTF8(mExpanderLabel, start,  +									draw_rect.mRight, draw_rect.mTop,  +									mStyle->getColor(),  +									LLFontGL::RIGHT, LLFontGL::TOP,  +									0,  +									mStyle->getShadowType(),  +									end - start, draw_rect.getWidth(),  +									&right_x,  +									mEditor.getUseEllipses());  		return right_x;  	}  	/*virtual*/ S32		getMaxHeight() const { return llceil(mStyle->getFont()->getLineHeight()); } @@ -75,14 +83,17 @@ public:  private:  	LLTextBase& mEditor;  	LLStyleSP	mStyle; -	std::string	mMoreText; +	std::string	mExpanderLabel;  }; - +LLExpandableTextBox::LLTextBoxEx::Params::Params() +:	more_label("more_label") +{}  LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p)  :	LLTextBox(p), -	mExpanded(false) +	mExpanderLabel(p.more_label), +	mExpanderVisible(false)  {  	setIsChrome(TRUE); @@ -106,6 +117,9 @@ void LLExpandableTextBox::LLTextBoxEx::setValue(const LLSD& value)  {  	LLTextBox::setValue(value); +	// text contents have changed, segments are cleared out +	// so hide the expander and determine if we need it +	//mExpanderVisible = false;  	if (getTextPixelHeight() > getRect().getHeight())  	{  		showExpandText(); @@ -119,7 +133,7 @@ void LLExpandableTextBox::LLTextBoxEx::setValue(const LLSD& value)  void LLExpandableTextBox::LLTextBoxEx::showExpandText()  { -	if (!mExpanded) +	if (!mExpanderVisible)  	{  		// get fully visible lines  		std::pair<S32, S32> visible_lines = getVisibleLines(true); @@ -129,9 +143,9 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText()  		expander_style.font.name.setIfNotProvided(LLFontGL::nameFromFont(expander_style.font));  		expander_style.font.style = "UNDERLINE";  		expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); -		LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, "More", *this); +		LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this);  		insertSegment(expanderp); -		mExpanded = true; +		mExpanderVisible = true;  	}  } @@ -139,14 +153,14 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText()  //NOTE: obliterates existing styles (including hyperlinks)  void LLExpandableTextBox::LLTextBoxEx::hideExpandText()   {  -	if (mExpanded) +	if (mExpanderVisible)  	{  		// this will overwrite the expander segment and all text styling with a single style  		LLNormalTextSegment* segmentp = new LLNormalTextSegment(  											new LLStyle(getDefaultStyle()), 0, getLength() + 1, *this);  		insertSegment(segmentp); -		mExpanded = false; +		mExpanderVisible = false;  	}  } @@ -275,6 +289,9 @@ S32 LLExpandableTextBox::recalculateTextDelta(S32 text_delta)  void LLExpandableTextBox::expandTextBox()  { +	// hide "more" link, and show full text contents +	mTextBox->hideExpandText(); +  	S32 text_delta = mTextBox->getVerticalTextDelta();  	text_delta += mTextBox->getVPad() * 2 + mScroll->getBorderWidth() * 2;  	// no need to expand diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index b78a4dc674..d6401e224f 100644 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -54,6 +54,8 @@ protected:  	public:  		struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>  		{ +			Mandatory<std::string> more_label; +			Params();  		};  		// adds or removes "More" link as needed @@ -76,11 +78,6 @@ protected:  		 */  		virtual S32 getHPad() { return mHPad; } -	protected: - -		LLTextBoxEx(const Params& p); -		friend class LLUICtrlFactory; -  		/**  		 * Shows "More" link  		 */ @@ -91,9 +88,15 @@ protected:  		 */  		void hideExpandText(); +	protected: + +		LLTextBoxEx(const Params& p); +		friend class LLUICtrlFactory; +  	private: +		std::string mExpanderLabel; -		bool mExpanded; +		bool mExpanderVisible;  	};  public: diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 91b9bcfe72..890d863db7 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -37,20 +37,15 @@  #include "llagent.h"  #include "llfocusmgr.h"  #include "llfloaterreg.h" -#include "llfloaterinventory.h" -#include "llfoldervieweventlistener.h" -#include "llinventorymodel.h"  #include "llviewercontrol.h"  #include "llworld.h"  // Linden libraries -#include "llbutton.h"  #include "lllineeditor.h"  #include "llscrolllistctrl.h"  #include "llscrolllistitem.h"  #include "llscrolllistcell.h"  #include "lltabcontainer.h" -#include "lltextbox.h"  #include "lluictrlfactory.h"  #include "message.h" @@ -117,13 +112,6 @@ BOOL LLFloaterAvatarPicker::postBuild()  	getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("no_results")); -	LLInventoryPanel* inventory_panel = getChild<LLInventoryPanel>("InventoryPanel"); -	inventory_panel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD); -	inventory_panel->setFollowsAll(); -	inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); -	inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD); -	inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::doCallingCardSelectionChange, this, _1, _2)); -	  	getChild<LLTabContainer>("ResidentChooserTabs")->setCommitCallback(  		boost::bind(&LLFloaterAvatarPicker::onTabChanged, this)); @@ -173,11 +161,7 @@ void LLFloaterAvatarPicker::onBtnSelect(void* userdata)  	{  		LLPanel* active_panel = self->childGetVisibleTab("ResidentChooserTabs"); -		if(active_panel == self->getChild<LLPanel>("CallingCardsPanel")) -		{ -			self->mCallback(self->mSelectedInventoryAvatarNames, self->mSelectedInventoryAvatarIDs, self->mCallbackUserdata); -		} -		else if(active_panel == self->getChild<LLPanel>("SearchPanel")) +		if(active_panel == self->getChild<LLPanel>("SearchPanel"))  		{  			std::vector<std::string>	avatar_names;  			std::vector<LLUUID>			avatar_ids; @@ -192,7 +176,6 @@ void LLFloaterAvatarPicker::onBtnSelect(void* userdata)  			self->mCallback(avatar_names, avatar_ids, self->mCallbackUserdata);  		}  	} -	self->getChild<LLInventoryPanel>("InventoryPanel")->setSelection(LLUUID::null, FALSE);  	self->getChild<LLScrollListCtrl>("SearchResults")->deselectAllItems(TRUE);  	self->getChild<LLScrollListCtrl>("NearMe")->deselectAllItems(TRUE);  	if(self->mCloseOnSelect) @@ -235,40 +218,6 @@ void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)  	}  } -// Callback for inventory picker (select from calling cards) -void LLFloaterAvatarPicker::doCallingCardSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action) -{ -	bool panel_active = (childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("CallingCardsPanel")); -	 -	mSelectedInventoryAvatarIDs.clear(); -	mSelectedInventoryAvatarNames.clear(); -	 -	if (panel_active) -	{ -		childSetEnabled("Select", FALSE); -	} - -	std::deque<LLFolderViewItem*>::const_iterator item_it; -	for (item_it = items.begin(); item_it != items.end(); ++item_it) -	{ -		LLFolderViewEventListener* listenerp = (*item_it)->getListener(); -		if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) -		{ -			LLInventoryItem* item = gInventory.getItem(listenerp->getUUID()); -			if (item) -			{ -				mSelectedInventoryAvatarIDs.push_back(item->getCreatorUUID()); -				mSelectedInventoryAvatarNames.push_back(listenerp->getName()); -			} -		} -	} - -	if (panel_active) -	{ -		childSetEnabled("Select", visibleItemsSelected()); -	} -} -  void LLFloaterAvatarPicker::populateNearMe()  {  	BOOL all_loaded = TRUE; @@ -336,10 +285,6 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const  	{  		return getChild<LLScrollListCtrl>("SearchResults")->getFirstSelectedIndex() >= 0;  	} -	else if(active_panel == getChild<LLPanel>("CallingCardsPanel")) -	{ -		return mSelectedInventoryAvatarIDs.size() > 0; -	}  	else if(active_panel == getChild<LLPanel>("NearMePanel"))  	{  		return getChild<LLScrollListCtrl>("NearMe")->getFirstSelectedIndex() >= 0; @@ -349,7 +294,7 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const  void LLFloaterAvatarPicker::find()  { -	const std::string& text = childGetValue("Edit").asString(); +	std::string text = childGetValue("Edit").asString();  	mQueryID.generate(); @@ -375,7 +320,6 @@ void LLFloaterAvatarPicker::find()  void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)  {  	getChild<LLScrollListCtrl>("SearchResults")->setAllowMultipleSelection(allow_multiple); -	getChild<LLInventoryPanel>("InventoryPanel")->setAllowMultiSelect(allow_multiple);  	getChild<LLScrollListCtrl>("NearMe")->setAllowMultipleSelection(allow_multiple);  } diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 63896bef9f..f3b9aefb9c 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -37,7 +37,6 @@  #include <vector> -  class LLFloaterAvatarPicker : public LLFloater  {  public: @@ -57,7 +56,6 @@ public:  	static void processAvatarPickerReply(class LLMessageSystem* msg, void**);  private: -  	static void editKeystroke(class LLLineEditor* caller, void* user_data);  	static void onBtnFind(void* userdata); @@ -68,8 +66,6 @@ private:  	static void onList(class LLUICtrl* ctrl, void* userdata);  		   void onTabChanged(); -		   void doCallingCardSelectionChange(const std::deque<class LLFolderViewItem*> &items, BOOL user_action); -  	void populateNearMe();  	BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected. @@ -79,8 +75,6 @@ private:  	virtual void draw();  	virtual BOOL handleKeyHere(KEY key, MASK mask); -	std::vector<LLUUID>				mSelectedInventoryAvatarIDs; -	std::vector<std::string>		mSelectedInventoryAvatarNames;  	LLUUID				mQueryID;  	BOOL				mResultsReturned;  	BOOL				mNearMeListComplete; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 473d5ce827..9d07362edc 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -74,8 +74,6 @@ BOOL LLFloaterBuy::postBuild()  	// mid-session and the saved rect is off-center.  	center(); -	mCloseSignal.connect(boost::bind(&LLFloaterBuy::onClose, this)); -	  	return TRUE;  } @@ -310,7 +308,8 @@ void LLFloaterBuy::onClickCancel()  	closeFloater();  } -void LLFloaterBuy::onClose() +// virtual +void LLFloaterBuy::onClose(bool app_quitting)  {  	mObjectSelection.clear();  } diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h index 2ec66136b2..ab38e082dc 100644 --- a/indra/newview/llfloaterbuy.h +++ b/indra/newview/llfloaterbuy.h @@ -56,6 +56,7 @@ public:  	~LLFloaterBuy();  	/*virtual*/	BOOL postBuild(); +	/*virtual*/ void onClose(bool app_quitting);  	static void show(const LLSaleInfo& sale_info); @@ -70,7 +71,6 @@ protected:  	void onClickBuy();  	void onClickCancel(); -	void onClose();  private:  	LLSafeHandle<LLObjectSelection>	mObjectSelection; diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp index 6b0b5ed5e0..2e0ae3265e 100644 --- a/indra/newview/llfloaterhelpbrowser.cpp +++ b/indra/newview/llfloaterhelpbrowser.cpp @@ -50,9 +50,6 @@  LLFloaterHelpBrowser::LLFloaterHelpBrowser(const LLSD& key)  	: LLFloater(key)  { -	// really really destroy the help browser when it's closed, it'll be recreated. -	// *TODO: when onClose() is resurrected as a virtual, this bind can go away. -	mCloseSignal.connect(boost::bind(&LLFloaterHelpBrowser::onClose, this));  }  BOOL LLFloaterHelpBrowser::postBuild() @@ -79,8 +76,10 @@ void LLFloaterHelpBrowser::buildURLHistory()  	}  } -void LLFloaterHelpBrowser::onClose() +//virtual +void LLFloaterHelpBrowser::onClose(bool app_quitting)  { +	// really really destroy the help browser when it's closed, it'll be recreated.  	destroy(); // really destroy this dialog on closure, it's relatively heavyweight.  } diff --git a/indra/newview/llfloaterhelpbrowser.h b/indra/newview/llfloaterhelpbrowser.h index 14a276b428..b66a67c4d6 100644 --- a/indra/newview/llfloaterhelpbrowser.h +++ b/indra/newview/llfloaterhelpbrowser.h @@ -47,7 +47,7 @@ class LLFloaterHelpBrowser :  	LLFloaterHelpBrowser(const LLSD& key);  	/*virtual*/ BOOL postBuild(); -	void onClose(); +	/*virtual*/ void onClose(bool app_quitting);  	// inherited from LLViewerMediaObserver  	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp index 9b7f3305e5..5673550fbe 100644 --- a/indra/newview/llfloatermediabrowser.cpp +++ b/indra/newview/llfloatermediabrowser.cpp @@ -156,6 +156,8 @@ std::string LLFloaterMediaBrowser::getSupportURL()  {  	return getString("support_page_url");  } + +//virtual  void LLFloaterMediaBrowser::onClose(bool app_quitting)  {  	//setVisible(FALSE); diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 811cc26efb..aa457de2d8 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -52,7 +52,10 @@ LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key)  	mPanelMediaSettingsGeneral(NULL),  	mPanelMediaSettingsSecurity(NULL),  	mPanelMediaSettingsPermissions(NULL), -	mWaitingToClose( false ) +	mWaitingToClose( false ), +	mIdenticalHasMediaInfo( true ), +	mMultipleMedia(false), +	mMultipleValidMedia(false)  {  //	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_settings.xml");  } @@ -86,8 +89,6 @@ LLFloaterMediaSettings::~LLFloaterMediaSettings()  //  BOOL LLFloaterMediaSettings::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLFloaterMediaSettings::onClose, this)); -  	mApplyBtn = getChild<LLButton>("Apply");  	mApplyBtn->setClickedCallback(onBtnApply, this); @@ -153,29 +154,29 @@ void LLFloaterMediaSettings::apply()  }  //////////////////////////////////////////////////////////////////////////////// -void LLFloaterMediaSettings::onClose() +void LLFloaterMediaSettings::onClose(bool app_quitting)  {  	if(mPanelMediaSettingsGeneral)  	{ -		mPanelMediaSettingsGeneral->onClose(); +		mPanelMediaSettingsGeneral->onClose(app_quitting);  	}  	LLFloaterReg::hideInstance("whitelist_entry");  }  ////////////////////////////////////////////////////////////////////////////////  //static  -void LLFloaterMediaSettings::initValues( const LLSD& media_settings ) +void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable )  { -	sInstance->clearValues(); +	sInstance->clearValues(editable);  	// update all panels with values from simulator  	sInstance->mPanelMediaSettingsGeneral-> -		initValues( sInstance->mPanelMediaSettingsGeneral, media_settings ); +		initValues( sInstance->mPanelMediaSettingsGeneral, media_settings, editable );  	sInstance->mPanelMediaSettingsSecurity-> -		initValues( sInstance->mPanelMediaSettingsSecurity, media_settings ); +		initValues( sInstance->mPanelMediaSettingsSecurity, media_settings, editable );  	sInstance->mPanelMediaSettingsPermissions-> -		initValues( sInstance->mPanelMediaSettingsPermissions, media_settings ); +		initValues( sInstance->mPanelMediaSettingsPermissions, media_settings, editable );  } @@ -195,12 +196,12 @@ void LLFloaterMediaSettings::commitFields()  ////////////////////////////////////////////////////////////////////////////////  //static  -void LLFloaterMediaSettings::clearValues() +void LLFloaterMediaSettings::clearValues( bool editable)  {  	// clean up all panels before updating -	sInstance->mPanelMediaSettingsGeneral->clearValues(sInstance->mPanelMediaSettingsGeneral); -	sInstance->mPanelMediaSettingsSecurity->clearValues(sInstance->mPanelMediaSettingsSecurity); -	sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions);	 +	sInstance->mPanelMediaSettingsGeneral	 ->clearValues(sInstance->mPanelMediaSettingsGeneral,  editable); +	sInstance->mPanelMediaSettingsSecurity	 ->clearValues(sInstance->mPanelMediaSettingsSecurity,  editable); +	sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions,  editable);	  } diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index b95c590346..e2683039cc 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -47,14 +47,20 @@ public:  	LLFloaterMediaSettings(const LLSD& key);  	~LLFloaterMediaSettings(); -	virtual BOOL postBuild(); +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onClose(bool app_quitting); +  	static LLFloaterMediaSettings* getInstance();  	static void apply(); -	static void initValues( const LLSD& media_settings ); -	static void clearValues(); +	static void initValues( const LLSD& media_settings , bool editable); +	static void clearValues( bool editable);  	void enableOkApplyBtns( bool enable );  	LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;}; +	bool mIdenticalHasMediaInfo; +	bool mMultipleMedia; +	bool mMultipleValidMedia; +	  protected:  	LLButton *mOKBtn;  	LLButton *mCancelBtn; @@ -65,7 +71,7 @@ protected:  	LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity;  	LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions; -	void		onClose(); +  	static void onBtnOK(void*);  	static void onBtnCancel(void*);  	static void onBtnApply(void*); diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 0df3780ac4..a61cc04941 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -63,7 +63,6 @@ protected:  	void refresh();  	void draw();  	virtual void onOpen(const LLSD& key); -//	virtual void onClose();  	void moveToInventory(bool wear); diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp new file mode 100644 index 0000000000..88811d06fe --- /dev/null +++ b/indra/newview/llfloaterpay.cpp @@ -0,0 +1,573 @@ +/**  + * @file llfloaterpay.cpp + * @author Aaron Brashears, Kelly Washington, James Cook + * @brief Implementation of the LLFloaterPay class. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + *  + * Copyright (c) 2002-2009, 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 "llfloaterpay.h" + +#include "message.h" +#include "llfloater.h" +#include "lllslconstants.h"		// MAX_PAY_BUTTONS +#include "lluuid.h" + +#include "llagent.h" +#include "llfloaterreg.h" +#include "llresmgr.h" +#include "lltextbox.h" +#include "lllineeditor.h" +#include "llmutelist.h" +#include "llfloaterreporter.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llbutton.h" +#include "llselectmgr.h" +#include "lltransactiontypes.h" +#include "lluictrlfactory.h" + +///---------------------------------------------------------------------------- +/// Local function declarations, constants, enums, and typedefs +///---------------------------------------------------------------------------- + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLGiveMoneyInfo +// +// A small class used to track callback information +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFloaterPay; + +struct LLGiveMoneyInfo +{ +	LLFloaterPay* mFloater; +	S32 mAmount; +	LLGiveMoneyInfo(LLFloaterPay* floater, S32 amount) : +		mFloater(floater), mAmount(amount){} +}; + +///---------------------------------------------------------------------------- +/// Class LLFloaterPay +///---------------------------------------------------------------------------- + +class LLFloaterPay : public LLFloater +{ +public: +	LLFloaterPay(const LLSD& key); +	virtual ~LLFloaterPay(); +	/*virtual*/	BOOL	postBuild(); +	/*virtual*/ void onClose(bool app_quitting); +	 +	void setCallback(money_callback callback) { mCallback = callback; } +	 + +	static void payViaObject(money_callback callback, LLSafeHandle<LLObjectSelection> selection); +	 +	static void payDirectly(money_callback callback, +							const LLUUID& target_id, +							bool is_group); + +private: +	static void onCancel(void* data); +	static void onKeystroke(LLLineEditor* editor, void* data); +	static void onGive(void* data); +	void give(S32 amount); +	static void processPayPriceReply(LLMessageSystem* msg, void **userdata); +	void onCacheOwnerName(const LLUUID& owner_id, +						  const std::string& firstname, +						  const std::string& lastname, +						  BOOL is_group); +	void finishPayUI(const LLUUID& target_id, BOOL is_group); + +protected: +	std::vector<LLGiveMoneyInfo*> mCallbackData; +	money_callback mCallback; +	LLTextBox* mObjectNameText; +	LLUUID mTargetUUID; +	BOOL mTargetIsGroup; +	BOOL mHaveName; + +	LLButton* mQuickPayButton[MAX_PAY_BUTTONS]; +	LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS]; + +	LLSafeHandle<LLObjectSelection> mObjectSelection; + +	static S32 sLastAmount; +}; + + +S32 LLFloaterPay::sLastAmount = 0; +const S32 MAX_AMOUNT_LENGTH = 10; +const S32 FASTPAY_BUTTON_WIDTH = 80; + +LLFloaterPay::LLFloaterPay(const LLSD& key) +	: LLFloater(key), +	  mCallbackData(), +	  mCallback(NULL), +	  mObjectNameText(NULL), +	  mTargetUUID(key.asUUID()), +	  mTargetIsGroup(FALSE) +{ +} + +// Destroys the object +LLFloaterPay::~LLFloaterPay() +{ +	std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer()); +	// Name callbacks will be automatically disconnected since LLFloater is trackable +} + +BOOL LLFloaterPay::postBuild() +{ +	S32 i = 0; +	 +	LLGiveMoneyInfo* info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0); +	mCallbackData.push_back(info); + +	childSetAction("fastpay 1",&LLFloaterPay::onGive,info); +	childSetVisible("fastpay 1", FALSE); + +	mQuickPayButton[i] = getChild<LLButton>("fastpay 1"); +	mQuickPayInfo[i] = info; +	++i; + +	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1); +	mCallbackData.push_back(info); + +	childSetAction("fastpay 5",&LLFloaterPay::onGive,info); +	childSetVisible("fastpay 5", FALSE); + +	mQuickPayButton[i] = getChild<LLButton>("fastpay 5"); +	mQuickPayInfo[i] = info; +	++i; + +	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2); +	mCallbackData.push_back(info); + +	childSetAction("fastpay 10",&LLFloaterPay::onGive,info); +	childSetVisible("fastpay 10", FALSE); + +	mQuickPayButton[i] = getChild<LLButton>("fastpay 10"); +	mQuickPayInfo[i] = info; +	++i; + +	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3); +	mCallbackData.push_back(info); + +	childSetAction("fastpay 20",&LLFloaterPay::onGive,info); +	childSetVisible("fastpay 20", FALSE); + +	mQuickPayButton[i] = getChild<LLButton>("fastpay 20"); +	mQuickPayInfo[i] = info; +	++i; + + +	childSetVisible("amount text", FALSE);	 + +	std::string last_amount; +	if(sLastAmount > 0) +	{ +		last_amount = llformat("%d", sLastAmount); +	} + +	childSetVisible("amount", FALSE); + +	getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this); +	childSetText("amount", last_amount); +	childSetPrevalidate("amount", LLLineEditor::prevalidateNonNegativeS32); + +	info = new LLGiveMoneyInfo(this, 0); +	mCallbackData.push_back(info); + +	childSetAction("pay btn",&LLFloaterPay::onGive,info); +	setDefaultBtn("pay btn"); +	childSetVisible("pay btn", FALSE); +	childSetEnabled("pay btn", (sLastAmount > 0)); + +	childSetAction("cancel btn",&LLFloaterPay::onCancel,this); + +	return TRUE; +} + +// virtual +void LLFloaterPay::onClose(bool app_quitting) +{ +	// Deselect the objects +	mObjectSelection = NULL; +} + +// static +void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata) +{ +	LLFloaterPay* self = (LLFloaterPay*)userdata; +	if (self) +	{ +		S32 price; +		LLUUID target; + +		msg->getUUIDFast(_PREHASH_ObjectData,_PREHASH_ObjectID,target); +		if (target != self->mTargetUUID) +		{ +			// This is a message for a different object's pay info +			return; +		} + +		msg->getS32Fast(_PREHASH_ObjectData,_PREHASH_DefaultPayPrice,price); +		 +		if (PAY_PRICE_HIDE == price) +		{ +			self->childSetVisible("amount", FALSE); +			self->childSetVisible("pay btn", FALSE); +			self->childSetVisible("amount text", FALSE); +		} +		else if (PAY_PRICE_DEFAULT == price) +		{			 +			self->childSetVisible("amount", TRUE); +			self->childSetVisible("pay btn", TRUE); +			self->childSetVisible("amount text", TRUE); +		} +		else +		{ +			// PAY_PRICE_HIDE and PAY_PRICE_DEFAULT are negative values +			// So we take the absolute value here after we have checked for those cases +			 +			self->childSetVisible("amount", TRUE); +			self->childSetVisible("pay btn", TRUE); +			self->childSetEnabled("pay btn", TRUE); +			self->childSetVisible("amount text", TRUE); + +			self->childSetText("amount", llformat("%d", llabs(price))); +		} + +		S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_ButtonData); +		S32 i = 0; +		if (num_blocks > MAX_PAY_BUTTONS) num_blocks = MAX_PAY_BUTTONS; + +		S32 max_pay_amount = 0; +		S32 padding_required = 0; + +		for (i=0;i<num_blocks;++i) +		{ +			S32 pay_button; +			msg->getS32Fast(_PREHASH_ButtonData,_PREHASH_PayButton,pay_button,i); +			if (pay_button > 0) +			{ +				std::string button_str = "L$"; +				button_str += LLResMgr::getInstance()->getMonetaryString( pay_button ); + +				self->mQuickPayButton[i]->setLabelSelected(button_str); +				self->mQuickPayButton[i]->setLabelUnselected(button_str); +				self->mQuickPayButton[i]->setVisible(TRUE); +				self->mQuickPayInfo[i]->mAmount = pay_button; +				self->childSetVisible("fastpay text",TRUE); + +				if ( pay_button > max_pay_amount ) +				{ +					max_pay_amount = pay_button; +				} +			} +			else +			{ +				self->mQuickPayButton[i]->setVisible(FALSE); +			} +		} + +		// build a string containing the maximum value and calc nerw button width from it. +		std::string balance_str = "L$"; +		balance_str += LLResMgr::getInstance()->getMonetaryString( max_pay_amount ); +		const LLFontGL* font = LLFontGL::getFontSansSerif(); +		S32 new_button_width = font->getWidth( std::string(balance_str)); +		new_button_width += ( 12 + 12 );	// padding + +		// dialong is sized for 2 digit pay amounts - larger pay values need to be scaled +		const S32 threshold = 100000; +		if ( max_pay_amount >= threshold ) +		{ +			S32 num_digits_threshold = (S32)log10((double)threshold) + 1; +			S32 num_digits_max = (S32)log10((double)max_pay_amount) + 1; +				 +			// calculate the extra width required by 2 buttons with max amount and some commas +			padding_required = ( num_digits_max - num_digits_threshold + ( num_digits_max / 3 ) ) * font->getWidth( std::string("0") ); +		}; + +		// change in button width +		S32 button_delta = new_button_width - FASTPAY_BUTTON_WIDTH; +		if ( button_delta < 0 )  +			button_delta = 0; + +		// now we know the maximum amount, we can resize all the buttons to be  +		for (i=0;i<num_blocks;++i) +		{ +			LLRect r; +			r = self->mQuickPayButton[i]->getRect(); + +			// RHS button colum needs to move further because LHS changed too +			if ( i % 2 ) +			{ +				r.setCenterAndSize( r.getCenterX() + ( button_delta * 3 ) / 2 ,  +					r.getCenterY(),  +						r.getWidth() + button_delta,  +							r.getHeight() );  +			} +			else +			{ +				r.setCenterAndSize( r.getCenterX() + button_delta / 2,  +					r.getCenterY(),  +						r.getWidth() + button_delta,  +						r.getHeight() );  +			} +			self->mQuickPayButton[i]->setRect( r ); +		} + +		for (i=num_blocks;i<MAX_PAY_BUTTONS;++i) +		{ +			self->mQuickPayButton[i]->setVisible(FALSE); +		} + +		self->reshape( self->getRect().getWidth() + padding_required, self->getRect().getHeight(), FALSE ); +	} +	msg->setHandlerFunc("PayPriceReply",NULL,NULL); +} + +// static +void LLFloaterPay::payViaObject(money_callback callback, LLSafeHandle<LLObjectSelection> selection) +{ +	// Object that lead to the selection, may be child +	LLViewerObject* object = selection->getPrimaryObject(); +	if (!object) +		return; +	 +	LLFloaterPay *floater = LLFloaterReg::showTypedInstance<LLFloaterPay>("pay_object", LLSD(object->getID())); +	if (!floater) +		return; +	 +	floater->setCallback(callback); +	// Hold onto the selection until we close +	floater->mObjectSelection = selection; + +	LLSelectNode* node = selection->getFirstRootNode(); +	if (!node)  +	{ +		//FIXME: notify user object no longer exists +		floater->closeFloater(); +		return; +	} +	 +	LLHost target_region = object->getRegion()->getHost(); +	 +	LLMessageSystem* msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_RequestPayPrice); +	msg->nextBlockFast(_PREHASH_ObjectData); +	msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); +	msg->sendReliable(target_region); +	msg->setHandlerFuncFast(_PREHASH_PayPriceReply, processPayPriceReply,(void **)floater); +	 +	LLUUID owner_id; +	BOOL is_group = FALSE; +	node->mPermissions->getOwnership(owner_id, is_group); +	 +	floater->childSetText("object_name_text",node->mName); + +	floater->finishPayUI(owner_id, is_group); +} + +void LLFloaterPay::payDirectly(money_callback callback,  +							   const LLUUID& target_id, +							   bool is_group) +{ +	LLFloaterPay *floater = LLFloaterReg::showTypedInstance<LLFloaterPay>("pay_resident", LLSD(target_id)); +	if (!floater) +		return; +	 +	floater->setCallback(callback); +	floater->mObjectSelection = NULL; +	 +	floater->childSetVisible("amount", TRUE); +	floater->childSetVisible("pay btn", TRUE); +	floater->childSetVisible("amount text", TRUE); + +	floater->childSetVisible("fastpay text",TRUE); +	for(S32 i=0;i<MAX_PAY_BUTTONS;++i) +	{ +		floater->mQuickPayButton[i]->setVisible(TRUE); +	} +	 +	floater->finishPayUI(target_id, is_group); +} +	 +void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group) +{ +	gCacheName->get(target_id, is_group, boost::bind(&LLFloaterPay::onCacheOwnerName, this, _1, _2, _3, _4)); + +	// Make sure the amount field has focus + +	childSetFocus("amount", TRUE); +	 +	LLLineEditor* amount = getChild<LLLineEditor>("amount"); +	amount->selectAll(); +	mTargetIsGroup = is_group; +} + +void LLFloaterPay::onCacheOwnerName(const LLUUID& owner_id, +									const std::string& firstname, +									const std::string& lastname, +									BOOL is_group) +{ +	if (is_group) +	{ +		childSetVisible("payee_group",true); +		childSetVisible("payee_resident",false); +	} +	else +	{ +		childSetVisible("payee_group",false); +		childSetVisible("payee_resident",true); +	} +	 +	childSetTextArg("payee_name", "[FIRST]", firstname); +	childSetTextArg("payee_name", "[LAST]", lastname); +} + +// static +void LLFloaterPay::onCancel(void* data) +{ +	LLFloaterPay* self = reinterpret_cast<LLFloaterPay*>(data); +	if(self) +	{ +		self->closeFloater(); +	} +} + +// static +void LLFloaterPay::onKeystroke(LLLineEditor*, void* data) +{ +	LLFloaterPay* self = reinterpret_cast<LLFloaterPay*>(data); +	if(self) +	{ +		// enable the Pay button when amount is non-empty and positive, disable otherwise +		std::string amtstr = self->childGetText("amount"); +		self->childSetEnabled("pay btn", !amtstr.empty() && atoi(amtstr.c_str()) > 0); +	} +} + +// static +void LLFloaterPay::onGive(void* data) +{ +	LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data); +	if(info && info->mFloater) +	{ +		info->mFloater->give(info->mAmount); +		info->mFloater->closeFloater(); +	} +} + +void LLFloaterPay::give(S32 amount) +{ +	if(mCallback) +	{ +		// if the amount is 0, that menas that we should use the +		// text field. +		if(amount == 0) +		{ +			amount = atoi(childGetText("amount").c_str()); +		} +		sLastAmount = amount; + +		// Try to pay an object. +		if (mObjectSelection.notNull()) +		{ +			LLViewerObject* dest_object = gObjectList.findObject(mTargetUUID); +			if(dest_object) +			{ +				LLViewerRegion* region = dest_object->getRegion(); +				if (region) +				{ +					// Find the name of the root object +					LLSelectNode* node = mObjectSelection->getFirstRootNode(); +					std::string object_name; +					if (node) +					{ +						object_name = node->mName; +					} +					S32 tx_type = TRANS_PAY_OBJECT; +					if(dest_object->isAvatar()) tx_type = TRANS_GIFT; +					mCallback(mTargetUUID, region, amount, FALSE, tx_type, object_name); +					mObjectSelection = NULL; + +					// request the object owner in order to check if the owner needs to be unmuted +					LLMessageSystem* msg = gMessageSystem; +					msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); +					msg->nextBlockFast(_PREHASH_AgentData); +					msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +					msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +					msg->nextBlockFast(_PREHASH_ObjectData); +					msg->addU32Fast(_PREHASH_RequestFlags, OBJECT_PAY_REQUEST ); +					msg->addUUIDFast(_PREHASH_ObjectID, 	mTargetUUID); +					msg->sendReliable( region->getHost() ); +				} +			} +		} +		else +		{ +			// just transfer the L$ +			mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, LLStringUtil::null); + +			// check if the payee needs to be unmuted +			LLMuteList::getInstance()->autoRemove(mTargetUUID, LLMuteList::AR_MONEY); +		} +	} +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Namespace LLFloaterPayUtil +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +void LLFloaterPayUtil::registerFloater() +{ +	// Sneaky, use same code but different XML for dialogs +	LLFloaterReg::add("pay_resident", "floater_pay.xml",  +		&LLFloaterReg::build<LLFloaterPay>); +	LLFloaterReg::add("pay_object", "floater_pay_object.xml",  +		&LLFloaterReg::build<LLFloaterPay>); +} + +void LLFloaterPayUtil::payViaObject(money_callback callback, +									LLSafeHandle<LLObjectSelection> selection) +{ +	LLFloaterPay::payViaObject(callback, selection); +} + +void LLFloaterPayUtil::payDirectly(money_callback callback, +								   const LLUUID& target_id, +								   bool is_group) +{ +	LLFloaterPay::payDirectly(callback, target_id, is_group); +} diff --git a/indra/newview/llfloaterpay.h b/indra/newview/llfloaterpay.h new file mode 100644 index 0000000000..161ed78acb --- /dev/null +++ b/indra/newview/llfloaterpay.h @@ -0,0 +1,61 @@ +/**  + * @file llfloaterpay.h + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + *  + * Copyright (c) 2002-2009, 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 LLFLOATERPAY_H +#define LLFLOATERPAY_H + +#include "llsafehandle.h" + +class LLObjectSelection; +class LLUUID; +class LLViewerRegion; + +typedef void (*money_callback)(const LLUUID&, LLViewerRegion*,S32,BOOL,S32,const std::string&); + +namespace LLFloaterPayUtil +{ +	/// Register with LLFloaterReg +	void registerFloater(); + +	/// Pay into an in-world object, which will trigger scripts and eventually +	/// transfer the L$ to the resident or group that owns the object. +	/// Objects must be selected.  Recipient (primary) object may be a child. +	void payViaObject(money_callback callback, +					  LLSafeHandle<LLObjectSelection> selection); +	 +	/// Pay an avatar or group directly, not via an object in the world. +	/// Scripts are not notified, L$ can be direcly transferred. +	void payDirectly(money_callback callback, +					 const LLUUID& target_id, +					 bool is_group); +} + +#endif // LLFLOATERPAY_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 57c043a1e0..dbee9ea309 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -357,8 +357,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  BOOL LLFloaterPreference::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLFloaterPreference::onClose, this)); -	  	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");  	if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))  		tabcontainer->selectFirstTab(); @@ -566,7 +564,8 @@ void LLFloaterPreference::setHardwareDefaults()  	refreshEnabledGraphics();  } -void LLFloaterPreference::onClose() +//virtual +void LLFloaterPreference::onClose(bool app_quitting)  {  	gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());  	LLPanelLogin::setAlwaysRefresh(false); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index ce31abcd9e..34723b8c7e 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -70,8 +70,9 @@ public:  	void apply();  	void cancel();  	/*virtual*/ void draw(); -	virtual BOOL postBuild(); -	virtual void onOpen(const LLSD& key); +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/	void onClose(bool app_quitting);  	// static data update, called from message handler  	static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email); @@ -79,10 +80,7 @@ public:  	// refresh all the graphics preferences menus  	static void refreshEnabledGraphics(); -protected: -	 -	void		onClose(); -	 +protected:	  	void		onBtnOK();  	void		onBtnCancel();  	void		onBtnApply(); diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 9e203c4269..43d31aa30a 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -58,7 +58,7 @@ class LLFloaterSellLandUI  public:  	LLFloaterSellLandUI(const LLSD& key);  	virtual ~LLFloaterSellLandUI(); -	void onClose(); +	/*virtual*/ void onClose(bool app_quitting);  private:  	class SelectionObserver : public LLParcelObserver @@ -131,7 +131,6 @@ LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key)  	mRegion(0)  {  	LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver); -	mCloseSignal.connect(boost::bind(&LLFloaterSellLandUI::onClose, this));  }  LLFloaterSellLandUI::~LLFloaterSellLandUI() @@ -140,7 +139,7 @@ LLFloaterSellLandUI::~LLFloaterSellLandUI()  }  // Because we are single_instance, we are not destroyed on close. -void LLFloaterSellLandUI::onClose() +void LLFloaterSellLandUI::onClose(bool app_quitting)  {  	// Must release parcel selection to allow land to deselect, see EXT-803  	mParcelSelection = NULL; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index c08996cc26..320647ff1a 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -77,12 +77,14 @@  #include "lltoolpipette.h"  #include "lltoolplacer.h"  #include "lltoolselectland.h" +#include "lltrans.h"  #include "llui.h" +#include "llviewercontrol.h" +#include "llviewerjoystick.h" +#include "llviewerregion.h"  #include "llviewermenu.h"  #include "llviewerparcelmgr.h"  #include "llviewerwindow.h" -#include "llviewercontrol.h" -#include "llviewerjoystick.h"  #include "lluictrlfactory.h"  // Globals @@ -198,9 +200,7 @@ LLPCode toolData[]={  	LL_PCODE_LEGACY_GRASS};  BOOL	LLFloaterTools::postBuild() -{ -	mCloseSignal.connect(boost::bind(&LLFloaterTools::onClose, this)); -	 +{	  	// Hide until tool selected  	setVisible(FALSE); @@ -724,7 +724,8 @@ void LLFloaterTools::onOpen(const LLSD& key)  	//gMenuBarView->setItemVisible("BuildTools", TRUE);  } -void LLFloaterTools::onClose() +// virtual +void LLFloaterTools::onClose(bool app_quitting)  {  	mTab->setVisible(FALSE); @@ -980,27 +981,86 @@ void LLFloaterTools::onFocusReceived()  void LLFloaterTools::refreshMedia()  {  	getMediaState();	 -	LLFloaterMediaSettings::getInstance(); -	LLFloaterMediaSettings::initValues(mMediaSettings );  } - +bool LLFloaterTools::selectedMediaEditable() +{ +	U32 owner_mask_on; +	U32 owner_mask_off; +	U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,  +																	  &owner_mask_on, &owner_mask_off ); +	U32 group_mask_on; +	U32 group_mask_off; +	U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,  +																	  &group_mask_on, &group_mask_off ); +	U32 everyone_mask_on; +	U32 everyone_mask_off; +	S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,  +																		 &everyone_mask_on, &everyone_mask_off ); +	 +	bool selected_Media_editable = false; +	 +	// if perms we got back are valid +	if ( valid_owner_perms && +		valid_group_perms &&  +		valid_everyone_perms ) +	{ +		 +		if ( ( owner_mask_on & PERM_MODIFY ) || +			( group_mask_on & PERM_MODIFY ) ||  +			( group_mask_on & PERM_MODIFY ) ) +		{ +			selected_Media_editable = true; +		} +		else +			// user is NOT allowed to press the RESET button +		{ +			selected_Media_editable = false; +		}; +	}; +	 +	return selected_Media_editable; +}  void LLFloaterTools::getMediaState()  { -	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); +	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); +	LLViewerObject* first_object = selected_objects->getFirstObject(); +	LLLineEditor* media_info = getChild<LLLineEditor>("media_info"); +	 +	if( !(first_object  +		  && first_object->getPCode() == LL_PCODE_VOLUME +		  &&first_object->permModify()  +	      )) +	{ +		childSetEnabled("media_tex", FALSE); +		childSetEnabled("add_media", FALSE); +		childSetEnabled("delete_media", FALSE); +		childSetEnabled("edit_media", FALSE); +		childSetEnabled("media_info", FALSE); +		media_info->setEnabled(FALSE); +		media_info->clear(); +		clearMediaSettings(); +		return; +	} -	if( !objectp ) +	std::string url = first_object->getRegion()->getCapability("ObjectMedia"); +	bool has_media_capability = (!url.empty()); +	 +	if(!has_media_capability)  	{  		childSetEnabled("media_tex", FALSE);  		childSetEnabled("add_media", FALSE);  		childSetEnabled("delete_media", FALSE);  		childSetEnabled("edit_media", FALSE); -		updateMediaSettings(); +		childSetEnabled("media_info", FALSE); +		media_info->setEnabled(FALSE); +		media_info->clear();	 +		clearMediaSettings();  		return;  	} -	bool editable = gAgent.isGodlike() || (objectp->permModify() && objectp->getPCode() == LL_PCODE_VOLUME); +	bool editable = (first_object->permModify());// && selectedMediaEditable());  	// Media settings  	U8 has_media = (U8)0; @@ -1011,24 +1071,104 @@ void LLFloaterTools::getMediaState()  			return (object->getTE(face)->getMediaTexGen());  		}  	} func; -	bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, has_media ); +	// check if all faces have media(or, all dont have media) +	LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, has_media ); +	bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA); + +	const LLMediaEntry default_media_data; +	 +	struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> +    { +		functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}	 + +        LLMediaEntry get( LLViewerObject* object, S32 face ) +        { +            if ( object ) +                if ( object->getTE(face) ) +                    if ( object->getTE(face)->getMediaData() ) +                        return *(object->getTE(face)->getMediaData()); +			return mMediaEntry; +        }; +		 +		const LLMediaEntry& mMediaEntry; +		 +    } func_media_data(default_media_data); + +	LLMediaEntry media_data_get; +    LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get )); +	 +	std::string multi_media_info_str = LLTrans::getString("Multiple Media"); +	std::string media_title = "";  	// update UI depending on whether "object" (prim or face) has media  	// and whether or not you are allowed to edit it. -	bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA); -	childSetEnabled("media_tex",  bool_has_media & editable); -	childSetEnabled( "edit_media", bool_has_media & editable ); -	childSetEnabled( "delete_media", bool_has_media & editable ); -	childSetEnabled( "add_media", ( ! bool_has_media ) & editable ); +	 +	// IF all the faces have media (or all dont have media) +	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) +	{ +		// TODO: get media title and set it. +		media_info->clear(); +		// if identical is set, all faces are same (whether all empty or has the same media) +		if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) ) +		{ +			// Media data is valid +			if(media_data_get!=default_media_data) +			{ +				//TODO: get Meida title +				//media_title =  media_data_get->getTile(); +				//LLFloaterMediaSettings::getInstance()->mIdenticalValidMedia = true; +				media_title = media_data_get.getHomeURL(); +			} +			// else all faces might be empty.  +			 +			 +		} +		else // there' re Different Medias' been set on on the faces. +		{ +			media_title = multi_media_info_str; +		} +		 +		childSetEnabled("media_tex",  bool_has_media & editable); +		childSetEnabled( "edit_media", bool_has_media & editable ); +		childSetEnabled( "delete_media", bool_has_media & editable ); +		childSetEnabled( "add_media", ( ! bool_has_media ) & editable ); +		media_info->setEnabled(bool_has_media & editable); +			// TODO: display a list of all media on the face - use 'identical' flag +	} +	else // not all face has media but at least one does. +	{ +		// seleted faces have not identical value +		LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data ); +	 +		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) +		{ +			media_title = multi_media_info_str; +		} +		else +		{ +			// Media data is valid +			if(media_data_get!=default_media_data) +			{ +				//TODO: get Meida title +				//media_title =  media_data_get->getTile(); +				media_title = media_data_get.getHomeURL(); +			} +			 +		} +		 +		media_info->setEnabled(TRUE); +		media_info->setTentative(true); +		childSetEnabled("media_tex",  TRUE); +		childSetEnabled( "edit_media", TRUE); +		childSetEnabled( "delete_media", TRUE); +		childSetEnabled( "add_media", FALSE ); +	} +	media_info->setText(media_title);  	// load values for media settings  	updateMediaSettings(); -	// if identical is set, all faces are same -	if ( identical ) -	{ -		// TODO: display a list of all media on the face - use 'identical' flag -	}; +	LLFloaterMediaSettings::initValues(mMediaSettings, editable );  } @@ -1104,6 +1244,12 @@ bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& re  	return false;  } +void LLFloaterTools::clearMediaSettings() +{ +	LLFloaterMediaSettings::getInstance(); +	LLFloaterMediaSettings::clearValues(false); + +}  //////////////////////////////////////////////////////////////////////////////  //  void LLFloaterTools::updateMediaSettings() @@ -1116,23 +1262,26 @@ void LLFloaterTools::updateMediaSettings()  	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();      // TODO: (CP) refactor this using something clever or boost or both !! -    LLMediaEntry default_media_data; +    const LLMediaEntry default_media_data;      // controls       U8 value_u8 = default_media_data.getControls();      struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >      { +		functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {} +		          U8 get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getControls(); -            LLMediaEntry default_media_data; -            return default_media_data.getControls(); +            return mMediaEntry.getControls();          }; -    } func_controls; +		const LLMediaEntry & mMediaEntry; +		 +    } func_controls(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );      base_key = std::string( LLMediaEntry::CONTROLS_KEY );      mMediaSettings[ base_key ] = value_u8; @@ -1142,17 +1291,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = default_media_data.getFirstClickInteract();      struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}		 +		          bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getFirstClickInteract(); -            LLMediaEntry default_media_data; -            return default_media_data.getFirstClickInteract(); +            return mMediaEntry.getFirstClickInteract();          }; -    } func_first_click; +		const LLMediaEntry & mMediaEntry; +		 +    } func_first_click(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );      base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1162,38 +1314,43 @@ void LLFloaterTools::updateMediaSettings()      value_str = default_media_data.getHomeURL();      struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >      { +		functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}		 +		          std::string get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getHomeURL(); -            LLMediaEntry default_media_data; -            return default_media_data.getHomeURL(); +            return mMediaEntry.getHomeURL();          }; -    } func_home_url; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_home_url(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );      base_key = std::string( LLMediaEntry::HOME_URL_KEY );      mMediaSettings[ base_key ] = value_str;      mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; -	llwarns<<"Angela debug : home url string == "<<value_str<<llendl;      // Current URL      value_str = default_media_data.getCurrentURL();      struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >      { -        std::string get( LLViewerObject* object, S32 face ) +		functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {} +         +		std::string get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getCurrentURL(); -            LLMediaEntry default_media_data; -            return default_media_data.getCurrentURL(); +            return mMediaEntry.getCurrentURL();          }; -    } func_current_url; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_current_url(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );      base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );      mMediaSettings[ base_key ] = value_str; @@ -1203,17 +1360,21 @@ void LLFloaterTools::updateMediaSettings()      value_bool = default_media_data.getAutoZoom();      struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >      { +		 +		functor_getter_auto_zoom(const LLMediaEntry& entry)	: mMediaEntry(entry) {}	 +		          bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getAutoZoom(); -            LLMediaEntry default_media_data; -            return default_media_data.getAutoZoom(); +            return mMediaEntry.getAutoZoom();          }; -    } func_auto_zoom; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_auto_zoom(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );      base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1223,37 +1384,44 @@ void LLFloaterTools::updateMediaSettings()      value_bool = default_media_data.getAutoPlay();      struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_auto_play(const LLMediaEntry& entry)	: mMediaEntry(entry) {}	 +			          bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getAutoPlay(); -			LLMediaEntry default_media_data; -            return default_media_data.getAutoPlay(); +            return mMediaEntry.getAutoPlay();          }; -    } func_auto_play; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_auto_play(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );      base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );      mMediaSettings[ base_key ] = value_bool;      mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; +	      // Auto scale      value_bool = default_media_data.getAutoScale();      struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}	 +          bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getAutoScale(); -			LLMediaEntry default_media_data; -            return default_media_data.getAutoScale();; +            return mMediaEntry.getAutoScale();;          }; -    } func_auto_scale; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_auto_scale(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );      base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1263,17 +1431,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = default_media_data.getAutoLoop();      struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_auto_loop(const LLMediaEntry& entry)	: mMediaEntry(entry) {}	 +          bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getAutoLoop(); -			LLMediaEntry default_media_data; -            return default_media_data.getAutoLoop(); +            return mMediaEntry.getAutoLoop();          }; -    } func_auto_loop; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_auto_loop(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );      base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1283,17 +1454,20 @@ void LLFloaterTools::updateMediaSettings()      value_int = default_media_data.getWidthPixels();      struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >      { +		functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}		 +          int get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getWidthPixels(); -			LLMediaEntry default_media_data; -            return default_media_data.getWidthPixels(); +            return mMediaEntry.getWidthPixels();          }; -    } func_width_pixels; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_width_pixels(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );      base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );      mMediaSettings[ base_key ] = value_int; @@ -1303,17 +1477,20 @@ void LLFloaterTools::updateMediaSettings()      value_int = default_media_data.getHeightPixels();      struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >      { -        int get( LLViewerObject* object, S32 face ) +		functor_getter_height_pixels(const LLMediaEntry& entry)	: mMediaEntry(entry) {} +         +		int get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getHeightPixels(); -			LLMediaEntry default_media_data; -            return default_media_data.getHeightPixels(); +            return mMediaEntry.getHeightPixels();          }; -    } func_height_pixels; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_height_pixels(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );      base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );      mMediaSettings[ base_key ] = value_int; @@ -1323,17 +1500,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = default_media_data.getAltImageEnable();      struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >      { -        bool get( LLViewerObject* object, S32 face ) +		functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {} +         +		bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getAltImageEnable(); -			LLMediaEntry default_media_data; -            return default_media_data.getAltImageEnable(); +            return mMediaEntry.getAltImageEnable();          }; -    } func_enable_alt_image; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_enable_alt_image(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );      base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1343,17 +1523,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );      struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >      { -        bool get( LLViewerObject* object, S32 face ) +		functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} +         +		bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER)); -			LLMediaEntry default_media_data; -            return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER ); +            return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );          }; -    } func_perms_owner_interact; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_perms_owner_interact(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );      base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1363,17 +1546,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );      struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_perms_owner_control(const LLMediaEntry& entry)	: mMediaEntry(entry) {} +                  bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER)); -			LLMediaEntry default_media_data; -            return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER ); +            return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );          }; -    } func_perms_owner_control; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_perms_owner_control(default_media_data);      identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );      base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1383,17 +1569,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );      struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} +                  bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP)); -			LLMediaEntry default_media_data; -            return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP ); +            return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );          }; -    } func_perms_group_interact; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_perms_group_interact(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );      base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1403,17 +1592,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );      struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {} +                  bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP)); -			LLMediaEntry default_media_data; -            return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP ); +            return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );          }; -    } func_perms_group_control; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_perms_group_control(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );      base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1423,17 +1615,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );      struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} +                  bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE)); -			LLMediaEntry default_media_data; -            return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); +            return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );          }; -    } func_perms_anyone_interact; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_perms_anyone_interact(default_media_data);      identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );      base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1443,17 +1638,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );      struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_perms_anyone_control(const LLMediaEntry& entry)	: mMediaEntry(entry) {} +                  bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE)); -			LLMediaEntry default_media_data; -            return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE ); +            return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );          }; -    } func_perms_anyone_control; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_perms_anyone_control(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );      base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1463,17 +1661,20 @@ void LLFloaterTools::updateMediaSettings()      value_bool = default_media_data.getWhiteListEnable();      struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >      { +		functor_getter_whitelist_enable(const LLMediaEntry& entry)	: mMediaEntry(entry) {} +                  bool get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getWhiteListEnable(); -			LLMediaEntry default_media_data; -            return default_media_data.getWhiteListEnable(); +            return mMediaEntry.getWhiteListEnable();          }; -    } func_whitelist_enable; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_whitelist_enable(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );      base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );      mMediaSettings[ base_key ] = value_bool; @@ -1483,17 +1684,20 @@ void LLFloaterTools::updateMediaSettings()      std::vector<std::string> value_vector_str = default_media_data.getWhiteList();      struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >      { +		functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {} +                  std::vector<std::string> get( LLViewerObject* object, S32 face )          {              if ( object )                  if ( object->getTE(face) )                      if ( object->getTE(face)->getMediaData() )                          return object->getTE(face)->getMediaData()->getWhiteList(); -            LLMediaEntry default_media_data; -            return default_media_data.getWhiteList(); +            return mMediaEntry.getWhiteList();          }; -    } func_whitelist_urls; +		const LLMediaEntry &  mMediaEntry; +		 +    } func_whitelist_urls(default_media_data);      identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );      base_key = std::string( LLMediaEntry::WHITELIST_KEY );  	mMediaSettings[ base_key ].clear(); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 008c9677ed..ffccf93943 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -74,6 +74,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& key);  	/*virtual*/ BOOL canClose(); +	/*virtual*/ void onClose(bool app_quitting);  	/*virtual*/ void draw();  	/*virtual*/ void onFocusReceived(); @@ -105,10 +106,10 @@ public:  	void onClickBtnDeleteMedia();  	void onClickBtnAddMedia();  	void onClickBtnEditMedia(); -	 +	void clearMediaSettings(); +	bool selectedMediaEditable();  private: -	void onClose();  	void refresh();  	void refreshMedia();  	void getMediaState(); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 266252efea..98ca33c9cc 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -283,8 +283,6 @@ LLFloaterUIPreview::~LLFloaterUIPreview()  // Perform post-build setup (defined in superclass)  BOOL LLFloaterUIPreview::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLFloaterUIPreview::onClose, this, _2)); -	  	LLPanel* main_panel_tmp = getChild<LLPanel>("main_panel");				// get a pointer to the main panel in order to...  	mFileList = main_panel_tmp->getChild<LLScrollListCtrl>("name_list");	// save pointer to file list  	// Double-click opens the floater, for convenience @@ -442,9 +440,9 @@ void LLFloaterUIPreview::onClickExportSchema()  // Close click handler -- delete my displayed floater if it exists -void LLFloaterUIPreview::onClose(const LLSD& app_quitting) +void LLFloaterUIPreview::onClose(bool app_quitting)  { -	if(!app_quitting.asBoolean() && mDisplayedFloater) +	if(!app_quitting && mDisplayedFloater)  	{  		onClickCloseDisplayedFloater(PRIMARY_FLOATER);  		onClickCloseDisplayedFloater(SECONDARY_FLOATER); diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h index b8c378e2e9..2a98c90727 100644 --- a/indra/newview/llfloateruipreview.h +++ b/indra/newview/llfloateruipreview.h @@ -96,7 +96,9 @@ public:  	std::string getLocStr(S32 ID);							// fetches the localization string based on what is selected in the drop-down menu  	void displayFloater(BOOL click, S32 ID, bool save = false);			// needs to be public so live file can call it when it finds an update -	BOOL postBuild();										// post-build setup (called by superclass' constructor) +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onClose(bool app_quitting); +  	void refreshList();										// refresh list (empty it out and fill it up from scratch)  	void addFloaterEntry(const std::string& path);			// add a single file's entry to the list of floaters @@ -116,9 +118,6 @@ public:  	typedef std::map<std::string, std::pair<StringListPtr,StringListPtr> > DiffMap;  	DiffMap mDiffsMap;							// map, of filename to pair of list of changed element paths and list of errors -protected: -	void onClose(const LLSD& app_quitting); -  private:  	// XUI elements for this floater  	LLScrollListCtrl*			mFileList;							// scroll list control for file list diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp index a7658d90e9..b64257b11d 100644 --- a/indra/newview/llfloatervoicedevicesettings.cpp +++ b/indra/newview/llfloatervoicedevicesettings.cpp @@ -293,11 +293,11 @@ LLFloaterVoiceDeviceSettings::LLFloaterVoiceDeviceSettings(const LLSD& seed)  }  BOOL LLFloaterVoiceDeviceSettings::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLFloaterVoiceDeviceSettings::onClose, this)); -	  	center();  	return TRUE;  } + +// virtual  void LLFloaterVoiceDeviceSettings::onOpen(const LLSD& key)  {  	if(mDevicePanel) @@ -306,7 +306,8 @@ void LLFloaterVoiceDeviceSettings::onOpen(const LLSD& key)  	}  } -void LLFloaterVoiceDeviceSettings::onClose() +// virtual +void LLFloaterVoiceDeviceSettings::onClose(bool app_settings)  {  	if(mDevicePanel)  	{ diff --git a/indra/newview/llfloatervoicedevicesettings.h b/indra/newview/llfloatervoicedevicesettings.h index 2565bfad2b..f1603dc414 100644 --- a/indra/newview/llfloatervoicedevicesettings.h +++ b/indra/newview/llfloatervoicedevicesettings.h @@ -68,8 +68,9 @@ class LLFloaterVoiceDeviceSettings : public LLFloater  public: -	virtual BOOL postBuild(); +	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/ void onClose(bool app_settings);  	/*virtual*/ void draw();  	void apply();  	void cancel(); @@ -78,9 +79,7 @@ private:  protected:  	static void* createPanelVoiceDeviceSettings(void* user_data); -	 -	void onClose(); -	 +		  protected:  	LLPanelVoiceDeviceSettings* mDevicePanel;  }; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 098a5197df..d653d44f8c 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -183,8 +183,6 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)  BOOL LLFloaterWorldMap::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLFloaterWorldMap::onClose, this)); -	  	mTabs = getChild<LLTabContainer>("maptab");  	if (!mTabs) return FALSE; @@ -255,7 +253,8 @@ LLFloaterWorldMap* LLFloaterWorldMap::getInstance()  	return LLFloaterReg::getTypedInstance<LLFloaterWorldMap>("world_map");  } -void LLFloaterWorldMap::onClose() +// virtual +void LLFloaterWorldMap::onClose(bool app_quitting)  {  	// While we're not visible, discard the overlay images we're using  	LLWorldMap::getInstance()->clearImageRefs(); diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index f117ea05af..6d5b7543d4 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -65,6 +65,7 @@ public:  	BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/ void onClose(bool app_quitting);  	static void reloadIcons(void*); @@ -111,9 +112,7 @@ public:  	// teleport to the tracked item, if there is one  	void			teleport(); -protected: -	void			onClose(); -	 +protected:	  	void			onGoHome();  	void			onLandmarkComboPrearrange(); diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index dde36ac25b..3e449e2c82 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -78,12 +78,11 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)  		}  	} -	mCloseSignal.connect(boost::bind(&LLIMFloater::onClose, this)); -  	LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);  } -void LLIMFloater::onClose() +// virtual +void LLIMFloater::onClose(bool app_quitting)  {  	LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID); diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index a183212f04..f85a941be3 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -56,6 +56,7 @@ public:  	/*virtual*/ void setVisible(BOOL visible);  	// LLFloater overrides +	/*virtual*/ void onClose(bool app_quitting);  	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);  	// override LLFloater's minimization according to EXT-1216  	/*virtual*/ void setMinimized(BOOL minimize); @@ -79,10 +80,6 @@ public:  	// called when docked floater's position has been set by chiclet  	void setPositioned(bool b) { mPositioned = b; }; -	// handler for a CLOSE signal -	void onClose(); - -  private:  	static void		onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 89a885090c..4435bba0ed 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1052,8 +1052,6 @@ LLFloaterIMPanel::~LLFloaterIMPanel()  BOOL LLFloaterIMPanel::postBuild()   { -	mCloseSignal.connect(boost::bind(&LLFloaterIMPanel::onClose, this)); -	  	mVisibleSignal.connect(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2));  	mInputEditor = getChild<LLLineEditor>("chat_editor"); @@ -1610,7 +1608,8 @@ void LLFloaterIMPanel::onInputEditorKeystroke(LLLineEditor* caller, void* userda  	}  } -void LLFloaterIMPanel::onClose() +// virtual +void LLFloaterIMPanel::onClose(bool app_quitting)  {  	setTyping(FALSE); diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index fb9b28ad16..57379b2c0d 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -198,7 +198,7 @@ public:  	// Check typing timeout timer.  	/*virtual*/ void draw(); -	void onClose(); +	/*virtual*/ void onClose(bool app_quitting);  	void onVisibilityChange(const LLSD& new_visibility);  	// add target ids to the session.  diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 9b75c15597..4046c893c1 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -51,6 +51,7 @@  #include "llcontrol.h"	// LLCachedControl  #include "llfloater.h"  #include "llfloaterreg.h" +#include "llmenubutton.h"  #include "lltooltip.h"	// positionViewNearMouse()  #include "lluictrl.h" @@ -80,6 +81,9 @@ public:  	// Because floater is single instance, need to re-parse data on each spawn  	// (for example, inspector about same avatar but in different position)  	/*virtual*/ void onOpen(const LLSD& avatar_id); + +	// When closing they should close their gear menu  +	/*virtual*/ void onClose(bool app_quitting);  	// Inspectors close themselves when they lose focus  	/*virtual*/ void onFocusLost(); @@ -288,6 +292,12 @@ void LLInspectAvatar::onOpen(const LLSD& data)  	updateVolumeSlider();  } +// virtual +void LLInspectAvatar::onClose(bool app_quitting) +{   +  getChild<LLMenuButton>("gear_btn")->hideMenu(); +}	 +  //virtual  void LLInspectAvatar::onFocusLost()  { diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index b0e6273c41..8c38e785e9 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -46,6 +46,7 @@  #include "llcontrol.h"			// LLCachedControl  #include "llfloater.h"  #include "llfloaterreg.h" +#include "llmenubutton.h"  #include "llresmgr.h"			// getMonetaryString  #include "llsafehandle.h"  #include "lltextbox.h"			// for description truncation @@ -81,7 +82,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& avatar_id);  	// Release the selection and do other cleanup -	void onClose(); +	/*virtual*/ void onClose(bool app_quitting);  	// Inspectors close themselves when they lose focus  	/*virtual*/ void onFocusLost(); @@ -175,8 +176,6 @@ BOOL LLInspectObject::postBuild(void)  	LLSelectMgr::getInstance()->mUpdateSignal.connect(  		boost::bind(&LLInspectObject::update, this) ); -	mCloseSignal.connect( boost::bind(&LLInspectObject::onClose, this) ); -  	return TRUE;  } @@ -250,10 +249,13 @@ void LLInspectObject::onOpen(const LLSD& data)  	}  } -void LLInspectObject::onClose() +// virtual +void LLInspectObject::onClose(bool app_quitting)  {  	// Release selection to deselect  	mObjectSelection = NULL; + +	getChild<LLMenuButton>("gear_btn")->hideMenu();  }  //virtual diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b996c15a7d..26ff219437 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -68,7 +68,9 @@ LLMediaCtrl::Params::Params()  	texture_width("texture_width", 1024),  	texture_height("texture_height", 1024),  	caret_color("caret_color") -{} +{ +	tab_stop(false); +}  LLMediaCtrl::LLMediaCtrl( const Params& p) :  	LLPanel( p ), @@ -903,6 +905,12 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)  			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL;  		};  		break; + +		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; +		}; +		break;  	};  	// chain all events to any potential observers of this object. diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp new file mode 100644 index 0000000000..e69c85f245 --- /dev/null +++ b/indra/newview/llmediadataclient.cpp @@ -0,0 +1,624 @@ +/**  + * @file llmediadataclient.cpp + * @brief class for queueing up requests for media data + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2009, 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 "llmediadataclient.h" + +#include <boost/lexical_cast.hpp> + +#include "llhttpstatuscodes.h" +#include "llsdutil.h" +#include "llmediaentry.h" +#include "lltextureentry.h" +#include "llviewerregion.h" + +// +// When making a request +// - obtain the "overall interest score" of the object.	  +//	 This would be the sum of the impls' interest scores. +// - put the request onto a queue sorted by this score  +//	 (highest score at the front of the queue) +// - On a timer, once a second, pull off the head of the queue and send  +//	 the request. +// - Any request that gets a 503 still goes through the retry logic +// + +const F32 LLMediaDataClient::QUEUE_TIMER_DELAY = 1.0; // seconds(s) +const F32 LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY = 5.0; // secs +const U32 LLMediaDataClient::MAX_RETRIES = 4; + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient::Request +// +////////////////////////////////////////////////////////////////////////////////////// +/*static*/U32 LLMediaDataClient::Request::sNum = 0; + +LLMediaDataClient::Request::Request(const std::string &cap_name,  +									const LLSD& sd_payload, +									LLMediaDataClientObject *obj,  +									LLMediaDataClient *mdc) +	: mCapName(cap_name),  +	  mPayload(sd_payload),  +	  mObject(obj), +	  mNum(++sNum),  +	  mRetryCount(0), +	  mMDC(mdc) +{ +} + +LLMediaDataClient::Request::~Request() +{ +	LL_DEBUGS("LLMediaDataClient") << "~Request" << (*this) << LL_ENDL; +	mMDC = NULL; +	mObject = NULL; +} + +													   +std::string LLMediaDataClient::Request::getCapability() const +{ +	return getObject()->getCapabilityUrl(getCapName()); +} + +// Helper function to get the "type" of request, which just pokes around to +// discover it. +LLMediaDataClient::Request::Type LLMediaDataClient::Request::getType() const +{ +	if (mCapName == "ObjectMediaNavigate") +	{ +		return NAVIGATE; +	} +	else if (mCapName == "ObjectMedia") +	{ +		const std::string &verb = mPayload["verb"]; +		if (verb == "GET") +		{ +			return GET; +		} +		else if (verb == "UPDATE") +		{ +			return UPDATE; +		} +	} +	llassert(false); +	return GET; +} + +const char *LLMediaDataClient::Request::getTypeAsString() const +{ +	Type t = getType(); +	switch (t) +	{ +		case GET: +			return "GET"; +			break; +		case UPDATE: +			return "UPDATE"; +			break; +		case NAVIGATE: +			return "NAVIGATE"; +			break; +	} +	return ""; +} +	 + +void LLMediaDataClient::Request::reEnqueue() const +{ +	// I sure hope this doesn't deref a bad pointer: +	mMDC->enqueue(this); +} + +F32 LLMediaDataClient::Request::getRetryTimerDelay() const +{ +	return (mMDC == NULL) ? LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY : +		mMDC->mRetryTimerDelay;  +} + +U32 LLMediaDataClient::Request::getMaxNumRetries() const +{ +	return (mMDC == NULL) ? LLMediaDataClient::MAX_RETRIES : mMDC->mMaxNumRetries; +} + +std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r) +{ +	s << "<request>"  +	  << "<num>" << r.getNum() << "</num>" +	  << "<type>" << r.getTypeAsString() << "</type>" +	  << "<object_id>" << r.getObject()->getID() << "</object_id>" +	  << "<num_retries>" << r.getRetryCount() << "</num_retries>" +	  << "</request> "; +	return s; +} + + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient::Responder::RetryTimer +// +////////////////////////////////////////////////////////////////////////////////////// + +LLMediaDataClient::Responder::RetryTimer::RetryTimer(F32 time, Responder *mdr) +	: LLEventTimer(time), mResponder(mdr) +{ +} + +// virtual  +LLMediaDataClient::Responder::RetryTimer::~RetryTimer()  +{ +	LL_DEBUGS("LLMediaDataClient") << "~RetryTimer" << *(mResponder->getRequest()) << LL_ENDL; +	mResponder = NULL; +} + +// virtual +BOOL LLMediaDataClient::Responder::RetryTimer::tick() +{ +	// Instead of retrying, we just put the request back onto the queue +	LL_INFOS("LLMediaDataClient") << "RetryTimer fired for: " << *(mResponder->getRequest()) << "retrying" << LL_ENDL; +	mResponder->getRequest()->reEnqueue(); +	// Don't fire again +	return TRUE; +} + + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient::Responder +// +////////////////////////////////////////////////////////////////////////////////////// + +LLMediaDataClient::Responder::Responder(const request_ptr_t &request) +	: mRequest(request) +{ +} + +LLMediaDataClient::Responder::~Responder() +{ +	LL_DEBUGS("LLMediaDataClient") << "~Responder" << *(getRequest()) << LL_ENDL; +	mRequest = NULL; +} + +/*virtual*/ +void LLMediaDataClient::Responder::error(U32 status, const std::string& reason) +{ +	if (status == HTTP_SERVICE_UNAVAILABLE) +	{ +		F32 retry_timeout = mRequest->getRetryTimerDelay(); + +		mRequest->incRetryCount(); +		 +		if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())  +		{ +			LL_INFOS("LLMediaDataClient") << *mRequest << "got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL; + +			// Start timer (instances are automagically tracked by +			// InstanceTracker<> and LLEventTimer) +			new RetryTimer(F32(retry_timeout/*secs*/), this); +		} +		else { +			LL_INFOS("LLMediaDataClient") << *mRequest << "got SERVICE_UNAVAILABLE...retry count " <<  +				mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL; +		} +	} +	else { +		std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason; +		LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL; +	} +} + + +/*virtual*/ +void LLMediaDataClient::Responder::result(const LLSD& content) +{ +	LL_INFOS("LLMediaDataClient") << *mRequest << "result : " << ll_pretty_print_sd(content) << LL_ENDL; +} + + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient::Comparator +// +////////////////////////////////////////////////////////////////////////////////////// + +bool LLMediaDataClient::Comparator::operator() (const request_ptr_t &o1, const request_ptr_t &o2) const +{ +	if (o2.isNull()) return true; +	if (o1.isNull()) return false; + +	// The score is intended to be a measure of how close an object is or +	// how much screen real estate (interest) it takes up +	// Further away = lower score. +	// Lesser interest = lower score +	// For instance, here are some cases: +	// 1: Two items with no impl, closest one wins +	// 2: Two items with an impl: interest should rule, but distance is +	// still taken into account (i.e. something really close might take +	// precedence over a large item far away) +	// 3: One item with an impl, another without: item with impl wins  +	//	  (XXX is that what we want?)		  +	// Calculate the scores for each.   +	F64 o1_score = Comparator::getObjectScore(o1->getObject()); +	F64 o2_score = Comparator::getObjectScore(o2->getObject()); + +    // XXX Weird: a higher score should go earlier, but by observation I notice +    // that this causes further-away objects load first.  This is counterintuitive +    // to the priority_queue Comparator, which states that this function should +    // return 'true' if o1 should be *before* o2. +    // In other words, I'd have expected that the following should return +    // ( o1_score > o2_score). +	return ( o1_score < o2_score ); +} +	 +// static +F64 LLMediaDataClient::Comparator::getObjectScore(const LLMediaDataClientObject::ptr_t &obj) +{ +	// *TODO: make this less expensive? +	F64 dist = obj->getDistanceFromAvatar() + 0.1;	 // avoids div by 0 +	// square the distance so that they are in the same "unit magnitude" as +	// the interest (which is an area)  +	dist *= dist; +	F64 interest = obj->getTotalMediaInterest() + 1.0; +		 +	return interest/dist;	    +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient::PriorityQueue +// Queue of LLMediaDataClientObject smart pointers to request media for. +// +////////////////////////////////////////////////////////////////////////////////////// + +// dump the queue +std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue &q) +{ +	int i = 0; +	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = q.c.begin(); +	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = q.c.end(); +	while (iter < end) +	{ +		s << "\t" << i << "]: " << (*iter)->getObject()->getID().asString(); +		iter++; +		i++; +	} +	return s; +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient::QueueTimer +// Queue of LLMediaDataClientObject smart pointers to request media for. +// +////////////////////////////////////////////////////////////////////////////////////// + +LLMediaDataClient::QueueTimer::QueueTimer(F32 time, LLMediaDataClient *mdc) +	: LLEventTimer(time), mMDC(mdc) +{ +	mMDC->setIsRunning(true); +} + +LLMediaDataClient::QueueTimer::~QueueTimer() +{ +	LL_DEBUGS("LLMediaDataClient") << "~QueueTimer" << LL_ENDL; +	mMDC->setIsRunning(false); +	mMDC = NULL; +} + +// virtual +BOOL LLMediaDataClient::QueueTimer::tick() +{ +	if (NULL == mMDC->pRequestQueue) +	{ +		// Shutting down?  stop. +		LL_DEBUGS("LLMediaDataClient") << "queue gone" << LL_ENDL; +		return TRUE; +	} +	 +	LLMediaDataClient::PriorityQueue &queue = *(mMDC->pRequestQueue); +	 +	if (queue.empty()) +	{ +		LL_DEBUGS("LLMediaDataClient") << "queue empty: " << queue << LL_ENDL; +		return TRUE; +	} + +	LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, queue is:	  " << queue << LL_ENDL; + +	// Peel one off of the items from the queue, and execute request +	request_ptr_t request = queue.top(); +	llassert(!request.isNull()); +	const LLMediaDataClientObject *object = request->getObject(); +	bool performed_request = false; +	llassert(NULL != object); +	if (NULL != object && object->hasMedia()) +	{ +		std::string url = request->getCapability(); +		if (!url.empty()) +		{ +			const LLSD &sd_payload = request->getPayload(); +			LL_INFOS("LLMediaDataClient") << "Sending request for " << *request << LL_ENDL; + +			// Call the subclass for creating the responder +			LLHTTPClient::post(url, sd_payload, mMDC->createResponder(request)); +			performed_request = true; +		} +		else { +			LL_INFOS("LLMediaDataClient") << "NOT Sending request for " << *request << ": empty cap url!" << LL_ENDL; +		} +	} +	else { +		if (!object->hasMedia()) +		{ +			LL_INFOS("LLMediaDataClient") << "Not Sending request for " << *request << " hasMedia() is false!" << LL_ENDL; +		} +	} +	bool exceeded_retries = request->getRetryCount() > mMDC->mMaxNumRetries; +	if (performed_request || exceeded_retries) // Try N times before giving up  +	{ +		if (exceeded_retries) +		{ +			LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for "  +										  << mMDC->mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;  +			// XXX Should we bring up a warning dialog?? +		} +		queue.pop(); +	} +	else { +		request->incRetryCount(); +	} +	LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue is now: " << (*(mMDC->pRequestQueue)) << LL_ENDL; + +	return queue.empty(); +} +	 +void LLMediaDataClient::startQueueTimer()  +{ +	if (! mQueueTimerIsRunning) +	{ +		LL_INFOS("LLMediaDataClient") << "starting queue timer (delay=" << mQueueTimerDelay << " seconds)" << LL_ENDL; +		// LLEventTimer automagically takes care of the lifetime of this object +		new QueueTimer(mQueueTimerDelay, this); +	} +} +	 +void LLMediaDataClient::stopQueueTimer() +{ +	mQueueTimerIsRunning = false; +} +	 +void LLMediaDataClient::request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload) +{ +	if (object.isNull() || ! object->hasMedia()) return;  + +	// Push the object on the priority queue +	enqueue(new Request(getCapabilityName(), payload, object, this)); +} + +void LLMediaDataClient::enqueue(const Request *request) +{ +	LL_INFOS("LLMediaDataClient") << "Queuing request for " << *request << LL_ENDL; +	// Push the request on the priority queue +	// Sadly, we have to const-cast because items put into the queue are not const +	pRequestQueue->push(const_cast<LLMediaDataClient::Request*>(request)); +	LL_DEBUGS("LLMediaDataClient") << "Queue:" << (*pRequestQueue) << LL_ENDL; +	// Start the timer if not already running +	startQueueTimer(); +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLMediaDataClient +// +////////////////////////////////////////////////////////////////////////////////////// + +LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay, +									 F32 retry_timer_delay, +									 U32 max_retries) +	: mQueueTimerDelay(queue_timer_delay), +	  mRetryTimerDelay(retry_timer_delay), +	  mMaxNumRetries(max_retries), +	  mQueueTimerIsRunning(false) +{ +	pRequestQueue = new PriorityQueue(); +} + +LLMediaDataClient::~LLMediaDataClient() +{ +	stopQueueTimer(); + +	// This should clear the queue, and hopefully call all the destructors. +	LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClient destructor: queue: " <<  +		(pRequestQueue->empty() ? "<empty> " : "<not empty> ") << (*pRequestQueue) << LL_ENDL; +	delete pRequestQueue; +	pRequestQueue = NULL; +} + +bool LLMediaDataClient::isEmpty() const +{ +	return (NULL == pRequestQueue) ? true : pRequestQueue->empty(); +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLObjectMediaDataClient +// Subclass of LLMediaDataClient for the ObjectMedia cap +// +////////////////////////////////////////////////////////////////////////////////////// + +LLMediaDataClient::Responder *LLObjectMediaDataClient::createResponder(const request_ptr_t &request) const +{ +	return new LLObjectMediaDataClient::Responder(request); +} + +const char *LLObjectMediaDataClient::getCapabilityName() const  +{ +	return "ObjectMedia"; +} + +void LLObjectMediaDataClient::fetchMedia(LLMediaDataClientObject *object) +{ +	LLSD sd_payload; +	sd_payload["verb"] = "GET"; +	sd_payload[LLTextureEntry::OBJECT_ID_KEY] = object->getID(); +	request(object, sd_payload); +} + +void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object) +{ +	LLSD sd_payload; +	sd_payload["verb"] = "UPDATE"; +	sd_payload[LLTextureEntry::OBJECT_ID_KEY] = object->getID(); +	LLSD object_media_data; +	int i = 0; +	int end = object->getMediaDataCount(); +	for ( ; i < end ; ++i)  +	{ +		object_media_data.append(object->getMediaDataLLSD(i)); +	} +	sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data; +		 +	LL_INFOS("LLMediaDataClient") << "update media data: " << object->getID() << " " << ll_pretty_print_sd(sd_payload) << LL_ENDL; +	 +	request(object, sd_payload); +} + +/*virtual*/ +void LLObjectMediaDataClient::Responder::result(const LLSD& content) +{ +	const LLMediaDataClient::Request::Type type = getRequest()->getType(); +	llassert(type == LLMediaDataClient::Request::GET || type == LLMediaDataClient::Request::UPDATE) +	if (type == LLMediaDataClient::Request::GET) +	{ +		LL_INFOS("LLMediaDataClient") << *(getRequest()) << "GET returned: " << ll_pretty_print_sd(content) << LL_ENDL; +		 +		// Look for an error +		if (content.has("error")) +		{ +			const LLSD &error = content["error"]; +			LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" <<  +				error["code"].asString() << ": " << error["message"].asString() << LL_ENDL; +			 +			// XXX Warn user? +		} +		else { +			// Check the data +			const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY]; +			if (object_id != getRequest()->getObject()->getID())  +			{ +				// NOT good, wrong object id!! +				LL_WARNS("LLMediaDataClient") << *(getRequest()) << "DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL; +				return; +			} +			 +			// Otherwise, update with object media data +			getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY]); +		} +	} +	else if (type == LLMediaDataClient::Request::UPDATE) +	{ +		// just do what our superclass does +		LLMediaDataClient::Responder::result(content); +	} +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// LLObjectMediaNavigateClient +// Subclass of LLMediaDataClient for the ObjectMediaNavigate cap +// +////////////////////////////////////////////////////////////////////////////////////// +LLMediaDataClient::Responder *LLObjectMediaNavigateClient::createResponder(const request_ptr_t &request) const +{ +	return new LLObjectMediaNavigateClient::Responder(request); +} + +const char *LLObjectMediaNavigateClient::getCapabilityName() const  +{ +	return "ObjectMediaNavigate"; +} + +void LLObjectMediaNavigateClient::navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url) +{ +	LLSD sd_payload; +	sd_payload[LLTextureEntry::OBJECT_ID_KEY] = object->getID(); +	sd_payload[LLMediaEntry::CURRENT_URL_KEY] = url; +	sd_payload[LLTextureEntry::TEXTURE_INDEX_KEY] = (LLSD::Integer)texture_index; +	request(object, sd_payload); +} + +/*virtual*/ +void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason) +{ +	// Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base +	// class +	if (status == HTTP_SERVICE_UNAVAILABLE) +	{ +		LLMediaDataClient::Responder::error(status, reason); +	} +	else { +		// bounce the face back +		LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: http code=" << status << LL_ENDL; +		const LLSD &payload = getRequest()->getPayload(); +		// bounce the face back +		getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]); +	} +} + +/*virtual*/ +void LLObjectMediaNavigateClient::Responder::result(const LLSD& content) +{ +	LL_DEBUGS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_pretty_print_sd(content) << LL_ENDL; +	 +	if (content.has("error")) +	{ +		const LLSD &error = content["error"]; +		int error_code = error["code"]; +		 +		if (ERROR_PERMISSION_DENIED_CODE == error_code) +		{ +			LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Navigation denied: bounce back" << LL_ENDL; +			const LLSD &payload = getRequest()->getPayload(); +			// bounce the face back +			getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]); +		} +		else { +			LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<  +				error["code"].asString() << ": " << error["message"].asString() << LL_ENDL; +		}			  +		// XXX Warn user? +	} +	else { +		// just do what our superclass does +		LLMediaDataClient::Responder::result(content); +	} +} diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h new file mode 100644 index 0000000000..9d0aa0981e --- /dev/null +++ b/indra/newview/llmediadataclient.h @@ -0,0 +1,309 @@ +/**  + * @file llmediadataclient.h + * @brief class for queueing up requests to the media service + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, 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_LLMEDIADATACLIENT_H +#define LL_LLMEDIADATACLIENT_H + +#include "llhttpclient.h" +#include <queue> +#include "llrefcount.h" +#include "llpointer.h" +#include "lltimer.h" + + +// Link seam for LLVOVolume +class LLMediaDataClientObject : public LLRefCount +{ +public: +	// Get the number of media data items +	virtual U8 getMediaDataCount() const = 0; +	// Get the media data at index, as an LLSD +	virtual LLSD getMediaDataLLSD(U8 index) const = 0; +	// Get this object's UUID +	virtual LLUUID getID() const = 0; +	// Navigate back to previous URL +	virtual void mediaNavigateBounceBack(U8 index) = 0; +	// Does this object have media? +	virtual bool hasMedia() const = 0; +	// Update the object's media data to the given array +	virtual void updateObjectMediaData(LLSD const &media_data_array) = 0; +	// Return the distance from the object to the avatar +	virtual F64 getDistanceFromAvatar() const = 0; +	// Return the total "interest" of the media (on-screen area) +	virtual F64 getTotalMediaInterest() const = 0; +	// Return the given cap url +	virtual std::string getCapabilityUrl(const std::string &name) const = 0; + +	// smart pointer +	typedef LLPointer<LLMediaDataClientObject> ptr_t; +}; + +// This object creates a priority queue for requests. +// Abstracts the Cap URL, the request, and the responder +class LLMediaDataClient : public LLRefCount +{ +public: +    LOG_CLASS(LLMediaDataClient); +     +    const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s) +	const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs +	const static U32 MAX_RETRIES;// = 4; + +	// Constructor +	LLMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY, +					  F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY, +		              U32 max_retries = MAX_RETRIES); +	 +	// Make the request +	void request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload); + +	F32 getRetryTimerDelay() const { return mRetryTimerDelay; } +	 +	// Returns true iff the queue is empty +	bool isEmpty() const;  +	 +protected: +	// Destructor +	virtual ~LLMediaDataClient(); // use unref +     +	// Request +	class Request : public LLRefCount +	{ +	public: +        enum Type { +            GET, +            UPDATE, +            NAVIGATE +        }; +         +		Request(const std::string &cap_name, const LLSD& sd_payload, LLMediaDataClientObject *obj, LLMediaDataClient *mdc); +		const std::string &getCapName() const { return mCapName; } +		const LLSD &getPayload() const { return mPayload; } +		LLMediaDataClientObject *getObject() const { return mObject; } + +        U32 getNum() const { return mNum; } + +		U32 getRetryCount() const { return mRetryCount; } +		void incRetryCount() { mRetryCount++; } +		 +		// Note: may return empty string! +		std::string getCapability() const; +         +        Type getType() const; +		const char *getTypeAsString() const; +		 +		// Re-enqueue thyself +		void reEnqueue() const; +		 +		F32 getRetryTimerDelay() const; +		U32 getMaxNumRetries() const; +		 +	public: +		friend std::ostream& operator<<(std::ostream &s, const Request &q); +		 +    protected: +        virtual ~Request(); // use unref(); +         +	private: +		std::string mCapName; +		LLSD mPayload; +		LLMediaDataClientObject::ptr_t mObject; +		// Simple tracking +		const U32 mNum; +		static U32 sNum; +        U32 mRetryCount; +		 +		// Back pointer to the MDC...not a ref! +		LLMediaDataClient *mMDC; +	}; +	typedef LLPointer<Request> request_ptr_t; + +	// Responder +	class Responder : public LLHTTPClient::Responder +	{ +	public: +		Responder(const request_ptr_t &request); +		//If we get back an error (not found, etc...), handle it here +		virtual void error(U32 status, const std::string& reason); +		//If we get back a normal response, handle it here.	 Default just logs it. +		virtual void result(const LLSD& content); + +		const request_ptr_t &getRequest() const { return mRequest; } + +    protected: +		virtual ~Responder(); +         +	private: + +		class RetryTimer : public LLEventTimer +		{ +		public: +			RetryTimer(F32 time, Responder *); +			virtual ~RetryTimer(); +			virtual BOOL tick(); +		private: +			// back-pointer +			boost::intrusive_ptr<Responder> mResponder; +		}; +		 +		request_ptr_t mRequest; +	}; +	 +protected: +	 +	void enqueue(const Request*); +	 +	// Subclasses must override this factory method to return a new responder +	virtual Responder *createResponder(const request_ptr_t &request) const = 0; +	 +	// Subclasses must override to return a cap name +	virtual const char *getCapabilityName() const = 0; +	 +private: +	 +	// Comparator for PriorityQueue +	class Comparator +	{ +	public: +		bool operator() (const request_ptr_t &o1, const request_ptr_t &o2) const; +	private: +		static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj); +	}; +	 +    // PriorityQueue +	class PriorityQueue : public std::priority_queue< +		request_ptr_t,  +		std::vector<request_ptr_t>,  +		Comparator > +	{ +	public: +		friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q); +	}; +     +	friend std::ostream& operator<<(std::ostream &s, const Request &q); +    friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q); + +	class QueueTimer : public LLEventTimer +	{ +	public: +		QueueTimer(F32 time, LLMediaDataClient *mdc); +		virtual BOOL tick(); +    protected: +		virtual ~QueueTimer(); +	private: +		// back-pointer +		LLPointer<LLMediaDataClient> mMDC; +	}; + +	void startQueueTimer(); +	void stopQueueTimer(); +	void setIsRunning(bool val) { mQueueTimerIsRunning = val; } + +	const F32 mQueueTimerDelay; +	const F32 mRetryTimerDelay; +	const U32 mMaxNumRetries; +	 +	bool mQueueTimerIsRunning; +	 +	PriorityQueue *pRequestQueue; +}; + + +// MediaDataResponder specific for the ObjectMedia cap +class LLObjectMediaDataClient : public LLMediaDataClient +{ +public: +    LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY, +							F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY, +							U32 max_retries = MAX_RETRIES) +		: LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries) +		{} +    ~LLObjectMediaDataClient() {} +     +	void fetchMedia(LLMediaDataClientObject *object);  +    void updateMedia(LLMediaDataClientObject *object); +     +protected: +	// Subclasses must override this factory method to return a new responder +	virtual Responder *createResponder(const request_ptr_t &request) const; +	 +	// Subclasses must override to return a cap name +	virtual const char *getCapabilityName() const; +     +    class Responder : public LLMediaDataClient::Responder +    { +    public: +        Responder(const request_ptr_t &request) +            : LLMediaDataClient::Responder(request) {} +        virtual void result(const LLSD &content); +    }; +}; + + +// MediaDataResponder specific for the ObjectMediaNavigate cap +class LLObjectMediaNavigateClient : public LLMediaDataClient +{ +public: +	// NOTE: from llmediaservice.h +	static const int ERROR_PERMISSION_DENIED_CODE = 8002; +	 +    LLObjectMediaNavigateClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY, +								F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY, +								U32 max_retries = MAX_RETRIES) +		: LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries) +		{} +    ~LLObjectMediaNavigateClient() {} +     +    void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url); +     +protected: +	// Subclasses must override this factory method to return a new responder +	virtual Responder *createResponder(const request_ptr_t &request) const; +	 +	// Subclasses must override to return a cap name +	virtual const char *getCapabilityName() const; + +    class Responder : public LLMediaDataClient::Responder +    { +    public: +        Responder(const request_ptr_t &request) +            : LLMediaDataClient::Responder(request) {} +		virtual void error(U32 status, const std::string& reason); +        virtual void result(const LLSD &content); +    private: +        void mediaNavigateBounceBack(); +    }; + +}; + + +#endif // LL_LLMEDIADATACLIENT_H diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 599e6b6859..7c8ffa3b94 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -72,11 +72,9 @@ public:  	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);  	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata); -	virtual void	onClose		(bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); } +	/*virtual*/ void	onOpen	(const LLSD& key); -	virtual void	onOpen		(const LLSD& key); - -	virtual void	draw		(); +	/*virtual*/ void	draw	();  private:  	void	add_timestamped_line(const LLChat& chat, const LLColor4& color); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 1ed5fa4357..a03902caba 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -78,11 +78,11 @@ public:  	 * Profile tabs should close any opened panels here.  	 *  	 * Called from LLPanelProfile::onOpen() before opening new profile. -	 * See LLPanelpicks::onClose for example. LLPanelPicks closes picture info panel +	 * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel  	 * before new profile is displayed, otherwise new profile will   	 * be hidden behind picture info panel.  	 */ -	virtual void onClose() {} +	virtual void onClosePanel() {}  	/**  	 * Resets controls visibility, state, etc. diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c61b987b1c..ee0426c7df 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -786,8 +786,8 @@ void LLPanelFace::getState()  		childSetEnabled("button align",FALSE);  		childSetEnabled("button apply",FALSE); -		childSetEnabled("has media", FALSE); -		childSetEnabled("media info set", FALSE); +		//childSetEnabled("has media", FALSE); +		//childSetEnabled("media info set", FALSE);  	}  } diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index be40d6fb5f..a33d9604fe 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -49,6 +49,8 @@  #include "llpanelcontents.h"  #include "llpluginclassmedia.h"  #include "llfloatermediasettings.h" +#include "llfloatertools.h" +#include "lltrans.h"  ////////////////////////////////////////////////////////////////////////////////  // @@ -155,43 +157,11 @@ void LLPanelMediaSettingsGeneral::draw()  	};  	// current URL can change over time. -	updateCurrentURL(); +//	updateCurrentURL();  	// enable/disable RESRET button depending on permissions  	// since this is the same as a navigate action -	U32 owner_mask_on; -	U32 owner_mask_off; -	U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,  -												&owner_mask_on, &owner_mask_off ); -	U32 group_mask_on; -	U32 group_mask_off; -	U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,  -												&group_mask_on, &group_mask_off ); -	U32 everyone_mask_on; -	U32 everyone_mask_off; -	S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,  -												&everyone_mask_on, &everyone_mask_off ); -	 -	bool user_can_press_reset = false; - -	// if perms we got back are valid -	if ( valid_owner_perms && -		 valid_group_perms &&  -		 valid_everyone_perms ) -	{ -		// if user is allowed to press the RESET button -		if ( ( owner_mask_on & PERM_MODIFY ) || -			 ( group_mask_on & PERM_MODIFY ) ||  -			 ( group_mask_on & PERM_MODIFY ) ) -		{ -			user_can_press_reset = true; -		} -		else -		// user is NOT allowed to press the RESET button -		{ -			user_can_press_reset = false; -		}; -	}; +	bool user_can_press_reset = gFloaterTools->selectedMediaEditable();  	// several places modify this widget so we must collect states in one place  	if ( reset_button_is_active ) @@ -216,7 +186,7 @@ void LLPanelMediaSettingsGeneral::draw()  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsGeneral::clearValues( void* userdata ) +void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable)  {	  	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;  	self->mAltImageEnable ->clear(); @@ -230,12 +200,23 @@ void LLPanelMediaSettingsGeneral::clearValues( void* userdata )  	self->mHeightPixels->clear();  	self->mHomeURL->clear();  	self->mWidthPixels->clear(); +	self->mAltImageEnable ->setEnabled(editable); +	self->mAutoLoop ->setEnabled(editable); +	self->mAutoPlay ->setEnabled(editable); +	self->mAutoScale ->setEnabled(editable); +	self->mAutoZoom  ->setEnabled(editable); +	self->mControls ->setEnabled(editable); +	self->mCurrentURL ->setEnabled(editable); +	self->mFirstClick ->setEnabled(editable); +	self->mHeightPixels ->setEnabled(editable); +	self->mHomeURL ->setEnabled(editable); +	self->mWidthPixels ->setEnabled(editable);  	self->mPreviewMedia->unloadMediaSource();   }  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings ) +void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings ,bool editable)  {  	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; @@ -243,6 +224,29 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_  	//llinfos << ll_pretty_print_sd(media_settings) << llendl;  	//llinfos << "---------------" << llendl; +	// IF all the faces have media (or all dont have media) +	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			self->mHomeURL ->setText(LLTrans::getString("Multiple Media")); +			return; +		} +		 +	} +	else +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			self->mHomeURL ->setText(LLTrans::getString("Multiple Media")); +			return; +		}			 +		 +	}  	std::string base_key( "" );  	std::string tentative_key( "" ); @@ -293,10 +297,11 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_  				static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )->  					setValue( media_settings[ base_key ].asInteger() ); +			data_set[ i ].ctrl_ptr->setEnabled(editable);  			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );  		};  	}; - +	  	// interrogates controls and updates widgets as required  	self->updateMediaPreview();  	self->updateCurrentURL(); @@ -322,30 +327,17 @@ void LLPanelMediaSettingsGeneral::updateMediaPreview()  // Helper to set current URL  void LLPanelMediaSettingsGeneral::updateCurrentURL()  { -	if( mPreviewMedia ) +	if( mCurrentURL->getText().empty() )  	{ -		LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin(); -		if( media_plugin ) -		{ -			// get current URL from plugin and display -			std::string current_location = media_plugin->getLocation(); -			if ( current_location.length() ) -			{ -				childSetText( "current_url", current_location ); -			} -			else -			// current location may be empty so we need to clear it -			{ -				const std::string empty_string( "" ); -				childSetText( "current_url", empty_string ); -			}; -		}; -	}; +		childSetText( "current_url", mHomeURL->getText() ); +	} +	  }  //////////////////////////////////////////////////////////////////////////////// -void LLPanelMediaSettingsGeneral::onClose() +// virtual +void LLPanelMediaSettingsGeneral::onClose(bool app_quitting)  {  	if(mPreviewMedia)  	{ @@ -374,7 +366,7 @@ void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl()  void LLPanelMediaSettingsGeneral::apply( void* userdata )  {  	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; - +	self->mHomeURL->onCommit();  	// build LLSD Fragment  	LLSD media_data_general;  	self->getValues(media_data_general); @@ -393,8 +385,7 @@ void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )      fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();      fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();      fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex(); -    // XXX Don't send current URL! -    //fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue(); +    fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();      fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();      fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();      fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue(); diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h index 24678a3a07..5acfa39181 100644 --- a/indra/newview/llpanelmediasettingsgeneral.h +++ b/indra/newview/llpanelmediasettingsgeneral.h @@ -48,7 +48,9 @@ class LLPanelMediaSettingsGeneral : public LLPanel  {  public:  	BOOL postBuild(); -	virtual void draw(); +	/*virtual*/ void draw(); +	/*virtual*/ void onClose(bool app_quitting); +  	static void apply(void*);      void getValues(LLSD &fill_me_in); @@ -56,14 +58,12 @@ public:  	~LLPanelMediaSettingsGeneral();  	void setParent( LLFloaterMediaSettings* parent ); -	static void initValues( void* userdata, const LLSD& media_settings ); -	static void clearValues( void* userdata ); +	static void initValues( void* userdata, const LLSD& media_settings ,bool editable); +	static void clearValues( void* userdata, bool editable);  	void updateMediaPreview();  	void updateCurrentURL(); -	void onClose(); -  protected:  	LLFloaterMediaSettings* mParent; @@ -74,7 +74,7 @@ private:  	LLComboBox* mControls;  	LLCheckBoxCtrl* mAutoLoop;  	LLCheckBoxCtrl* mFirstClick; -	LLTextureCtrl* mMediaPreview; +//	LLTextureCtrl* mMediaPreview;  	LLCheckBoxCtrl* mAutoZoom;  	LLCheckBoxCtrl* mAutoPlay;  	LLCheckBoxCtrl* mAutoScale; diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp index d6a2677f4b..4d84874e7a 100644 --- a/indra/newview/llpanelmediasettingspermissions.cpp +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -49,7 +49,8 @@  #include "llselectmgr.h"  #include "llmediaentry.h"  #include "llnamebox.h" - +#include "lltrans.h" +#include "llfloatermediasettings.h"  ////////////////////////////////////////////////////////////////////////////////  //  LLPanelMediaSettingsPermissions::LLPanelMediaSettingsPermissions() : @@ -119,7 +120,7 @@ void LLPanelMediaSettingsPermissions::draw()  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsPermissions::clearValues( void* userdata ) +void LLPanelMediaSettingsPermissions::clearValues( void* userdata, bool editable)  {	  	LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;  	self->mPermsOwnerInteract->clear(); @@ -128,16 +129,41 @@ void LLPanelMediaSettingsPermissions::clearValues( void* userdata )  	self->mPermsGroupControl->clear();  	self->mPermsWorldInteract ->clear();  	self->mPermsWorldControl ->clear(); -//	mPermsGroupName ->setValue(0); - +	 +	self->mPermsOwnerInteract->setEnabled(editable); +	self->mPermsOwnerControl ->setEnabled(editable); +	self->mPermsGroupInteract->setEnabled(editable); +	self->mPermsGroupControl ->setEnabled(editable); +	self->mPermsWorldInteract->setEnabled(editable); +	self->mPermsWorldControl ->setEnabled(editable);  }  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings ) +void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings ,  bool editable)  {      LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata; +	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			return; +		} +		 +	} +	else +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			return; +		}			 +		 +	}      std::string base_key( "" );      std::string tentative_key( "" ); @@ -178,10 +204,17 @@ void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& me              if ( data_set[ i ].ctrl_type == "LLComboBox" )                  static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->                      setCurrentByIndex( media_settings[ base_key ].asInteger() ); - +			data_set[ i ].ctrl_ptr->setEnabled(editable);              data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );          };      }; +	self->childSetEnabled("media_perms_label_owner", editable ); +	self->childSetText("media_perms_label_owner",  LLTrans::getString("Media Perms Owner") ); +	self->childSetEnabled("media_perms_label_group", editable ); +	self->childSetText("media_perms_label_group",  LLTrans::getString("Media Perms Group") ); +	self->childSetEnabled("media_perms_label_anyone", editable ); +	self->childSetText("media_perms_label_anyone", LLTrans::getString("Media Perms Anyone") ); +	  }  //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelmediasettingspermissions.h b/indra/newview/llpanelmediasettingspermissions.h index ce293e07b9..ecc50e3582 100644 --- a/indra/newview/llpanelmediasettingspermissions.h +++ b/indra/newview/llpanelmediasettingspermissions.h @@ -55,8 +55,8 @@ class LLPanelMediaSettingsPermissions : public LLPanel  		LLPanelMediaSettingsPermissions();  		~LLPanelMediaSettingsPermissions(); -		static void initValues( void* userdata, const LLSD& media_settings ); -		static void clearValues( void* userdata ); +		static void initValues( void* userdata, const LLSD& media_settings, bool editable ); +		static void clearValues( void* userdata,  bool editable);  	private:          LLCheckBoxCtrl* mPermsOwnerInteract; diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp index a4eee82aa9..cea105d7de 100644 --- a/indra/newview/llpanelmediasettingssecurity.cpp +++ b/indra/newview/llpanelmediasettingssecurity.cpp @@ -44,7 +44,7 @@  #include "llselectmgr.h"  #include "llmediaentry.h"  #include "llfloaterwhitelistentry.h" - +#include "llfloatermediasettings.h"  ////////////////////////////////////////////////////////////////////////////////  //  LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity() @@ -110,10 +110,30 @@ void LLPanelMediaSettingsSecurity::draw()  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings ) +void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings , bool editable)  {  	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; +	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			return; +		} +		 +	} +	else +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			return; +		}			 +		 +	}  	std::string base_key( "" );  	std::string tentative_key( "" ); @@ -163,7 +183,7 @@ void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media  					++iter;  				};  			}; - +			data_set[ i ].ctrl_ptr->setEnabled(editable);  			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );  		};  	}; @@ -171,11 +191,13 @@ void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsSecurity::clearValues( void* userdata ) +void LLPanelMediaSettingsSecurity::clearValues( void* userdata , bool editable)  {  	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;  	self->mEnableWhiteList->clear();  	self->mWhiteListList->deleteAllItems(); +	self->mEnableWhiteList->setEnabled(editable); +	self->mWhiteListList->setEnabled(editable);  }  ////////////////////////////////////////////////////////////////////////////////  // static diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h index d77509897d..b7cf67c039 100644 --- a/indra/newview/llpanelmediasettingssecurity.h +++ b/indra/newview/llpanelmediasettingssecurity.h @@ -49,8 +49,8 @@ class LLPanelMediaSettingsSecurity : public LLPanel  		LLPanelMediaSettingsSecurity();  		~LLPanelMediaSettingsSecurity(); -		static void initValues( void* userdata, const LLSD& media_settings ); -		static void clearValues( void* userdata ); +		static void initValues( void* userdata, const LLSD& media_settings,bool editable ); +		static void clearValues( void* userdata, bool editable);  		void addWhiteListItem(const std::string& url);  	private: diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index e74afba25a..979e9618da 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -463,7 +463,8 @@ void LLPickItem::processProperties(void *data, EAvatarProcessorType type)  	LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);  } -void LLPanelPicks::onClose() +// virtual +void LLPanelPicks::onClosePanel()  {  	// Toggle off Pick Info panel if it is visible.  	if(mPickPanel && mPickPanel->getVisible()) diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 7ebdc3089c..18c571c735 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -77,7 +77,7 @@ public:  	/**  	 * Closes LLPanelPick if it is visible.  	 */ -	/*virtual*/ void onClose(); +	/*virtual*/ void onClosePanel();  private:  	void onClickDelete(); diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index eb269fabe3..d6be0a9419 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -44,14 +44,16 @@  #include "llqueryflags.h"  #include "llbutton.h" +#include "llcombobox.h"  #include "lliconctrl.h" -#include "lllineeditor.h"  #include "llscrollcontainer.h"  #include "lltextbox.h" +#include "lltrans.h"  #include "llaccordionctrl.h"  #include "llaccordionctrltab.h"  #include "llagent.h" +#include "llagentui.h"  #include "llavatarpropertiesprocessor.h"  #include "llfloaterworldmap.h"  #include "llinventorymodel.h" @@ -64,6 +66,16 @@  #include "llviewertexteditor.h"  #include "llworldmap.h" +//---------------------------------------------------------------------------- +// Aux types and methods +//---------------------------------------------------------------------------- + +typedef std::pair<LLUUID, std::string> folder_pair_t; + +static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); +static std::string getFullFolderName(const LLViewerInventoryCategory* cat); +static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats); +  static LLRegisterPanelClassWrapper<LLPanelPlaceInfo> t_place_info("panel_place_info");  LLPanelPlaceInfo::LLPanelPlaceInfo() @@ -141,11 +153,8 @@ BOOL LLPanelPlaceInfo::postBuild()  	mCreated = getChild<LLTextBox>("created");  	mTitleEditor = getChild<LLLineEditor>("title_editor"); -	mTitleEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, TITLE)); -  	mNotesEditor = getChild<LLTextEditor>("notes_editor"); -	mNotesEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, NOTE)); -	mNotesEditor->setCommitOnFocusLost(true); +	mFolderCombo = getChild<LLComboBox>("folder_combo");  	LLScrollContainer* scroll_container = getChild<LLScrollContainer>("scroll_container");  	scroll_container->setBorderVisible(FALSE); @@ -316,6 +325,7 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	LLPanel* landmark_edit_panel = getChild<LLPanel>("landmark_edit_panel");  	bool is_info_type_agent = type == AGENT; +	bool is_info_type_create_landmark = type == CREATE_LANDMARK;  	bool is_info_type_landmark = type == LANDMARK;  	bool is_info_type_teleport_history = type == TELEPORT_HISTORY; @@ -329,7 +339,10 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	mLastVisited->setVisible(is_info_type_teleport_history);  	landmark_info_panel->setVisible(is_info_type_landmark); -	landmark_edit_panel->setVisible(is_info_type_landmark || type == CREATE_LANDMARK); +	landmark_edit_panel->setVisible(is_info_type_landmark || is_info_type_create_landmark); + +	getChild<LLTextBox>("folder_lable")->setVisible(is_info_type_create_landmark); +	mFolderCombo->setVisible(is_info_type_create_landmark);  	getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent); @@ -337,6 +350,11 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	{  		case CREATE_LANDMARK:  			mCurrentTitle = getString("title_create_landmark"); + +			mTitleEditor->setEnabled(TRUE); +			mNotesEditor->setEnabled(TRUE); + +			populateFoldersList();  		break;  		case AGENT: @@ -351,6 +369,11 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  		case LANDMARK:  			mCurrentTitle = getString("title_landmark"); + +			mTitleEditor->setEnabled(FALSE); +			mNotesEditor->setEnabled(FALSE); + +			populateFoldersList();  		break;  		case TELEPORT_HISTORY: @@ -485,10 +508,9 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  						parcel_data.sim_name.c_str(), region_x, region_y, region_z);  		mRegionName->setText(name);  	} -	 +  	if (mInfoType == CREATE_LANDMARK)  	{ -  		if (parcel_data.name.empty())  		{  			mTitleEditor->setText(name); @@ -498,7 +520,15 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  			mTitleEditor->setText(parcel_data.name);  		} -		mNotesEditor->setText(LLStringUtil::null); +		// FIXME: Creating landmark works only for current agent location. +		std::string desc; +		LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, gAgent.getPositionAgent()); +		mNotesEditor->setText(desc); + +		if (!LLLandmarkActions::landmarkAlreadyExists()) +		{ +			createLandmark(mFolderCombo->getValue().asUUID()); +		}  	}  } @@ -694,7 +724,6 @@ void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel,  													 &rent_price,  													 &for_sale,  													 &dwell); -  	if (for_sale)  	{  		// Adding "For Sale" flag in remote parcel response format. @@ -803,52 +832,42 @@ void LLPanelPlaceInfo::updateLastVisitedText(const LLDate &date)  	}  } -void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) +void LLPanelPlaceInfo::toggleLandmarkEditMode(BOOL enabled)  { -	LLInventoryItem* item = gInventory.getItem(mLandmarkID); -	if (!item) -		return; - -	std::string current_value; -	std::string item_value; -	if (type == TITLE) +	// If switching to edit mode while creating landmark +	// the "Create Landmark" title remains. +	if (enabled && mInfoType != CREATE_LANDMARK)  	{ -		if (mTitleEditor) -		{ -			current_value = mTitleEditor->getText(); -			item_value = item->getName(); -		} +		mTitle->setText(getString("title_edit_landmark"));  	}  	else  	{ -		if (mNotesEditor) -		{ -			current_value = mNotesEditor->getText(); -			item_value = item->getDescription(); -		} +		mTitle->setText(mCurrentTitle);  	} -	LLStringUtil::trim(current_value); +	mTitleEditor->setEnabled(enabled); +	mNotesEditor->setReadOnly(!enabled); +	mFolderCombo->setVisible(enabled); +	getChild<LLTextBox>("folder_lable")->setVisible(enabled); -	if (!current_value.empty() && -		item_value != current_value && -	    gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) -	{ -		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +	// HACK: To change the text color in a text editor +	// when it was enabled/disabled we set the text once again. +	mNotesEditor->setText(mNotesEditor->getText()); +} -		if (type == TITLE) -		{ -			new_item->rename(current_value); -		} -		else -		{ -			new_item->setDescription(current_value); -		} +const std::string& LLPanelPlaceInfo::getLandmarkTitle() const +{ +	return mTitleEditor->getText(); +} -		new_item->updateServer(FALSE); -		gInventory.updateItem(new_item); -		gInventory.notifyObservers(); -	} +const std::string LLPanelPlaceInfo::getLandmarkNotes() const +{ +	return mNotesEditor->getText(); +} + +const LLUUID LLPanelPlaceInfo::getLandmarkFolder() const +{ +	return mFolderCombo->getValue().asUUID();  }  void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id) @@ -921,3 +940,91 @@ void LLPanelPlaceInfo::handleVisibilityChange (BOOL new_visibility)  		}  	}  } + +void LLPanelPlaceInfo::populateFoldersList() +{ +	// Collect all folders that can contain landmarks. +	LLInventoryModel::cat_array_t cats; +	collectLandmarkFolders(cats); + +	mFolderCombo->removeall(); + +	// Put the "Landmarks" folder first in list. +	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); +	const LLViewerInventoryCategory* cat = gInventory.getCategory(landmarks_id); +	if (!cat) +	{ +		llwarns << "Cannot find the landmarks folder" << llendl; +	} +	std::string cat_full_name = getFullFolderName(cat); +	mFolderCombo->add(cat_full_name, cat->getUUID()); + +	typedef std::vector<folder_pair_t> folder_vec_t; +	folder_vec_t folders; +	// Sort the folders by their full name. +	for (S32 i = 0; i < cats.count(); i++) +	{ +		cat = cats.get(i); +		cat_full_name = getFullFolderName(cat); +		folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); +	} +	sort(folders.begin(), folders.end(), cmp_folders); + +	// Finally, populate the combobox. +	for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++) +		mFolderCombo->add(it->second, LLSD(it->first)); +} + +static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) +{ +	return left.second < right.second; +} + +static std::string getFullFolderName(const LLViewerInventoryCategory* cat) +{ +	std::string name = cat->getName(); +	LLUUID parent_id; + +	// translate category name, if it's right below the root +	// FIXME: it can throw notification about non existent string in strings.xml +	if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID()) +	{ +		LLTrans::findString(name, "InvFolder " + name); +	} + +	// we don't want "My Inventory" to appear in the name +	while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID()) +	{ +		cat = gInventory.getCategory(parent_id); +		name = cat->getName() + "/" + name; +	} + +	return name; +} + +static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) +{ +	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + +	// Add descendent folders of the "Landmarks" category. +	LLInventoryModel::item_array_t items; // unused +	LLIsType is_category(LLAssetType::AT_CATEGORY); +	gInventory.collectDescendentsIf( +		landmarks_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		is_category); + +	// Add the "My Favorites" category. +	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); +	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); +	if (!favorites_cat) +	{ +		llwarns << "Cannot find the favorites folder" << llendl; +	} +	else +	{ +		cats.put(favorites_cat); +	} +} diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 23a845bc20..49aa195490 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -42,6 +42,7 @@  #include "llremoteparcelrequest.h"  class LLButton; +class LLComboBox;  class LLInventoryItem;  class LLLineEditor;  class LLPanelPick; @@ -117,18 +118,19 @@ public:  							 const std::string& first,  							 const std::string& last); +	void toggleLandmarkEditMode(BOOL enabled); + +	const std::string& getLandmarkTitle() const; +	const std::string getLandmarkNotes() const; +	const LLUUID getLandmarkFolder() const; +  	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	/*virtual*/ void handleVisibilityChange (BOOL new_visibility);  private: -	enum LANDMARK_INFO_TYPE -	{ -		TITLE, -		NOTE -	}; -	void onCommitTitleOrNote(LANDMARK_INFO_TYPE type); +	void populateFoldersList();  	LLUUID			mParcelID;  	LLUUID			mRequestedID; @@ -182,6 +184,7 @@ private:  	LLTextBox*			mCreated;  	LLLineEditor*		mTitleEditor;  	LLTextEditor*		mNotesEditor; +	LLComboBox*			mFolderCombo;  	LLPanel*            mScrollingPanel;  	LLPanel*			mInfoPanel;  	LLMediaPanel*		mMediaPanel; diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 80ecc95afb..35206f54c7 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -40,16 +40,19 @@  #include "lllandmark.h"  #include "llparcel.h" +#include "llcombobox.h" +#include "llfiltereditor.h"  #include "llfloaterreg.h"  #include "llnotifications.h" -#include "llfiltereditor.h"  #include "lltabcontainer.h" +#include "lltexteditor.h"  #include "lltrans.h"  #include "lluictrlfactory.h"  #include "llagent.h"  #include "llavatarpropertiesprocessor.h"  #include "llfloaterworldmap.h" +#include "llinventorybridge.h"  #include "llinventorymodel.h"  #include "lllandmarkactions.h"  #include "lllandmarklist.h" @@ -74,9 +77,6 @@ static const std::string TELEPORT_HISTORY_INFO_TYPE	= "teleport_history";  // Helper functions  static bool is_agent_in_selected_parcel(LLParcel* parcel); -static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); -static std::string getFullFolderName(const LLViewerInventoryCategory* cat); -static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);  static void onSLURLBuilt(std::string& slurl);  static void setAllChildrenVisible(LLView* view, BOOL visible); @@ -125,8 +125,8 @@ LLPanelPlaces::LLPanelPlaces()  		mItem(NULL),  		mPlaceMenu(NULL),  		mLandmarkMenu(NULL), -		mLandmarkFoldersMenuHandle(), -		mPosGlobal() +		mPosGlobal(), +		isLandmarkEditModeOn(false)  {  	mParcelObserver = new LLPlacesParcelObserver(this);  	mInventoryObserver = new LLPlacesInventoryObserver(this); @@ -146,20 +146,12 @@ LLPanelPlaces::~LLPanelPlaces()  	LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); -	LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle); -  	delete mInventoryObserver;  	delete mParcelObserver;  }  BOOL LLPanelPlaces::postBuild()  { -	mCreateLandmarkBtn = getChild<LLButton>("create_landmark_btn"); -	mCreateLandmarkBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, LLUUID())); -	 -	mFolderMenuBtn = getChild<LLButton>("folder_menu_btn"); -	mFolderMenuBtn->setClickedCallback(boost::bind(&LLPanelPlaces::showLandmarkFoldersMenu, this)); -  	mTeleportBtn = getChild<LLButton>("teleport_btn");  	mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); @@ -169,6 +161,18 @@ BOOL LLPanelPlaces::postBuild()  	mShareBtn = getChild<LLButton>("share_btn");  	//mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this)); +	mEditBtn = getChild<LLButton>("edit_btn"); +	mEditBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); + +	mSaveBtn = getChild<LLButton>("save_btn"); +	mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this)); + +	mCancelBtn = getChild<LLButton>("cancel_btn"); +	mCancelBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCancelButtonClicked, this)); + +	mCloseBtn = getChild<LLButton>("close_btn"); +	mCloseBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); +  	mOverflowBtn = getChild<LLButton>("overflow_btn");  	mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); @@ -200,10 +204,18 @@ BOOL LLPanelPlaces::postBuild()  	}  	mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info"); -	 +  	LLButton* back_btn = mPlaceInfo->getChild<LLButton>("back_btn");  	back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); +	LLLineEditor* title_editor = mPlaceInfo->getChild<LLLineEditor>("title_editor"); +	title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL); + +	LLTextEditor* notes_editor = mPlaceInfo->getChild<LLTextEditor>("notes_editor"); +	notes_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); + +	LLComboBox* folder_combo = mPlaceInfo->getChild<LLComboBox>("folder_combo"); +	folder_combo->setSelectionCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));  	return TRUE;  } @@ -217,6 +229,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	mPlaceInfoType = key["type"].asString();  	mPosGlobal.setZero(); +	mItem = NULL;  	togglePlaceInfoPanel(TRUE);  	updateVerbs(); @@ -227,11 +240,25 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)  	{  		mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); + +		if (key.has("x") && key.has("y") && key.has("z")) +		{ +			mPosGlobal = LLVector3d(key["x"].asReal(), +									key["y"].asReal(), +									key["z"].asReal()); +		} +		else +		{ +			mPosGlobal = gAgent.getPositionGlobal(); +		} + +		mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal);  	}  	else if (mPlaceInfoType == LANDMARK_INFO_TYPE)  	{ -		LLUUID item_uuid = key["id"].asUUID(); -		LLInventoryItem* item = gInventory.getItem(item_uuid); +		mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); + +		LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());  		if (!item)  			return; @@ -272,8 +299,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	// Start using LLViewerParcelMgr for land selection if  	// information about nearby land is requested.  	// Otherwise stop using land selection and deselect land. -	if (mPlaceInfoType == AGENT_INFO_TYPE || -		mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) +	if (mPlaceInfoType == AGENT_INFO_TYPE)  	{  		parcel_mgr->addObserver(mParcelObserver);  		parcel_mgr->selectParcelAt(gAgent.getPositionGlobal()); @@ -291,7 +317,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)  void LLPanelPlaces::setItem(LLInventoryItem* item)  { -	if (!mPlaceInfo) +	if (!item)  		return;  	mItem = item; @@ -304,7 +330,9 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)  			return;  	} -	mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); +	if (!mPlaceInfo) +		return; +  	mPlaceInfo->displayItemInfo(mItem);  	LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(), @@ -324,6 +352,12 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)  	landmark->getRegionID(region_id);  	landmark->getGlobalPos(mPosGlobal);  	mPlaceInfo->displayParcelInfo(region_id, mPosGlobal); + +	// Check if item is in agent's inventory and he has the permission to modify it. +	BOOL is_landmark_editable = mItem.notNull() && +								gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && +								mItem->getPermissions().allowModifyBy(gAgent.getID()); +	mEditBtn->setEnabled(is_landmark_editable);  }  void LLPanelPlaces::onFilterEdit(const std::string& search_string) @@ -436,6 +470,136 @@ void LLPanelPlaces::onShowOnMapButtonClicked()  	}  } +void LLPanelPlaces::onEditButtonClicked() +{ +	if (!mPlaceInfo || isLandmarkEditModeOn) +		return; + +	isLandmarkEditModeOn = true; + +	mPlaceInfo->toggleLandmarkEditMode(TRUE); + +	updateVerbs(); +} + +void LLPanelPlaces::onSaveButtonClicked() +{ +	if (!mPlaceInfo || mItem.isNull()) +		return; + +	LLAssetType::EType item_type = mItem->getType(); +	if (item_type == LLAssetType::AT_LANDMARK || item_type != LLAssetType::AT_LINK) +	{ +		// If the item is a link get a linked item +		if (item_type == LLAssetType::AT_LINK) +		{ +			mItem = gInventory.getItem(mItem->getAssetUUID()); +			if (mItem.isNull()) +				return; +		} +	} +	else +	{ +		return; +	} + +	std::string current_title_value = mPlaceInfo->getLandmarkTitle(); +	std::string item_title_value = mItem->getName(); +	std::string current_notes_value = mPlaceInfo->getLandmarkNotes(); +	std::string item_notes_value = mItem->getDescription(); + +	LLStringUtil::trim(current_title_value); +	LLStringUtil::trim(current_notes_value); + +	bool is_item_update_needed = false; + +	if (!current_title_value.empty() && +		(item_title_value != current_title_value || item_notes_value != current_notes_value)) +	{ +		is_item_update_needed = true; +	} + +	LLUUID item_id = mItem->getUUID(); +	LLUUID folder_id = mPlaceInfo->getLandmarkFolder(); + +	// Check if item is in agent's inventory and he has the permission to modify it. +	if (!gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()) || +		!mItem->getPermissions().allowModifyBy(gAgent.getID())) +		return; + +	if(folder_id != mItem->getParentUUID() || is_item_update_needed) +	{ +		LLViewerInventoryItem* item = (LLViewerInventoryItem*)mItem.get(); +		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + +		LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + +		// If target is the favorites folder we create link to it. +		if (favorites_id == folder_id) +		{ +			if (is_item_update_needed) +			{ +				new_item->rename(current_title_value); +				new_item->setDescription(current_notes_value); +				new_item->updateServer(FALSE); + +				gInventory.updateItem(new_item); +				gInventory.notifyObservers(); +			} + +			link_inventory_item(gAgent.getID(), +								item->getUUID(), +								folder_id, +								item->getName(), +								LLAssetType::AT_LINK, +								LLPointer<LLInventoryCallback>(NULL)); +		} +		else +		{ +			if (is_item_update_needed) +			{ +				new_item->rename(current_title_value); +				new_item->setDescription(current_notes_value); +				new_item->updateServer(FALSE); +			} + +			LLInventoryModel::update_list_t update; +			LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); +			update.push_back(old_folder); +			LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); +			update.push_back(new_folder); +			gInventory.accountForUpdate(update); + +			new_item->setParent(folder_id); +			new_item->updateParentOnServer(FALSE); + +			gInventory.updateItem(new_item); +			gInventory.notifyObservers(); +		} +	} + +	onCancelButtonClicked(); +} + +void LLPanelPlaces::onCancelButtonClicked() +{ +	if (!mPlaceInfo) +		return; + +	if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) +	{ +		onBackButtonClicked(); +	} +	else +	{ +		mPlaceInfo->toggleLandmarkEditMode(FALSE); +		updateVerbs(); + +		// Reload the landmark properties. +		mPlaceInfo->displayItemInfo(mItem); +	} +} +  void LLPanelPlaces::onOverflowButtonClicked()  {  	LLToggleableMenu* menu; @@ -487,7 +651,12 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)  	std::string item = param.asString();  	if (item == "landmark")  	{ -		onOpen(LLSD().insert("type", CREATE_LANDMARK_INFO_TYPE)); +		LLSD key; +		key["type"] = CREATE_LANDMARK_INFO_TYPE; +		key["x"] = mPosGlobal.mdV[VX]; +		key["y"] = mPosGlobal.mdV[VY]; +		key["z"] = mPosGlobal.mdV[VZ]; +		onOpen(key);  	}  	else if (item == "copy")  	{ @@ -523,20 +692,6 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)  	}  } -void LLPanelPlaces::onCreateLandmarkButtonClicked(const LLUUID& folder_id) -{ -	if (!mPlaceInfo) -		return; - -	// To prevent creating duplicate landmarks -	// disable landmark creating buttons until -	// the information on existing landmarks is reloaded. -	mCreateLandmarkBtn->setEnabled(FALSE); -	mFolderMenuBtn->setEnabled(FALSE); - -	mPlaceInfo->createLandmark(folder_id); -} -  void LLPanelPlaces::onBackButtonClicked()  {  	if (!mPlaceInfo) @@ -697,10 +852,14 @@ void LLPanelPlaces::updateVerbs()  	bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;  	bool is_media_panel_visible = mPlaceInfo->isMediaPanelVisible(); -	mTeleportBtn->setVisible(!is_create_landmark_visible); -	mShareBtn->setVisible(!is_create_landmark_visible); -	mCreateLandmarkBtn->setVisible(is_create_landmark_visible); -	mFolderMenuBtn->setVisible(is_create_landmark_visible); +	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); +	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); +	mShareBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); +	mOverflowBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); +	mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn); +	mSaveBtn->setVisible(isLandmarkEditModeOn); +	mCancelBtn->setVisible(isLandmarkEditModeOn); +	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);  	mOverflowBtn->setEnabled(is_place_info_visible && !is_media_panel_visible && !is_create_landmark_visible); @@ -714,15 +873,6 @@ void LLPanelPlaces::updateVerbs()  									 !mPosGlobal.isExactlyZero() &&  									 !LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal));  		} -		else if (is_create_landmark_visible) -		{ -			// Enable "Create Landmark" only if there is no landmark -			// for the current parcel and agent is inside it. -			bool enable = !LLLandmarkActions::landmarkAlreadyExists() && -						  is_agent_in_selected_parcel(mParcel->getParcel()); -			mCreateLandmarkBtn->setEnabled(enable); -			mFolderMenuBtn->setEnabled(enable); -		}  		else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)  		{  			mTeleportBtn->setEnabled(TRUE); @@ -735,131 +885,8 @@ void LLPanelPlaces::updateVerbs()  		if (mActivePanel)  			mActivePanel->updateVerbs();  	} -} - -void LLPanelPlaces::showLandmarkFoldersMenu() -{ -	if (mLandmarkFoldersMenuHandle.isDead()) -	{ -		LLToggleableMenu::Params menu_p; -		menu_p.name("landmarks_folders_menu"); -		menu_p.can_tear_off(false); -		menu_p.visible(false); -		menu_p.scrollable(true); -		menu_p.max_scrollable_items = 10; - -		LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p); - -		mLandmarkFoldersMenuHandle = menu->getHandle(); -	} - -	LLToggleableMenu* menu = (LLToggleableMenu*)mLandmarkFoldersMenuHandle.get(); -	if(!menu) -		return; - -	if (!menu->toggleVisibility()) -		return; - -	// Collect all folders that can contain landmarks. -	LLInventoryModel::cat_array_t cats; -	collectLandmarkFolders(cats); - -	// Sort the folders by their full name. -	folder_vec_t folders; -	S32 count = cats.count(); -	for (S32 i = 0; i < count; i++) -	{ -		const LLViewerInventoryCategory* cat = cats.get(i); -		std::string cat_full_name = getFullFolderName(cat); -		folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); -	} -	sort(folders.begin(), folders.end(), cmp_folders); - -	LLRect btn_rect = mFolderMenuBtn->getRect(); - -	LLRect root_rect = getRootView()->getRect(); -	 -	// Check it there are changed items or viewer dimensions  -	// have changed since last call -	if (mLandmarkFoldersCache.size() == count && -		mRootViewWidth == root_rect.getWidth() && -		mRootViewHeight == root_rect.getHeight()) -	{ -		S32 i; -		for (i = 0; i < count; i++) -		{ -			if (mLandmarkFoldersCache[i].second != folders[i].second) -			{ -				break; -			} -		} - -		// Check passed, just show the menu -		if (i == count) -		{ -			menu->buildDrawLabels(); -			menu->updateParent(LLMenuGL::sMenuContainer); - -			menu->setButtonRect(btn_rect, this); -			LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop); -			return; -		} -	} - -	// If there are changes, store the new viewer dimensions -	// and a list of folders -	mRootViewWidth = root_rect.getWidth(); -	mRootViewHeight = root_rect.getHeight(); -	mLandmarkFoldersCache = folders; - -	menu->empty(); - -	// Menu width must not exceed the root view limits, -	// so we assume the space between the left edge of -	// the root view and  -	LLRect screen_btn_rect; -	localRectToScreen(btn_rect, &screen_btn_rect); -	S32 free_space = screen_btn_rect.mRight; -	U32 max_width = llmin(LANDMARK_FOLDERS_MENU_WIDTH, free_space); -	for(folder_vec_t::const_iterator it = mLandmarkFoldersCache.begin(); it != mLandmarkFoldersCache.end(); it++) -	{ -		const std::string& item_name = it->second; - -		LLMenuItemCallGL::Params item_params; -		item_params.name(item_name); -		item_params.label(item_name); - -		item_params.on_click.function(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, it->first)); - -		LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); - -		// *TODO: Use a separate method for menu width calculation. -		// Check whether item name wider than menu -		if (menu_item->getNominalWidth() > max_width) -		{ -			S32 chars_total = item_name.length(); -			S32 chars_fitted = 1; -			menu_item->setLabel(LLStringExplicit("")); -			S32 label_space = max_width - menu_item->getFont()->getWidth("...") - -				menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels) - -			while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space) -			{ -				chars_fitted++; -			} -			chars_fitted--; // Rolling back one char, that doesn't fit - -			menu_item->setLabel(item_name.substr(0, chars_fitted) + "..."); -		} - -		menu->addChild(menu_item); -	} - -	menu->buildDrawLabels(); -	menu->updateParent(LLMenuGL::sMenuContainer); -	menu->setButtonRect(btn_rect, this); -	LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop); +	isLandmarkEditModeOn = false;  }  static bool is_agent_in_selected_parcel(LLParcel* parcel) @@ -874,70 +901,6 @@ static bool is_agent_in_selected_parcel(LLParcel* parcel)  			parcel->getLocalID() == parcel_mgr->getAgentParcel()->getLocalID();  } -static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) -{ -	return left.second < right.second; -} - -static std::string getFullFolderName(const LLViewerInventoryCategory* cat) -{ -	std::string name = cat->getName(); -	LLUUID parent_id; - -	// translate category name, if it's right below the root -	// FIXME: it can throw notification about non existent string in strings.xml -	if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID()) -	{ -		LLTrans::findString(name, "InvFolder " + name); -	} - -	// we don't want "My Inventory" to appear in the name -	while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID()) -	{ -		cat = gInventory.getCategory(parent_id); -		name = cat->getName() + "/" + name; -	} - -	return name; -} - -static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) -{ -	// Add the "Landmarks" category itself. -	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); -	LLViewerInventoryCategory* landmarks_cat = gInventory.getCategory(landmarks_id); -	if (!landmarks_cat) -	{ -		llwarns << "Cannot find the landmarks folder" << llendl; -	} -	else -	{ -		cats.put(landmarks_cat); -	} - -	// Add descendent folders of the "Landmarks" category. -	LLInventoryModel::item_array_t items; // unused -	LLIsType is_category(LLAssetType::AT_CATEGORY); -	gInventory.collectDescendentsIf( -		landmarks_id, -		cats, -		items, -		LLInventoryModel::EXCLUDE_TRASH, -		is_category); - -	// Add the "My Favorites" category. -	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); -	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); -	if (!favorites_cat) -	{ -		llwarns << "Cannot find the favorites folder" << llendl; -	} -	else -	{ -		cats.put(favorites_cat); -	} -} -  static void onSLURLBuilt(std::string& slurl)  {  	LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl)); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index f208e91237..0b3b3b5fc3 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -72,6 +72,9 @@ private:  	//void onShareButtonClicked();  	void onTeleportButtonClicked();  	void onShowOnMapButtonClicked(); +	void onEditButtonClicked(); +	void onSaveButtonClicked(); +	void onCancelButtonClicked();  	void onOverflowButtonClicked();  	void onOverflowMenuItemClicked(const LLSD& param);  	void onCreateLandmarkButtonClicked(const LLUUID& folder_id); @@ -84,8 +87,6 @@ private:  	void onAgentParcelChange();  	void updateVerbs(); -	void showLandmarkFoldersMenu(); -  	LLFilterEditor*				mFilterEditor;  	LLPanelPlacesTab*			mActivePanel;  	LLTabContainer*				mTabContainer; @@ -94,11 +95,13 @@ private:  	LLToggleableMenu*			mPlaceMenu;  	LLToggleableMenu*			mLandmarkMenu; -	LLButton*					mCreateLandmarkBtn; -	LLButton*					mFolderMenuBtn;  	LLButton*					mTeleportBtn;  	LLButton*					mShowOnMapBtn;  	LLButton*					mShareBtn; +	LLButton*					mEditBtn; +	LLButton*					mSaveBtn; +	LLButton*					mCancelBtn; +	LLButton*					mCloseBtn;  	LLButton*					mOverflowBtn;  	LLPlacesInventoryObserver*	mInventoryObserver; @@ -118,19 +121,7 @@ private:  	// Information type currently shown in Place Information panel  	std::string					mPlaceInfoType; -	// Menu handle for pop-up menu to chose a landmark saving -	// folder when creating a new landmark -	LLHandle<LLView> 			mLandmarkFoldersMenuHandle; - -	typedef std::vector<folder_pair_t>	folder_vec_t; - -	// List of folders to choose from when creating a landmark -	folder_vec_t				mLandmarkFoldersCache; - -	// If root view width or height is changed -	// the pop-up menu must be updated -	S32							mRootViewWidth; -	S32							mRootViewHeight; +	bool						isLandmarkEditModeOn;  	LLSafeHandle<LLParcelSelection>	mParcel;  }; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 3bd2645be3..cda7942c1d 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -102,7 +102,7 @@ void LLPanelProfile::onOpen(const LLSD& key)  {  	if (key.has("open_tab_name"))  	{ -		getTabContainer()[PANEL_PICKS]->onClose(); +		getTabContainer()[PANEL_PICKS]->onClosePanel();  		// onOpen from selected panel will be called from onTabSelected callback  		getTabCtrl()->selectTabByName(key["open_tab_name"]); diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 3bda30e0c6..604faf8eb4 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -68,8 +68,6 @@ void LLPreviewAnim::endAnimCallback( void *userdata )  // virtual  BOOL LLPreviewAnim::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLPreviewAnim::onClose, this)); -	  	const LLInventoryItem* item = getItem();  	if(item)  	{ @@ -181,7 +179,8 @@ void LLPreviewAnim::auditionAnim( void *userdata )  	}  } -void LLPreviewAnim::onClose() +// virtual +void LLPreviewAnim::onClose(bool app_quitting)  {  	const LLInventoryItem *item = getItem(); diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h index d24e624c32..616c5789ac 100644 --- a/indra/newview/llpreviewanim.h +++ b/indra/newview/llpreviewanim.h @@ -46,10 +46,10 @@ public:  	static void auditionAnim( void* userdata );  	static void endAnimCallback( void *userdata );  	/*virtual*/	BOOL postBuild(); +	/*virtual*/ void onClose(bool app_quitting);  	void activate(e_activation_type type);  protected: -	void onClose();  	LLAnimPauseRequest	mPauseRequest;  	LLUUID		mItemID; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index faca950963..32ed20bd56 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -32,10 +32,10 @@  #include "llviewerprecompiledheaders.h" -#include <algorithm> -  #include "llpreviewgesture.h" +#include <algorithm> +  // libraries  #include "lldatapacker.h"  #include "lldarray.h" @@ -260,7 +260,8 @@ BOOL LLPreviewGesture::canClose()  	}  } -void LLPreviewGesture::onClose() +// virtual +void LLPreviewGesture::onClose(bool app_quitting)  {  	LLGestureManager::instance().stopGesture(mPreviewGesture);  } @@ -354,7 +355,6 @@ LLPreviewGesture::~LLPreviewGesture()  BOOL LLPreviewGesture::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLPreviewGesture::onClose, this));  	mVisibleSignal.connect(boost::bind(&LLPreviewGesture::onVisibilityChange, this, _2));  	LLLineEditor* edit; diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index 16ac935775..9d26539453 100644 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -70,11 +70,10 @@ public:  	// LLFloater  	/*virtual*/ BOOL canClose(); +	/*virtual*/ void onClose(bool app_quitting);  	/*virtual*/ void onUpdateSucceeded();  	/*virtual*/ void refresh(); -	 -  protected:  	// Populate various comboboxes  	void addModifiers(); @@ -108,7 +107,6 @@ protected:  	// "Sound", "Chat", or "Wait"  	LLScrollListItem* addStep(const enum EStepType step_type); -	void onClose();  	void onVisibilityChange ( const LLSD& new_visibility );  	static std::string getLabel(std::vector<std::string> labels); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 26ac95060f..296502ff16 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -273,11 +273,14 @@ public:  	LLViewerObject*	getFirstCopyableObject(BOOL get_parent = FALSE);  	LLViewerObject* getFirstDeleteableObject();  	LLViewerObject*	getFirstMoveableObject(BOOL get_parent = FALSE); + +	/// Return the object that lead to this selection, possible a child  	LLViewerObject* getPrimaryObject() { return mPrimaryObject; }  	// iterate through texture entries  	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res); -		 +	template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value); +	  	void addNode(LLSelectNode *nodep);  	void addNodeAtEnd(LLSelectNode *nodep);  	void moveNodeToFront(LLSelectNode *nodep); @@ -783,5 +786,52 @@ template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGet  	return identical;  } +// Templates +//----------------------------------------------------------------------------- +// isMultipleTEValue iterate through all TEs and test for uniqueness  +// with certain return value ignored when performing the test.  +// e.g. when testing if the selection has a unique non-empty homeurl : +// you can set ignore_value = "" and it will only compare among the non-empty   +// homeUrls and ignore the empty ones. +//----------------------------------------------------------------------------- +template <typename T> bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value) +{ +	bool have_first = false; +	T selected_value = T(); +	 +	// Now iterate through all TEs to test for sameness +	bool unique = TRUE; +	for (iterator iter = begin(); iter != end(); iter++) +	{ +		LLSelectNode* node = *iter; +		LLViewerObject* object = node->getObject(); +		for (S32 te = 0; te < object->getNumTEs(); ++te) +		{ +			if (!node->isTESelected(te)) +			{ +				continue; +			} +			T value = func->get(object, te); +			if(value == ignore_value) +			{ +				continue; +			} +			if (!have_first) +			{ +				have_first = true; +			} +			else +			{ +				if (value !=selected_value  ) +				{ +					unique = false; +					return !unique; +				} +			} +		} +	} +	return !unique; +} +  #endif diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 2bb1e80eb8..c5a92f52d0 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -522,7 +522,7 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&  	contactName->setValue(name);  	mCloseBtn = getChild<LLButton>("hide_btn"); -	mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClose, this)); +	mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClosePanel, this));  }  //--------------------------------------------------------------------------------- @@ -531,7 +531,7 @@ LLSysWellWindow::RowPanel::~RowPanel()  }  //--------------------------------------------------------------------------------- -void LLSysWellWindow::RowPanel::onClose() +void LLSysWellWindow::RowPanel::onClosePanel()  {  	gIMMgr->removeSession(mChiclet->getSessionId());  	// This row panel will be removed from the list in LLSysWellWindow::sessionRemoved(). diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 203b949715..0c3f4d0587 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -137,7 +137,7 @@ private:  		void onMouseLeave(S32 x, S32 y, MASK mask);  		BOOL handleMouseDown(S32 x, S32 y, MASK mask);  	private: -		void onClose(); +		void onClosePanel();  	public:  		LLIMChiclet* mChiclet;  	private: diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 9fc91e2971..43f82e592b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -102,15 +102,16 @@ public:  	virtual ~LLFloaterTexturePicker();  	// LLView overrides -	virtual BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask, +	/*virtual*/ BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask,  						BOOL drop, EDragAndDropType cargo_type, void *cargo_data,   						EAcceptance *accept,  						std::string& tooltip_msg); -	virtual void	draw(); -	virtual BOOL	handleKeyHere(KEY key, MASK mask); +	/*virtual*/ void	draw(); +	/*virtual*/ BOOL	handleKeyHere(KEY key, MASK mask);  	// LLFloater overrides -	virtual BOOL    postBuild(); +	/*virtual*/ BOOL    postBuild(); +	/*virtual*/ void	onClose(bool app_settings);  	// New functions  	void setImageID( const LLUUID& image_asset_id); @@ -130,7 +131,6 @@ public:  	void commitIfImmediateSet();  	void onFilterEdit(const std::string& search_string ); -	void onClose();  	static void		onBtnSetToDefault( void* userdata );  	static void		onBtnSelect( void* userdata ); @@ -369,7 +369,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)  	return LLFloater::handleKeyHere(key, mask);  } -void LLFloaterTexturePicker::onClose() +void LLFloaterTexturePicker::onClose(bool app_quitting)  {  	if (mOwner)  	{ @@ -381,8 +381,6 @@ void LLFloaterTexturePicker::onClose()  // virtual  BOOL LLFloaterTexturePicker::postBuild()  { -	mCloseSignal.connect(boost::bind(&LLFloaterTexturePicker::onClose, this)); -	  	LLFloater::postBuild();  	if (!mLabel.empty()) diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index d9be6b172c..e4a3f8603b 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -308,7 +308,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  	//gFloaterView->adjustToFitScreen(this, FALSE);  	if (mLineEditor)  	{ -		mLineEditor->setFocus(TRUE);  		mLineEditor->selectAll();  	}  	if(mDefaultOption >= 0) diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 5525c359fc..beb16c267e 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -70,6 +70,7 @@  #include "llworld.h"  #include "llui.h"  #include "llweb.h" +#include "pipeline.h"	// setHighlightObject  extern BOOL gDebugClicks; @@ -391,24 +392,24 @@ ECursorType cursor_from_object(LLViewerObject* object)  	case CLICK_ACTION_SIT:  		if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // not already sitting?  		{ -			cursor = UI_CURSOR_TOOLSIT; +			cursor = UI_CURSOR_HAND;  		}  		break;  	case CLICK_ACTION_BUY: -		cursor = UI_CURSOR_TOOLBUY; +		cursor = UI_CURSOR_HAND;  		break;  	case CLICK_ACTION_OPEN:  		// Open always opens the parent.  		if (parent && parent->allowOpen())  		{ -			cursor = UI_CURSOR_TOOLOPEN; +			cursor = UI_CURSOR_HAND;  		}  		break;  	case CLICK_ACTION_PAY:	  		if ((object && object->flagTakesMoney())  			|| (parent && parent->flagTakesMoney()))  		{ -			cursor = UI_CURSOR_TOOLPAY; +			cursor = UI_CURSOR_HAND;  		}  		break;  	case CLICK_ACTION_PLAY: @@ -472,7 +473,9 @@ void LLToolPie::selectionPropertiesReceived()  BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  {  	mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE); -	 + +	// Show screen-space highlight glow effect +	bool show_highlight = false;  	LLViewerObject *parent = NULL;  	LLViewerObject *object = mHoverPick.getObject(); @@ -483,24 +486,28 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  	if (object && useClickAction(mask, object, parent))  	{ +		show_highlight = true;  		ECursorType cursor = cursor_from_object(object);  		gViewerWindow->setCursor(cursor);  		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;  	}  	else if (handleMediaHover(mHoverPick))  	{ +		show_highlight = true;  		// cursor set by media object  		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;  	}  	else if ((object && !object->isAvatar() && object->usePhysics())   			 || (parent && !parent->isAvatar() && parent->usePhysics()))  	{ +		show_highlight = true;  		gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);  		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;  	}  	else if ( (object && object->flagHandleTouch())   			  || (parent && parent->flagHandleTouch()))  	{ +		show_highlight = true;  		gViewerWindow->setCursor(UI_CURSOR_HAND);  		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;  	} @@ -519,6 +526,15 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  		}  	} +	static LLCachedControl<bool> enable_highlight( +		gSavedSettings, "RenderHighlightEnable", false); +	LLDrawable* drawable = NULL; +	if (enable_highlight && show_highlight && object) +	{ +		drawable = object->mDrawable; +	} +	gPipeline.setHighlightObject(drawable); +  	return TRUE;  } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 0b21f3565d..8c46949d70 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -83,7 +83,7 @@  #include "llfloaternamedesc.h"  #include "llfloaternotificationsconsole.h"  #include "llfloateropenobject.h" -#include "llgivemoney.h" +#include "llfloaterpay.h"  #include "llfloaterparcel.h"  #include "llfloaterperms.h"  #include "llfloaterpostcard.h" @@ -195,8 +195,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);  	LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>); -	LLFloaterReg::add("pay_resident", "floater_pay.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPay>); -	LLFloaterReg::add("pay_object", "floater_pay_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPay>); +	LLFloaterPayUtil::registerFloater();  	LLFloaterReg::add("postcard", "floater_postcard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostcard>);  	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 2b972614f1..2f55be8b9c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -588,7 +588,9 @@ LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,  	mHasFocus(false),  	mPriority(LLPluginClassMedia::PRIORITY_UNLOADED),  	mDoNavigateOnLoad(false), +	mDoNavigateOnLoadRediscoverType(false),  	mDoNavigateOnLoadServerRequest(false), +	mMediaSourceFailedInit(false),  	mIsUpdated(false)  {  @@ -664,7 +666,7 @@ void LLViewerMediaImpl::createMediaSource()  	{  		if(! mMediaURL.empty())  		{ -			navigateTo(mMediaURL, mMimeType, false, mDoNavigateOnLoadServerRequest); +			navigateTo(mMediaURL, mMimeType, mDoNavigateOnLoadRediscoverType, mDoNavigateOnLoadServerRequest);  		}  		else if(! mMimeType.empty())  		{ @@ -703,7 +705,7 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type)  LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height)  {  	std::string plugin_basename = LLMIMETypes::implType(media_type); - +	  	if(plugin_basename.empty())  	{  		LL_WARNS("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL; @@ -774,6 +776,9 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)  		return false;  	} +	// If we got here, we want to ignore previous init failures. +	mMediaSourceFailedInit = false; +  	LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight);  	if (media_source) @@ -787,6 +792,9 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)  		return true;  	} +	// Make sure the timer doesn't try re-initing this plugin repeatedly until something else changes. +	mMediaSourceFailedInit = true; +  	return false;  } @@ -1003,14 +1011,7 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)  //////////////////////////////////////////////////////////////////////////////////////////  void LLViewerMediaImpl::navigateHome()  { -	mMediaURL = mHomeURL; -	mDoNavigateOnLoad = !mMediaURL.empty(); -	mDoNavigateOnLoadServerRequest = false; -	 -	if(mMediaSource) -	{ -		mMediaSource->loadURI( mHomeURL ); -	} +	navigateTo(mHomeURL, "", true, false);  }  ////////////////////////////////////////////////////////////////////////////////////////// @@ -1025,12 +1026,16 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi  		setNavState(MEDIANAVSTATE_NONE);  	} -	// Always set the current URL. +	// Always set the current URL and MIME type.  	mMediaURL = url; +	mMimeType = mime_type;  	// If the current URL is not null, make the instance do a navigate on load.  	mDoNavigateOnLoad = !mMediaURL.empty(); +	// if mime type discovery was requested, we'll need to do it when the media loads +	mDoNavigateOnLoadRediscoverType = rediscover_type; +	  	// and if this was a server request, the navigate on load will also need to be one.  	mDoNavigateOnLoadServerRequest = server_request; @@ -1041,6 +1046,21 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi  		return;  	} +	 +	// If the caller has specified a non-empty MIME type, look that up in our MIME types list. +	// If we have a plugin for that MIME type, use that instead of attempting auto-discovery. +	// This helps in supporting legacy media content where the server the media resides on returns a bogus MIME type +	// but the parcel owner has correctly set the MIME type in the parcel media settings. +	 +	if(!mMimeType.empty() && (mMimeType != "none/none")) +	{ +		std::string plugin_basename = LLMIMETypes::implType(mMimeType); +		if(!plugin_basename.empty()) +		{ +			// We have a plugin for this mime type +			rediscover_type = false; +		} +	}  	if(rediscover_type)  	{ @@ -1147,7 +1167,7 @@ bool LLViewerMediaImpl::canNavigateBack()  //////////////////////////////////////////////////////////////////////////////////////////  void LLViewerMediaImpl::update()  { -	if(mMediaSource == NULL) +	if(mMediaSource == NULL && !mMediaSourceFailedInit)  	{  		if(mPriority != LLPluginClassMedia::PRIORITY_UNLOADED)  		{ @@ -1374,6 +1394,18 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  {  	switch(event)  	{ +		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: +		{ +			// The plugin failed to load properly.  Make sure the timer doesn't retry. +			mMediaSourceFailedInit = true; +			 +			// TODO: may want a different message for this case? +			LLSD args; +			args["PLUGIN"] = LLMIMETypes::implType(mMimeType); +			LLNotifications::instance().add("MediaPluginFailed", args); +		} +		break; +  		case MEDIA_EVENT_PLUGIN_FAILED:  		{  			LLSD args; @@ -1422,7 +1454,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:  		{  			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_COMPLETE, uri is: " << plugin->getNavigateURI() << LL_ENDL; -			setNavState(MEDIANAVSTATE_NONE);  		}  		break; diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index c9ba5841e9..37aabcf2d6 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -278,7 +278,9 @@ public:  	bool mHasFocus;  	LLPluginClassMedia::EPriority mPriority;  	bool mDoNavigateOnLoad; +	bool mDoNavigateOnLoadRediscoverType;  	bool mDoNavigateOnLoadServerRequest; +	bool mMediaSourceFailedInit;  private: diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index f9377ab37b..1b1b7cedb1 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -304,7 +304,11 @@ BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks)  	BOOL retval = FALSE;  	if(mFocus.notNull() && mMediaImpl.notNull() && mMediaImpl->hasMedia())  	{ -		mMediaImpl->getMediaPlugin()->scrollEvent(x, y, clicks); +        // the scrollEvent() API's x and y are not the same as handleScrollWheel's x and y. +        // The latter is the position of the mouse at the time of the event +        // The former is the 'scroll amount' in x and y, respectively. +        // All we have for 'scroll amount' here is 'clicks', and no mask. +		mMediaImpl->getMediaPlugin()->scrollEvent(0, clicks, /*mask*/0);  		retval = TRUE;  	}  	return retval; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d95992412f..dde7b1c7ee 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -111,6 +111,7 @@  #include "llfloaterlandholdings.h"  #include "llfloatermap.h"  #include "llfloateropenobject.h" +#include "llfloaterpay.h"  #include "llfloaterperms.h"  #include "llfloaterpostprocess.h"  #include "llfloaterpreference.h" @@ -129,7 +130,6 @@  #include "llavataractions.h"  #include "lllandmarkactions.h"  #include "llmemoryview.h" -#include "llgivemoney.h"  #include "llgroupmgr.h"  #include "lltooltip.h"  #include "llhudeffecttrail.h" @@ -567,6 +567,15 @@ void init_menus()  	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);  	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); +#if !MEM_TRACK_MEM +	// Don't display the Memory console menu if the feature is turned off +	LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE); +	if (memoryMenu) +	{ +		memoryMenu->setVisible(FALSE); +	} +#endif +  	gMenuBarView->createJumpKeys();  	// Let land based option enable when parcel changes @@ -5405,7 +5414,7 @@ class LLAvatarAddContact : public view_listener_t  	}  }; -bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle) +bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection)  {  	S32 option = LLNotification::getSelectedOption(notification, response);  	if (option == 0) @@ -5413,7 +5422,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec  		gAgent.clearBusy();  	} -	LLViewerObject* objectp = handle->getPrimaryObject(); +	LLViewerObject* objectp = selection->getPrimaryObject();  	// Show avatar's name if paying attachment  	if (objectp && objectp->isAttachment()) @@ -5428,14 +5437,14 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec  	{  		if (objectp->isAvatar())  		{ -			const BOOL is_group = FALSE; -			LLFloaterPay::payDirectly(&give_money, +			const bool is_group = false; +			LLFloaterPayUtil::payDirectly(&give_money,  									  objectp->getID(),  									  is_group);  		}  		else  		{ -			LLFloaterPay::payViaObject(&give_money, objectp->getID()); +			LLFloaterPayUtil::payViaObject(&give_money, selection);  		}  	}  	return false; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 2e8580907e..aa662b713e 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -98,6 +98,7 @@  #include "llnotifications.h"  #include "llnotify.h"  #include "llpanelgrouplandmoney.h" +#include "llpanelplaces.h"  #include "llrecentpeople.h"  #include "llselectmgr.h"  #include "llsidetray.h" @@ -138,7 +139,6 @@  #include "llkeythrottle.h"  #include "llgroupactions.h"  #include "llagentui.h" -#include "llsidetray.h"  #include "llpanelblockedlist.h"  #include "llpanelplaceinfo.h" @@ -907,14 +907,15 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)  					LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());  					LLSD args;  					args["LANDMARK_NAME"] = item->getName(); -					args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unnkown"); +					args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");  					LLNotifications::instance().add("LandmarkCreated", args); -					 -					// Open new landmark for editing in Places panel. -					LLSD key; -					key["type"] = "landmark"; -					key["id"] = item->getUUID(); -					LLSideTray::getInstance()->showPanel("panel_places", key); + +					// Created landmark is passed to Places panel to allow its editing. +					LLPanelPlaces *panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", LLSD())); +					if (panel) +					{ +						panel->setItem(item); +					}  			  	}  				break;  			  case LLAssetType::AT_TEXTURE: diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 05011a1568..1f4f1322fd 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -47,7 +47,6 @@  #include "llframetimer.h"  #include "llinventory.h"  #include "llmaterialtable.h" -#include "llmediadataresponder.h"  #include "llmutelist.h"  #include "llnamevalue.h"  #include "llprimitive.h" diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index a3f9c839a0..9bcdcbf9ad 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -226,11 +226,13 @@ void LLViewerParcelMedia::play(LLParcel* parcel)  				media_height,   				media_auto_scale,  				media_loop); -			sMediaImpl->navigateTo(media_url); +			sMediaImpl->navigateTo(media_url, mime_type, true);  		}  	}  	else  	{ +		LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; +  		// There is no media impl, make a new one  		sMediaImpl = LLViewerMedia::newMediaImpl(  			placeholder_texture_id, @@ -238,7 +240,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel)  			media_height,   			media_auto_scale,  			media_loop); -		sMediaImpl->navigateTo(media_url); +		sMediaImpl->navigateTo(media_url, mime_type, true);  	}  	LLFirstUse::useMedia(); @@ -544,6 +546,12 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent  			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL;  		};  		break; +		 +		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; +		}; +		break;  	};  } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 6401389c8f..3c1ac3d571 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -6921,7 +6921,8 @@ void LLVoiceClient::notifyFriendObservers()  void LLVoiceClient::lookupName(const LLUUID &id)  { -	gCacheName->get(id, FALSE, &LLVoiceClient::onAvatarNameLookup); +	BOOL is_group = FALSE; +	gCacheName->get(id, is_group, &LLVoiceClient::onAvatarNameLookup);  }  //static diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e69779b2dc..1704f63376 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -46,7 +46,6 @@  #include "llvolumemessage.h"  #include "material_codes.h"  #include "message.h" -#include "llmediadataresponder.h"  #include "llpluginclassmedia.h" // for code in the mediaEvent handler  #include "object_flags.h"  #include "llagentconstants.h" @@ -69,7 +68,7 @@  #include "pipeline.h"  #include "llsdutil.h"  #include "llmediaentry.h" -#include "llmediadatafetcher.h" +#include "llmediadataclient.h"  #include "llagent.h"  const S32 MIN_QUIET_FRAMES_COALESCE = 30; @@ -86,10 +85,63 @@ F32 LLVOVolume::sLODFactor = 1.f;  F32	LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop   F32 LLVOVolume::sDistanceFactor = 1.0f;  S32 LLVOVolume::sNumLODChanges = 0; +LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL; +LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;  static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");  static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes"); +// Implementation class of LLMediaDataClientObject.  See llmediadataclient.h +class LLMediaDataClientObjectImpl : public LLMediaDataClientObject +{ +public: +	LLMediaDataClientObjectImpl(LLVOVolume *obj) : mObject(obj) {} +	LLMediaDataClientObjectImpl() { mObject = NULL; } +	 +	virtual U8 getMediaDataCount() const  +		{ return mObject->getNumTEs(); } + +	virtual LLSD getMediaDataLLSD(U8 index) const  +		{ +			LLSD result; +			LLTextureEntry *te = mObject->getTE(index);  +			if (NULL != te) +			{ +				llassert((te->getMediaData() != NULL) == te->hasMedia()); +				if (te->getMediaData() != NULL) +				{ +					result = te->getMediaData()->asLLSD(); +				} +			} +			return result; +		} + +	virtual LLUUID getID() const +		{ return mObject->getID(); } + +	virtual void mediaNavigateBounceBack(U8 index) +		{ mObject->mediaNavigateBounceBack(index); } +	 +	virtual bool hasMedia() const +		{ return mObject->hasMedia(); } +	 +	virtual void updateObjectMediaData(LLSD const &data)  +		{ mObject->updateObjectMediaData(data); } + +	virtual F64 getDistanceFromAvatar() const +		{ return mObject->getRenderPosition().length(); } +	 +	virtual F64 getTotalMediaInterest() const  +		{ return mObject->getTotalMediaInterest(); } + +	virtual std::string getCapabilityUrl(const std::string &name) const +		{ return mObject->getRegion()->getCapability(name); } +	 +private: +	LLPointer<LLVOVolume> mObject; +}; + +  LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  	: LLViewerObject(id, pcode, regionp),  	  mVolumeImpl(NULL) @@ -133,13 +185,19 @@ LLVOVolume::~LLVOVolume()  // static  void LLVOVolume::initClass()  { -	LLMediaDataFetcher::initClass(); +	// gSavedSettings better be around +	const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay"); +	const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay"); +	const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries"); +    sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries); +    sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, max_retries);  }  // static  void LLVOVolume::cleanupClass()  { -	LLMediaDataFetcher::cleanupClass(); +    sObjectMediaClient = NULL; +    sObjectMediaNavigateClient = NULL;  }  U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, @@ -316,13 +374,23 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  			}  		}  	} -	if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) { -		// If the media changed at all, request new media data -		if(mMedia) +	if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED))  +	{ +		// If only the media URL changed, and it isn't a media version URL, +		// ignore it +		if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) && +				 mMedia && ! mMedia->mMediaURL.empty() && +				 ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) )  		{ -			llinfos << "Media URL: " << mMedia->mMediaURL << llendl; +			// If the media changed at all, request new media data +			LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " << +                ((mMedia) ?  mMedia->mMediaURL : std::string("")) << LL_ENDL; +			requestMediaDataUpdate();  		} -		requestMediaDataUpdate(); +        else { +            LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " << +                ((mMedia) ?  mMedia->mMediaURL : std::string("")) << LL_ENDL; +        }  	}  	// ...and clean up any media impls  	cleanUpMediaImpls(); @@ -1621,7 +1689,7 @@ bool LLVOVolume::hasMedia() const  void LLVOVolume::requestMediaDataUpdate()  { -	LLMediaDataFetcher::fetchMedia(this); +    sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));  }  void LLVOVolume::cleanUpMediaImpls() @@ -1700,6 +1768,72 @@ void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool m  	//	<< ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;  } +void LLVOVolume::mediaNavigateBounceBack(U8 texture_index) +{ +	// Find the media entry for this navigate +	const LLMediaEntry* mep = NULL; +	viewer_media_t impl = getMediaImpl(texture_index); +	LLTextureEntry *te = getTE(texture_index); +	if(te) +	{ +		mep = te->getMediaData(); +	} +	 +	if (mep && impl) +	{ +        std::string url = mep->getCurrentURL(); +        if (url.empty()) +        { +            url = mep->getHomeURL(); +        } +        if (! url.empty()) +        { +            LL_INFOS("LLMediaDataClient") << "bouncing back to URL: " << url << LL_ENDL; +            impl->navigateTo(url, "", false, true); +        } +    } +} + +bool LLVOVolume::hasNavigatePermission(const LLMediaEntry* media_entry) +{ +    // NOTE: This logic duplicates the logic in the server (in particular, in llmediaservice.cpp). +    if (NULL == media_entry ) return false; // XXX should we assert here? +     +    // The agent has permissions to navigate if: +    // - agent has edit permissions, or +    // - world permissions are on, or +    // - group permissions are on, and agent_id is in the group, or +    // - agent permissions are on, and agent_id is the owner +     +    if (permModify())  +    { +        return true; +    } +     +    U8 media_perms = media_entry->getPermsInteract(); +     +    // World permissions +    if (0 != (media_perms & LLMediaEntry::PERM_ANYONE))  +    { +        return true; +    } +     +    // Group permissions +    else if (0 != (media_perms & LLMediaEntry::PERM_GROUP) && permGroupOwner()) +    { +        return true; +    } +     +    // Owner permissions +    else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner())  +    { +        return true; +    } +     +    return false; +     +} +  void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)  {  	switch(event) @@ -1733,6 +1867,10 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,  						{  							block_navigation = true;  						} +                        if (!block_navigation && !hasNavigatePermission(mep)) +                        { +                            block_navigation = true; +                        }  					}  					else  					{ @@ -1744,29 +1882,14 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,  						llinfos << "blocking navigate to URI " << new_location << llendl;  						// "bounce back" to the current URL from the media entry -						// NOTE: the only way block_navigation can be true is if we found the media entry, so we're guaranteed here that mep is not NULL. -						impl->navigateTo(mep->getCurrentURL()); +						mediaNavigateBounceBack(face_index);  					}  					else  					{  						llinfos << "broadcasting navigate with URI " << new_location << llendl; -						// Post the navigate to the cap -						std::string cap = getRegion()->getCapability("ObjectMediaNavigate"); -						if(cap.empty()) -						{ -							// XXX *TODO: deal with no cap!	 It may happen! (retry?) -							LL_WARNS("Media") << "Can't broadcast navigate event -- ObjectMediaNavigate cap is not available" << LL_ENDL; -							return; -						} -						 -						// If we got here, the cap is available.  Index through all faces that have this media and send the navigate message. -						LLSD sd; -						sd["object_id"] = mID; -						sd["current_url"] = new_location; -						sd["texture_index"] = face_index; -						LLHTTPClient::post(cap, sd, new LLMediaDataResponder("ObjectMediaNavigate", sd, this)); +						sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this), face_index, new_location);  					}  				}  				break; @@ -1790,29 +1913,9 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,  } -void LLVOVolume::sendMediaDataUpdate() const +void LLVOVolume::sendMediaDataUpdate()  { -	std::string url = getRegion()->getCapability("ObjectMedia"); -	if (!url.empty()) -	{ -		LLSD sd_payload; -		sd_payload["verb"] = "UPDATE"; -		sd_payload[LLTextureEntry::OBJECT_ID_KEY] = mID; -		LLSD object_media_data; -		for (int i=0; i < getNumTEs(); i++) { -			LLTextureEntry *texture_entry = getTE(i); -			llassert((texture_entry->getMediaData() != NULL) == texture_entry->hasMedia()); -			const LLSD &media_data =   -				(texture_entry->getMediaData() == NULL) ? LLSD() : texture_entry->getMediaData()->asLLSD(); -			object_media_data.append(media_data); -		} -		sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data; - -		llinfos << "Sending media data: " << getID() << " " << ll_pretty_print_sd(sd_payload) << llendl; - -		LLHTTPClient::post(url, sd_payload, new LLMediaDataResponder("ObjectMedia", sd_payload, this)); -	} -	// XXX *TODO: deal with no cap!	 It may happen! (retry?) +    sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this));  }  void LLVOVolume::removeMediaImpl(S32 texture_index) @@ -1905,6 +2008,22 @@ viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const  	return NULL;  } +F64 LLVOVolume::getTotalMediaInterest() const +{ +	F64 interest = (F64)0.0; +    int i = 0; +	const int end = getNumTEs(); +	for ( ; i < end; ++i) +	{ +		const viewer_media_t &impl = getMediaImpl(i); +		if (!impl.isNull()) +		{ +			interest += impl->getInterest(); +		} +	} +	return interest; +} +  S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id)  {  	S32 end = (S32)mMediaImplList.size() ; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 9a79b620d5..90dfa2204b 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -45,6 +45,8 @@  class LLViewerTextureAnim;  class LLDrawPool;  class LLSelectNode; +class LLObjectMediaDataClient; +class LLObjectMediaNavigateClient;  typedef std::vector<viewer_media_t> media_list_t; @@ -231,17 +233,29 @@ public:  	BOOL canBeFlexible() const;  	BOOL setIsFlexible(BOOL is_flexible); -	void updateObjectMediaData(const LLSD &media_data_duples); +    // Functions that deal with media, or media navigation +     +    // Update this object's media data with the given media data array +    // (typically this is only called upon a response from a server request) +	void updateObjectMediaData(const LLSD &media_data_array); +     +    // Bounce back media at the given index to its current URL (or home URL, if current URL is empty) +	void mediaNavigateBounceBack(U8 texture_index); +     +    // Returns whether or not this object has permission to navigate the given media entry +    bool hasNavigatePermission(const LLMediaEntry* media_entry); +      	void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);  	// Sync the given media data with the impl and the given te  	void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);  	// Send media data update to the simulator. -	void sendMediaDataUpdate() const; +	void sendMediaDataUpdate();  	viewer_media_t getMediaImpl(U8 face_id) const;  	S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id); +	F64 getTotalMediaInterest() const;  	bool hasMedia() const; @@ -283,6 +297,9 @@ public:  	static F32 sLODFactor;				// LOD scale factor  	static F32 sDistanceFactor;			// LOD distance factor +	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient; +	static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient; +  protected:  	static S32 sNumLODChanges; diff --git a/indra/newview/res/toolbuy.cur b/indra/newview/res/toolbuy.cur Binary files differdeleted file mode 100644 index c61cd76bef..0000000000 --- a/indra/newview/res/toolbuy.cur +++ /dev/null diff --git a/indra/newview/res/toolopen.cur b/indra/newview/res/toolopen.cur Binary files differdeleted file mode 100644 index 8408f7c7eb..0000000000 --- a/indra/newview/res/toolopen.cur +++ /dev/null diff --git a/indra/newview/res/toolsit.cur b/indra/newview/res/toolsit.cur Binary files differdeleted file mode 100644 index 60b0e773e5..0000000000 --- a/indra/newview/res/toolsit.cur +++ /dev/null diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 87a8bd5787..4ac48c1857 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -123,10 +123,6 @@ TOOLPICKOBJECT3         CURSOR                  "toolpickobject3.cur"  ARROWCOPY               CURSOR                  "arrowcop.cur"  ARROWDRAGMULTI          CURSOR                  "llarrowdragmulti.cur"  ARROWCOPYMULTI          CURSOR                  "arrowcopmulti.cur" -TOOLSIT                 CURSOR                  "toolsit.cur" -TOOLBUY                 CURSOR                  "toolbuy.cur" -TOOLPAY                 CURSOR                  "toolpay.cur" -TOOLOPEN                CURSOR                  "toolopen.cur"  TOOLPIPETTE             CURSOR                  "toolpipette.cur"  TOOLPLAY                CURSOR                  "toolplay.cur"  TOOLPAUSE               CURSOR                  "toolpause.cur" @@ -138,8 +134,8 @@ TOOLMEDIAOPEN           CURSOR                  "toolmediaopen.cur"  //  VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,0,0 - PRODUCTVERSION 2,0,0,0 + FILEVERSION 2,0,0,2639 + PRODUCTVERSION 2,0,0,2639   FILEFLAGSMASK 0x3fL  #ifdef _DEBUG   FILEFLAGS 0x1L @@ -156,12 +152,12 @@ BEGIN          BEGIN              VALUE "CompanyName", "Linden Lab"              VALUE "FileDescription", "Second Life" -            VALUE "FileVersion", "2.0.0.0" +            VALUE "FileVersion", "2.0.0.2639"              VALUE "InternalName", "Second Life" -            VALUE "LegalCopyright", "Copyright  2001-2008, Linden Research, Inc." +            VALUE "LegalCopyright", "Copyright � 2001-2008, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life" -            VALUE "ProductVersion", "2.0.0.0" +            VALUE "ProductVersion", "2.0.0.2639"          END      END      BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index f106796cd9..2c09689ec6 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -384,12 +384,12 @@    <texture name="TaskPanel_BG" file_name="taskpanel/TaskPanel_BG.png" preload="false" scale.left="4" scale.top="146" scale.right="146" scale.bottom="4" />    <texture name="TaskPanel_Tab_Unselected" file_name="taskpanel/TaskPanel_Tab_Over.png" preload="false" scale.left="5" scale.top="30" scale.right="36" scale.bottom="5" /> -  <texture name="TextField_Search_Disabled" file_name="widgets/TextField_Search_Disabled.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" /> -  <texture name="TextField_Off" file_name="widgets/TextField_Off.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" /> -  <texture name="TextField_Search_Active" file_name="widgets/TextField_Search_Active.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" /> -  <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" /> -  <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" /> -  <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" /> +  <texture name="TextField_Search_Disabled" file_name="widgets/TextField_Search_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="TextField_Off" file_name="widgets/TextField_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="TextField_Search_Active" file_name="widgets/TextField_Search_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />    <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" />    <texture name="Toast" file_name="windows/Toast.png" preload="true" /> @@ -513,11 +513,6 @@    <texture name="toggle_button_off" file_name="toggle_button_off.png" preload="true" />    <texture name="toggle_button_selected" file_name="toggle_button_selected.png" preload="true" /> -<!--TODO: REPLACE CODE REFERENCE TO THIS ART WITH Icon_Minimize_Background above --> -  <texture name="minimize_inactive.tga" preload="true" /> -  <texture name="minimize.tga" preload="true" /> -  <texture name="minimize_pressed.tga"	preload="true" /> -    <texture name="sm_rounded_corners_simple.tga" scale.left="4" scale.top="4" scale.bottom="4" scale.right="4" />    <texture name="rounded_square.tga"	file_name="rounded_square.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" /> diff --git a/indra/newview/skins/default/xui/da/floater_camera.xml b/indra/newview/skins/default/xui/da/floater_camera.xml index 0eb090d2e4..c52f7ab832 100644 --- a/indra/newview/skins/default/xui/da/floater_camera.xml +++ b/indra/newview/skins/default/xui/da/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="move floater" title=""> -	<string name="rotate_tooltip"> +<floater name="camera_floater" title=""> +	<floater.string name="rotate_tooltip">  		Roter kamera omkring fokus -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Zoom kamera mod fokus -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		Flyt kamera op og ned, til venstre og højre -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Flyt kamera op og ned, til venstre og højre"/> +		<joystick_zoom name="zoom" tool_tip="Zoom kamera mod fokus"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/da/floater_color_picker.xml b/indra/newview/skins/default/xui/da/floater_color_picker.xml index e6cc5774ed..c8e1fc813b 100644 --- a/indra/newview/skins/default/xui/da/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/da/floater_color_picker.xml @@ -26,6 +26,6 @@  		Nuværende Farve:  	</text>  	<text name="(Drag below to save.)"> -		(Træk ned og gem.) +		(Træk ned og gem)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/de/floater_camera.xml b/indra/newview/skins/default/xui/de/floater_camera.xml index 198b5b07f2..f44db713d8 100644 --- a/indra/newview/skins/default/xui/de/floater_camera.xml +++ b/indra/newview/skins/default/xui/de/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="move floater"> -	<string name="rotate_tooltip"> +<floater name="camera_floater"> +	<floater.string name="rotate_tooltip">  		Kamera um Fokus drehen -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Kamera auf Fokus zoomen -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		Kamera nach oben, unten, links und rechts bewegen -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Kamera nach oben, unten, links und rechts bewegen"/> +		<joystick_zoom name="zoom" tool_tip="Kamera auf Fokus zoomen"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/de/floater_color_picker.xml b/indra/newview/skins/default/xui/de/floater_color_picker.xml index f53a1135dc..fa2f616249 100644 --- a/indra/newview/skins/default/xui/de/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/de/floater_color_picker.xml @@ -27,6 +27,6 @@  	</text>  	<text name="(Drag below to save.)">  (Nach unten ziehen, - um zu speichern.) + um zu speichern)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml index 3ab5c18300..e1f8011cbe 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml @@ -55,14 +55,13 @@               width="220">                  Type part of a person's name:              </text> -            <text_editor +            <line_editor  	     bevel_style="none"  	     border_style="line"  	     border.border_thickness="0"  	     commit_on_focus_lost="false"               follows="left|top|right"               height="23" -             layout="topleft"               left_delta="0"               name="Edit"               top_pad="0" @@ -85,38 +84,7 @@               top="52"               width="132" />          </panel> -        <panel -         border="true" -         height="150" -         label="Calling Cards" -         layout="topleft" -         left_delta="-1" -         name="CallingCardsPanel" -         top_delta="134" -         width="135"> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="16" -             layout="topleft" -             left="10" -             name="InstructSelectCallingCard" -             top="8" -             width="220"> -                Select a calling card: -            </text> -            <inventory_panel -             allow_multi_select="false" -             border="true" -             follows="left|top|right|bottom" -             height="110" -             layout="topleft" -             left_delta="0" -             name="InventoryPanel" -             top_pad="7" -             width="115" /> -        </panel> +          <panel           border="none"           height="150" @@ -188,8 +156,8 @@      <button       follows="right|bottom"       height="23" -     label="Ok" -     label_selected="Ok" +     label="OK" +     label_selected="OK"       name="Select"       top_pad="3"       left="46" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 053215f8ae..c65206d629 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2688,7 +2688,7 @@               height="18"               layout="topleft"               left="20" -             max_length="63" +			 read_only="true"               name="media_info"               select_on_focus="true"               top_delta="12" diff --git a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml index 0eb2c5e1be..4f501b65f3 100644 --- a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml +++ b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml @@ -1,24 +1,24 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<floater
 - can_minimize="false"
 - height="108"
 - layout="topleft"
 - name="whitelist_entry"
 - width="390">
 -
 -  <text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft"
 -     left="10" name="media_label" top="20">
 -        Enter a URL or URL pattern to add to the list of allowed domains
 -    </text>
 -
 -  <line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif"
 -	     height="20" left="10" name="whitelist_entry"
 -	     tool_tip="Enter a URL or URL pattern to White List"
 -	     width="350" />
 -
 -  <button follows="top|left" height="20" font="SansSerifSmall" label="OK"
 -     layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" />
 -  
 -  <button follows="top|left" height="20" font="SansSerifSmall" label="Cancel"
 -     layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" />
 -</floater>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_minimize="false" + height="108" + layout="topleft" + name="whitelist_entry" + width="390"> + +  <text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft" +     left="10" name="media_label" top="20"> +        Enter a URL or URL pattern to add to the list of allowed domains +    </text> + +  <line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif" +	     height="20" left="10" name="whitelist_entry" +	     tool_tip="Enter a URL or URL pattern to White List" +	     width="350" /> + +  <button follows="top|left" height="20" font="SansSerifSmall" label="OK" +     layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" /> +   +  <button follows="top|left" height="20" font="SansSerifSmall" label="Cancel" +     layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index b44acebbcf..1af07c35be 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -5,16 +5,16 @@  -->  <floater   bevel_style="in" - bg_alpha_color="PanelDefaultBackgroundColor" + bg_opaque_color="MouseGray"   can_close="false"   can_minimize="false" - height="190" + height="138"   layout="topleft"   name="inspect_avatar"   single_instance="true"   sound_flags="0"   visible="true" - width="300"> + width="245">    <!-- Allowed fields include:  	[BORN_ON] ("12/3/2008")  	[SL_PROFILE] (Second Life profile), @@ -36,107 +36,116 @@      Partner: [PARTNER]    </string>    <text -     follows="left|top|right|bottom" -     font="SansSerifHugeBold" -     height="70" -     left="10" +     follows="all" +     font="SansSerifLargeBold" +     height="18" +     left="8"       name="user_name" +     top="5"       text_color="white" -     top="20"       use_ellipses="true" -     value="Test Name" -     width="280" -     word_wrap="true" /> -    <text -     follows="left|top|right|bottom" -     font="SansSerifBig" -     height="20" -     left="10" -     name="user_subtitle" -     text_color="white" -     top="45" -     width="150" /> +     value="Grumpity ProductEngine" +     width="240" +     word_wrap="false" />      <!-- Leave text fields blank so it doesn't flash when data arrives off the network -->      <text -     follows="left|top|right|bottom" -     height="20" -     left="10" +     follows="all" +     height="16" +     left="8" +     value="Grumpity ProductEngine moose moose"       name="user_details" -     text_color="white" -     top="85" -     width="290" -     word_wrap="true" /> +     top_pad="0" +     width="170" +     use_ellipses="true" +     word_wrap="false" />      <text -     follows="left|top|right|bottom" -     height="20" -     left="10" +     follows="all" +   font="SansSerifSmallBold" +   text_color="White" +   height="18" +   left="8" +     name="user_subtitle" +     use_ellipses="true" +     top_pad="0" +     width="170" /> +    <text +     follows="all" +     height="16" +     left="8"       name="user_partner" -     text_color="white" -     top="105" -     width="290" -     word_wrap="true" /> -    <avatar_icon -     follows="left|top|right|bottom" -     height="60" -     left="230" -     mouse_opaque="true" -     name="avatar_icon"  -     top="15" -     width="60" /> +     top_pad="8" +     width="240" +     use_ellipses="true" +     word_wrap="false" />      <slider       follows="top|left" -     height="30" +     height="23"       increment="0.05" -     left="20" +     left="1"       max_val="0.95"       min_val="0.05"       name="volume_slider"       show_text="false"       tool_tip="Voice Volume" -     top="125" +     top_pad="0"       value="0.5" -     width="240" /> +     width="150" />      <button -     follows="left|top|right|bottom" +     follows="all"       height="16" -     image_disabled="icn_speaker_dark.tga" -     image_disabled_selected="icn_speaker-muted_dark.tga" -     image_hover_selected="icn_speaker-muted_dark.tga" -     image_selected="icn_speaker-muted_dark.tga" -     image_unselected="icn_speaker_dark.tga" +     image_disabled="Inv_Sound" +     image_disabled_selected="Inv_Sound" +     image_hover_selected="Inv_Sound" +     image_selected="Inv_Sound" +     image_unselected="Inv_Sound"       is_toggle="true" -     left="265" +     left_pad="0" +     top_delta="4"       name="mute_btn"       picture_style="true" -     top="132" -     width="32" /> +     width="16" /> +    <avatar_icon +     follows="all" +     height="38" +     right="-25" +     bevel_style="in" +     border_style="line" +     mouse_opaque="true" +     name="avatar_icon" +     top="24" +     width="38" />      <button       follows="top|left" -     font="SansSerif" -     height="20" +     height="18" +     image_disabled="ForwardArrow_Disabled" +     image_selected="ForwardArrow_Press" +     image_unselected="ForwardArrow_Off" +     layout="topleft" +     name="view_profile_btn" +     picture_style="true" +     right="-8" +     top="35" +     left_delta="110" +     tab_stop="false" +     width="18" /> +    <button +     follows="bottom|left" +     height="23"       label="Add Friend" -     left="10" +     left="8" +     top="246"       name="add_friend_btn" -     top_pad="10" -     width="105" /> -    <button -     follows="top|left" -     font="SansSerif" -     height="20" -     label="View Profile" -     left_delta="110" -     name="view_profile_btn" -     top_delta="0" -     width="105" /> +     width="100" />      <menu_button       follows="top|left" -     height="20" -     image_overlay="windows\Icon_Gear_Foreground.png" -     image_overlay_alignment="center" +     height="18" +     image_disabled="OptionsMenu_Disabled" +     image_selected="OptionsMenu_Press" +     image_unselected="OptionsMenu_Off"       menu_filename="menu_inspect_avatar_gear.xml"       name="gear_btn"       picture_style="true" -     top_delta="0" -     left_delta="110" -     width="60"/> +     right="-10" +     top="249" +     width="18" />  </floater> diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml index cc56f630b0..97df28aa30 100644 --- a/indra/newview/skins/default/xui/en/inspect_object.xml +++ b/indra/newview/skins/default/xui/en/inspect_object.xml @@ -17,8 +17,8 @@   width="300">    <string name="Creator">By [CREATOR]</string>    <string name="CreatorAndOwner"> -By [CREATOR] -Owned by [OWNER] +by [CREATOR] +owner [OWNER]    </string>    <!-- *TODO: Might need to change to [AMOUNT] if icon contains "L$" -->    <string name="Price">L$[AMOUNT]</string> @@ -28,57 +28,59 @@ Owned by [OWNER]    <text       follows="all"       font="SansSerifLargeBold" -     height="20" +     height="16"       left="8"       name="object_name" -     text_color="white" -     top="8" +     text_color="White" +     top="5"       use_ellipses="true"       value="Test Object Name That Is Really Long" -     width="268" /> +     width="291" />    <text     follows="all"     font="SansSerif"     height="30" -   left="10" +   left="8"     name="object_creator"     top_pad="0" -   width="280"> -By Longavatarname Johnsonlongstonnammer -Owned by James Linden -  </text> -  <text -   follows="all" -   height="45" -   left="100" -   name="object_description" -   top_pad="4" -   width="200" -   word_wrap="true"> -This is a really long description for an object being as how it is at least 80 characters in length and maybe more like 120 at this point. Who knows, really? +   use_ellipses="true" +   width="275"> +by Longavatarname Johnsonlongstonnammer +owner James Linden    </text>    <!-- *TODO: Replace this icon -->    <icon    name="price_icon" -  image_name="Favorite_Star_Active" -  left="5" +  image_name="Icon_For_Sale" +  left="7"    width="16"    height="16" -  top="79" +  top="52"    follows="left|top"    />    <text     follows="all"     font="SansSerifSmallBold" -   height="45" -   left="22" +   height="16" +   left_pad="5"     name="price_text"     text_color="white" -   top="80" +   top="54"     font_shadow="none" -   width="80"> +   width="150">  L$300,000    </text> +    <text +   follows="all" +   height="30" +   left="8" +   name="object_description" +   top_pad="0" +   width="291" +   use_ellipses="true" +   word_wrap="true"> +This is a really long description for an object being as how it is at least 80 characters in length and maybe more like 120 at this point. Who knows, really? +  </text>    <!-- Overlapping buttons for all default actions.  Show "Buy" if    for sale, "Sit" if can sit, etc. -->    <button @@ -88,7 +90,7 @@ L$300,000       label="Buy"       left="10"       name="buy_btn" -     top="116" +     top="114"       width="100" />    <button     follows="top|left" @@ -136,27 +138,30 @@ L$300,000     top_delta="0"     width="100" />    <!-- non-overlapping buttons here --> -  <menu_button +    <menu_button       follows="top|left" -     height="23" -     image_overlay="Icon_Gear_Foreground" -     image_overlay_alignment="center" -   right="-8" -     menu_filename="menu_inspect_object_gear.xml"  +     height="18" +     image_disabled="OptionsMenu_Disabled" +     image_selected="OptionsMenu_Press" +     image_unselected="OptionsMenu_Off" +     menu_filename="menu_inspect_avatar_gear.xml"       name="gear_btn"       picture_style="true" -   top_delta="0" -     width="30" /> -    <button +     right="-10" +     top_delta="5" +     width="18" /> +   <button       follows="top|left" -     height="22" -     image_overlay="TabIcon_Close_Off" +     height="18" +     image_disabled="ForwardArrow_Disabled" +     image_selected="ForwardArrow_Press" +     image_unselected="ForwardArrow_Off"       layout="topleft"       name="more_info_btn"       picture_style="true" -     right="-8" -     top="7" +     right="-5" +     top="20"       left_delta="110"       tab_stop="false" -     width="20" /> +     width="18" />  </floater> diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml index 71418d446a..c523185034 100644 --- a/indra/newview/skins/default/xui/en/language_settings.xml +++ b/indra/newview/skins/default/xui/en/language_settings.xml @@ -6,7 +6,13 @@  	<string name="MicrosoftLocale">english</string>  	<string name="DarwinLocale">C</string>  	<string name="LinuxLocale">C</string> -	 +   +  <!-- Note: for plural nouns, see strings.xml.  For example: +       AgeYearsA = singular, +       AgeYearsB = plural, +       AgeYearsC = plural for non-English languages like Russian +       For example, LLTrans::getCountString("AgeYears", 3) is plural form B +       in English and form C in Russian -->  	<!--   	datetimeToCodes["wkday"]	= "%a";		// Thu  	datetimeToCodes["weekday"]	= "%A";		// Thursday diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 2c77f61da6..b0839ce255 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -361,18 +361,6 @@              </menu_item_call>          </menu>          <menu_item_check -         label="Search" -         layout="topleft" -         name="Search" -         shortcut="control|F"> -            <menu_item_check.on_check -             function="Floater.Visible" -             parameter="search" /> -            <menu_item_check.on_click -             function="Floater.Toggle" -             parameter="search" /> -        </menu_item_check> -        <menu_item_check           label="World Map"           layout="topleft"           name="World Map" @@ -1072,6 +1060,18 @@           name="Shortcuts"           tear_off="true"           visible="false"> +            <menu_item_check +               label="Search" +               layout="topleft" +               name="Search" +               shortcut="control|F"> +            <menu_item_check.on_check +             function="Floater.Visible" +             parameter="search" /> +            <menu_item_check.on_click +             function="Floater.Toggle" +             parameter="search" /> +            </menu_item_check>              <menu_item_call               enabled="false"               label="Release Keys" @@ -2503,7 +2503,6 @@           tear_off="true">              <menu_item_check               label="Axes" -             layout="topleft"               name="Axes">                  <menu_item_check.on_check                   function="CheckControl" @@ -2514,7 +2513,6 @@              </menu_item_check>              <menu_item_check               label="Tangent Basis" -             layout="topleft"               name="Tangent Basis">                  <menu_item_check.on_check                   function="CheckControl" @@ -2525,7 +2523,6 @@              </menu_item_check>              <menu_item_call               label="Selected Texture Info Basis" -             layout="topleft"               name="Selected Texture Info Basis"               shortcut="control|alt|shift|T">                  <menu_item_call.on_click @@ -2533,7 +2530,6 @@              </menu_item_call>              <menu_item_check               label="Wireframe" -             layout="topleft"               name="Wireframe"               shortcut="control|shift|R">                  <menu_item_check.on_check @@ -2544,7 +2540,6 @@              </menu_item_check>              <menu_item_check               label="Object-Object Occlusion" -             layout="topleft"               name="Object-Object Occlusion"               shortcut="control|shift|O">                  <menu_item_check.on_check @@ -2558,7 +2553,6 @@              </menu_item_check>            <menu_item_check               label="Framebuffer Objects" -             layout="topleft"               name="Framebuffer Objects">              <menu_item_check.on_check               function="CheckControl" @@ -2571,7 +2565,6 @@             </menu_item_check>            <menu_item_check                         label="Deferred Rendering" -                       layout="topleft"                         name="Deferred Rendering">              <menu_item_check.on_check               function="CheckControl" @@ -2584,7 +2577,6 @@            </menu_item_check>            <menu_item_check                     label="Global Illumintation" -                   layout="topleft"                     name="Global Illumination">              <menu_item_check.on_check               function="CheckControl" @@ -2595,10 +2587,11 @@              <menu_item_check.on_enable                   function="Advanced.EnableRenderDeferredGI" />            </menu_item_check> - +           +          <menu_item_separator /> +                      <menu_item_check               label="Debug GL" -             layout="topleft"               name="Debug GL">                  <menu_item_check.on_check                   function="CheckControl" @@ -2609,7 +2602,6 @@              </menu_item_check>              <menu_item_check               label="Debug Pipeline" -             layout="topleft"               name="Debug Pipeline">                  <menu_item_check.on_check                   function="CheckControl" @@ -2620,7 +2612,6 @@              </menu_item_check>              <menu_item_check               label="Fast Alpha" -             layout="topleft"               name="Fast Alpha">                  <menu_item_check.on_check                   function="CheckControl" @@ -2631,7 +2622,6 @@              </menu_item_check>              <menu_item_check               label="Animation Textures" -             layout="topleft"               name="Animation Textures">                  <menu_item_check.on_check                   function="CheckControl" @@ -2642,7 +2632,6 @@              </menu_item_check>              <menu_item_check               label="Disable Textures" -             layout="topleft"               name="Disable Textures">                  <menu_item_check.on_check                   function="Advanced.CheckDisableTextures" @@ -2652,7 +2641,6 @@              </menu_item_check>              <menu_item_check               label="Texture Atlas" -             layout="topleft"               name="Texture Atlas">                <menu_item_check.on_check                 function="Advanced.CheckTextureAtlas" @@ -2662,7 +2650,6 @@              </menu_item_check>                <menu_item_check               label="Render Attached Lights" -             layout="topleft"               name="Render Attached Lights">                  <menu_item_check.on_check                   function="CheckControl" @@ -2673,7 +2660,6 @@              </menu_item_check>              <menu_item_check               label="Render Attached Particles" -             layout="topleft"               name="Render Attached Particles">                  <menu_item_check.on_check                   function="CheckControl" @@ -2682,6 +2668,16 @@                   function="Advanced.HandleAttchedLightParticles"                   parameter="RenderAttachedParticles" />              </menu_item_check> +            <menu_item_check +             label="Hover Highlight Objects" +             name="Hover Highlight Objects"> +                <menu_item_check.on_check +                 function="CheckControl" +                 parameter="RenderHighlightEnable" /> +                <menu_item_check.on_click +                 function="ToggleControl" +                 parameter="RenderHighlightEnable" /> +            </menu_item_check>          </menu>          <menu           create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 829c2e02d8..f141a909a8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -761,7 +761,7 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now?  	name="url"  	openexternally = "1"> -			http://join/secondlife.com/ +			http://join.secondlife.com/      </url>      <usetemplate       name="okcancelbuttons" diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index 1e7ca7aa3f..f1e2560356 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -64,7 +64,7 @@    <web_browser      border_visible="false"  -   bottom_delta="-120"  +   bottom_delta="-133"      follows="top|left"     left="120"      name="preview_media"  @@ -83,7 +83,7 @@    </text>    <text  -   bottom_delta="-20"  +   bottom_delta="-5"      follows="top|left"      height="15"     left="10"  @@ -161,39 +161,92 @@     radio_style="false"      width="150" /> -  <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall" -	     height="16" initial_value="false" -	     label="Use Default Alternative Image" left="10" mouse_opaque="true" -	     name="alt_image_enable" radio_style="false" width="150" /> +  <check_box  +   bottom_delta="-25"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Use Default Alternative Image"  +   left="10"  +   mouse_opaque="true" +   name="alt_image_enable"  +   radio_style="false"  +   width="150" /> -  <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall" -	     height="16" initial_value="false" -	     label="Auto Play Media" left="10" mouse_opaque="true" -	     name="auto_play" radio_style="false" width="150" /> -  <text bottom_delta="-14" follows="top|left" height="15" left="30" width="340"  -        enabled="false" name=""> +  <check_box  +   bottom_delta="-25"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Auto Play Media"  +   left="10"  +   mouse_opaque="true" +   name="auto_play"  +   radio_style="false"  +   width="150" /> +    +  <text  +   bottom_delta="-14"  +   follows="top|left"  +   height="15"  +   left="30"  +   width="340"  +   enabled="false"  +   name="meida_setting_note">      Note: Residents can override this setting    </text> -  <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall" -	     height="16" initial_value="false" -	     label="Auto Scale Media on Face of Object" left="10" mouse_opaque="true" -	     name="auto_scale" radio_style="false" width="150" /> -  <text bottom_delta="-20" follows="top|left" height="15" left="30" name=""> +  <check_box  +   bottom_delta="-25"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Auto Scale Media on Face of Object"  +   left="10"  +   mouse_opaque="true" +   name="auto_scale"  +   radio_style="false"  +   width="150" /> +    +  <text  +   bottom_delta="-20"  +   follows="top|left"  +   height="15"  +   left="30"  +   name="">      Size:    </text> -  <spinner bottom_delta="0" -	     decimal_digits="0" enabled="true" follows="left|top" height="16" -	     increment="1" initial_val="256" label="" label_width="0" -	     left_delta="40" max_val="2000" min_val="0" mouse_opaque="true" -	     name="width_pixels" width="50" /> +   +  <spinner  +   bottom_delta="0" +   decimal_digits="0"  +   enabled="true"  +   follows="left|top"  +   height="16" +   increment="1"  +   initial_val="256"  +   label=""  +   label_width="0" +   left_delta="40"  +   max_val="2048"  +   min_val="0"  +   mouse_opaque="true" +   name="width_pixels"  +   width="50" /> +       <text bottom_delta="0" follows="top|left" height="15" left_delta="60" name="">      X    </text>    <spinner bottom_delta="0"  	     decimal_digits="0" enabled="true" follows="left|top" height="16"  	     increment="1" initial_val="256" label="" label_width="0" -	     left_delta="20" max_val="2000" min_val="0" mouse_opaque="true" +	     left_delta="20" max_val="2048" min_val="0" mouse_opaque="true"  	     name="height_pixels" width="50" />  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml index f11364874a..0cc1406d62 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml @@ -1,49 +1,137 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel border="true" enabled="true" follows="left|top|right|bottom" -    height="500" label="Controls" left="102" mouse_opaque="true" -    name="Media settings for controls" width="365"> +<panel  + border="true"  + enabled="true"  + follows="left|top|right|bottom" + height="500"  + label="Controls"  + left="102"  + mouse_opaque="true" + name="Media settings for controls"  + width="365"> -  <text bottom_delta="-50" follows="top|left" height="15" left="10" name="" enabled="false"> +  <text  +   bottom_delta="-50"  +   follows="top|left"  +   height="15"  +   left="10"  +   name="media_perms_label_owner"  +   enabled="false">      Owner    </text> -  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall" -         height="16" initial_value="false" -         label="Disable Navigation & Interactivity" left="30" mouse_opaque="true" -         name="perms_owner_interact" radio_style="false" width="250" /> +   +  <check_box  +   bottom_delta="-22"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Disable Navigation & Interactivity"  +   left="30"  +   mouse_opaque="true" +   name="perms_owner_interact"  +   radio_style="false"  +   width="250" /> -  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall" -         height="16" initial_value="false" -         label="Hide Control Bar" left="30" mouse_opaque="true" -         name="perms_owner_control" radio_style="false" width="250" /> +  <check_box  +   bottom_delta="-22"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Hide Control Bar"  +   left="30"  +   mouse_opaque="true" +   name="perms_owner_control"  +   radio_style="false"  +   width="250" /> -  <text bottom_delta="-36" follows="top|left" height="15" left="10" name="perms_group_name_label" enabled="false"> +  <text  +   bottom_delta="-36"  +   follows="top|left"  +   height="15"  +   left="10"  +   name="media_perms_label_group"  +   enabled="false">      Group    </text> -  <name_box bottom_delta="-5" enabled="false" follows="left|top" font="SansSerif" -	     height="20" left="60" name="perms_group_name" -       value =""  -	     width="200" /> -  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall" -         height="16" initial_value="false" -         label="Disable Navigation & Interactivity" left="30" mouse_opaque="true" -         name="perms_group_interact" radio_style="false" width="250" /> +   +  <name_box  +   bottom_delta="-5"  +   enabled="false"  +   follows="left|top"  +   font="SansSerif" +   height="20" left="60"  +   name="perms_group_name" +   value =""  +   width="200" /> +    +  <check_box  +   bottom_delta="-22"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Disable Navigation & Interactivity"  +   left="30"  +   mouse_opaque="true" +   name="perms_group_interact"  +   radio_style="false"  +   width="250" /> -  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall" -         height="16" initial_value="false" -         label="Hide Control Bar" left="30" mouse_opaque="true" -         name="perms_group_control" radio_style="false" width="250" /> +  <check_box  +   bottom_delta="-22"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Hide Control Bar"  +   left="30"  +   mouse_opaque="true" +   name="perms_group_control"  +   radio_style="false"  +   width="250" /> -  <text bottom_delta="-36" follows="top|left" height="15" left="10" name="" enabled="false"> +  <text  +   bottom_delta="-36"  +   follows="top|left"  +   height="15"  +   left="10"  +   name="media_perms_label_anyone"  +   enabled="false">      Anyone    </text> -  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall" -         height="16" initial_value="false" -         label="Disable Navigation & Interactivity" left="30" mouse_opaque="true" -         name="perms_anyone_interact" radio_style="false" width="250" /> +   +  <check_box  +   bottom_delta="-22"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Disable Navigation & Interactivity"  +   left="30"  +   mouse_opaque="true" +   name="perms_anyone_interact"  +   radio_style="false"  +   width="250" /> -  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall" -         height="16" initial_value="false" -         label="Hide Control Bar" left="30" mouse_opaque="true" -         name="perms_anyone_control" radio_style="false" width="250" /> +  <check_box  +   bottom_delta="-22"  +   enabled="true"  +   follows="left|top"  +   font="SansSerifSmall" +   height="16"  +   initial_value="false" +   label="Hide Control Bar"  +   left="30"  +   mouse_opaque="true" +   name="perms_anyone_control"  +   radio_style="false"  +   width="250" />  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 8b9fe2cf77..696e0b3c33 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -60,7 +60,7 @@           left="5"           name="teleport_btn"           top="0" -         width="90" /> +         width="70" />          <button           follows="bottom|left"           font="SansSerifSmallBold" @@ -70,7 +70,7 @@           left_pad="5"           name="map_btn"           top="0" -         width="80" /> +         width="50" />          <button           enabled="false"           follows="bottom|left" @@ -83,40 +83,54 @@           top="0"           width="60" />          <button +         follows="bottom|left" +         font="SansSerifSmallBold" +         height="25" +         label="Edit" +         layout="topleft" +         left_pad="5" +         name="edit_btn" +         top="0" +         width="50" /> +        <button           follows="bottom|right"           font="SansSerifSmallBold"           height="25"           label="▼"           layout="topleft" -         left_pad="5"           name="overflow_btn" +         right="-10"           top="0"           width="30" />          <button -         follows="bottom|left" +         follows="bottom|right"           font="SansSerifSmallBold"           height="25" -         image_disabled="widgets/SegmentedBtn_Left_Disabled.png" -         image_selected="widgets/SegmentedBtn_Left_Selected.png" -         image_unselected="widgets/SegmentedBtn_Left_Off.png" -         label="Create" +         label="Close"           layout="topleft" -         left="5" -         name="create_landmark_btn" +         name="close_btn" +         right="-10"           top="0" -         width="70" /> +         width="60" />          <button -         follows="bottom|left" +         follows="bottom|right"           font="SansSerifSmallBold"           height="25" -         image_disabled="widgets/ComboButton_Disabled.png" -         image_selected="widgets/ComboButton_Selected.png" -         image_unselected="widgets/ComboButton_Off.png" -         label="▼" +         label="Cancel" +         layout="topleft" +         name="cancel_btn" +         right="-10" +         top="0" +         width="60" /> +        <button +         follows="bottom|right" +         font="SansSerifSmallBold" +         height="25" +         label="Save"           layout="topleft" -         left_pad="0" -         name="folder_menu_btn" +         name="save_btn" +         right="-75"           top="0" -         width="20" /> +         width="60" />      </panel>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml index 3b1b049ff2..9845a9eb78 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml @@ -4,7 +4,7 @@   bottom="0"   follows="left|top|right"   height="30" - width="305" + width="333"   layout="topleft"   left="0"   name="sidetray_tab_panel"> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 3a5347fe12..d124a4cdfa 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -44,23 +44,12 @@  	<!-- Tooltip, lltooltipview.cpp --> -	<!-- *TODO: Most of these are now unused, eliminate them -->  	<string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar -->  	<string name="TooltipNoName">(no name)</string> <!-- No name on an object -->  	<string name="TooltipOwner">Owner:</string> <!-- Owner name follows -->  	<string name="TooltipPublic">Public</string> <!-- Public permissions on an object -->  	<string name="TooltipIsGroup">(Group)</string> <!-- The name before this text is that of a group --> -	<string name="TooltipFlagScript">Script</string> -	<string name="TooltipFlagPhysics">Physics</string> -	<string name="TooltipFlagTouch">Touch</string> -	<string name="TooltipFlagL$">L$</string> -	<string name="TooltipFlagDropInventory">Drop Inventory</string> -	<string name="TooltipFlagPhantom">Phantom</string> -	<string name="TooltipFlagTemporary">Temporary</string> -	<string name="TooltipFlagRightClickMenu">(Right-click for menu)</string> -	<string name="TooltipFreeToCopy">Free to copy</string>  	<string name="TooltipForSaleL$">For Sale: L$[AMOUNT]</string> <!-- L$ version --> -	<string name="TooltipForSaleMsg">For Sale: [MESSAGE]</string> <!-- Message (RetrievingData) -->  	<string name="TooltipFlagGroupBuild">Group Build</string>  	<string name="TooltipFlagNoBuild">No Build</string>  	<string name="TooltipFlagNoEdit">Group Build</string> @@ -1940,16 +1929,23 @@ this texture in your inventory    <string name="DaysOld">[AGEDAYS] old</string>    <string name="TodayOld">Joined today</string> -  <!-- AgeYearsA = singular, AgeYearsB = plural, see logic in -      LLTrans::getCountString() --> +  <!-- AgeYearsA = singular, +       AgeYearsB = plural, +       AgeYearsC = plural for non-English languages like Russian +       For example, LLTrans::getCountString("AgeYears", 3) is plural form B +       in English and form C in Russian -->    <string name="AgeYearsA">[COUNT] year</string>    <string name="AgeYearsB">[COUNT] years</string> +  <string name="AgeYearsC">[COUNT] years</string>    <string name="AgeMonthsA">[COUNT] month</string>    <string name="AgeMonthsB">[COUNT] months</string> +  <string name="AgeMonthsC">[COUNT] months</string>    <string name="AgeWeeksA">[COUNT] week</string>    <string name="AgeWeeksB">[COUNT] weeks</string> +  <string name="AgeWeeksC">[COUNT] weeks</string>    <string name="AgeDaysA">[COUNT] day</string>    <string name="AgeDaysB">[COUNT] days</string> +  <string name="AgeDaysC">[COUNT] days</string>    <!-- Account types, see LLAvatarPropertiesProcessor -->    <string name="AcctTypeResident">Resident</string> @@ -2177,6 +2173,9 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh  	<string name="'">'</string>	  	<string name="---">---</string>										 +	<!-- media --> +	<string name="Multiple Media">Multiple Media</string> +	  	<!-- OSMessageBox messages -->  	<string name="MBCmdLineError">  		An error was found parsing the command line. @@ -2246,225 +2245,585 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	</string>  	<!-- Avatar Shape Information --> -    <string name="Attached Earlobes">Attached Earlobes</string> -	<string name="Arm Length">Arm Length</string>	 -    <string name="Back Bangs Down">Back Bangs Down</string> -    <string name="Back Bangs Up">Back Bangs Up</string> -    <string name="Back Hair Down">Back Hair Down</string> -    <string name="Back Hair Up">Back Hair Up</string> -    <string name="Belly Size">Belly Size</string>	 -	<string name="Blonde Hair">Blonde Hair</string> -    <string name="Big Eyeball">Big Eyeball</string> -    <string name="Big Hair Back">Big Hair: Back</string> -    <string name="Big Hair Front">Big Hair: Front</string> -    <string name="Big Hair Top">Big Hair: Top</string> -	<string name="Body Fat">Body Fat</string> -    <string name="Body Thickness">Body Thickness</string> -    <string name="Breast Buoyancy">Breast Buoyancy</string> -    <string name="Breast Cleavage">Breast Cleavage</string> -	<string name="Breast Size">Breast Size</string> -    <string name="Bridge Width">Bridge Width</string> -    <string name="Brow Size">Brow Size</string> -    <string name="Butt Size">Butt Size</string> -    <string name="Cheek Bones">Cheek Bones</string> -    <string name="Chest Size">Chest Size</string> -    <string name="Chin Angle">Chin Angle</string> -    <string name="Chin Cleft">Chin Cleft</string> -    <string name="Chin Depth">Chin Depth</string> -    <string name="Chin-Neck">Chin-Neck</string> -	<string name="Collar Back">Collar Back</string> -	<string name="Collar Front">Collar Front</string> -    <string name="Crooked Nose">Crooked Nose</string> -    <string name="Cuff Flare">Cuff Flare</string> -    <string name="Ear Angle">Ear Angle</string> -    <string name="Ear Size">Ear Size</string> -    <string name="Ear Tips">Ear Tips</string> -    <string name="Egg Head">Egg Head</string> -    <string name="Eye Bags">Eye Bags</string> -	<string name="Eye Color">Eye Color</string> -    <string name="Eye Depth">Eye Depth</string> -	<string name="Eye Lightness">Eye Lightness</string> -    <string name="Eye Opening">Eye Opening</string> -    <string name="Eye Pop">Eye Pop</string> -    <string name="Eye Size">Eye Size</string> -    <string name="Eye Spacing">Eye Spacing</string> -    <string name="Eyeball Size">Eyeball Size</string> -    <string name="Eyebrow Arc">Eyebrow Arc</string> -    <string name="Eyebrow Height">Eyebrow Height</string> -    <string name="Eyebrow Points">Eyebrow Points</string> -    <string name="Eyelash Length">Eyelash Length</string> -	<string name="Eyeliner">Eyeliner</string> -	<string name="Eyeliner Color">Eyeliner Color</string> -	<string name="Face Shear">Face Shear</string> -	<string name="Facial Definitionr">Facial Definition</string> -    <string name="Fat Head">Fat Head</string> -    <string name="Fat Lower Lip">Fat Lower Lip</string> -    <string name="Fat Torso">Fat Torso</string> -    <string name="Fat Upper Lip">Fat Upper Lip</string> -    <string name="Foot Size">Foot Size</string> -	<string name="Freckles">Freckles</string> -    <string name="Front Bangs Down">Front Bangs Down</string> -    <string name="Front Bangs Up">Front Bangs Up</string> -    <string name="Front Hair Down">Front Hair Down</string> -    <string name="Front Hair Up">Front Hair Up</string> -	<string name="Forehead Angle">Forehead Angle</string> -    <string name="Full Hair Sides">Full Hair Sides</string> -	<string name="Glove Fingers">Glove Fingers</string>  -	<string name="Glove Length">Glove Length</string> -    <string name="Hair Thickess">Hair Thickess</string> -    <string name="Hair Tilted Left">Hair Tilted Left</string> -    <string name="Hair Tilted Right">Hair Tilted Right</string> -    <string name="Hair Volume">Hair: Volume</string> -	<string name="Hand Size">Hand Size</string> -	<string name="Head Length">Head Length</string> -    <string name="Head Shape">Head Shape</string> -    <string name="Head Size">Head Size</string> -    <string name="Head Stretch">Head Stretch</string> -    <string name="Heel Height">Heel Height</string> -    <string name="Heel Shape">Heel Shape</string> -    <string name="Height">Height</string> -    <string name="Hip Width">Hip Width</string> -	<string name="Hip Length">Hip Length</string> -    <string name="Inner Eye Corner">Inner Eye Corner</string> -    <string name="Jacket Length">Jacket Length</string> -    <string name="Jacket Wrinkles">Jacket Wrinkles</string> -    <string name="Jowls">Jowls</string>	 -    <string name="Jaw Angle">Jaw Angle</string> -    <string name="Jaw Jut">Jaw Jut</string> -    <string name="Jaw Shape">Jaw Shape</string> -    <string name="Knee Angle">Knee Angle</string> -    <string name="Left Part">Left Part</string> -    <string name="Leg Muscles">Leg Muscles</string> -	<string name="Leg Length">Leg Length</string> -    <string name="Lip Cleft">Lip Cleft</string> -    <string name="Lip Cleft Depth">Lip Cleft Depth</string> -    <string name="Lip Fullness">Lip Fullness</string> -	<string name="Lip Pinkness">Lip Pinkness</string> -    <string name="Lip Ratio">Lip Ratio</string> -    <string name="Lip Thickness">Lip Thickness</string>	 -    <string name="Lip Width">Lip Width</string> -    <string name="Longcuffs">Longcuffs</string> -    <string name="Love Handles">Love Handles</string> -    <string name="Lower Bridge">Lower Bridge</string> -    <string name="Lower Cheeks">Lower Cheeks</string> -    <string name="Middle Part">Middle Part</string> -    <string name="Mouth Corner">Mouth Corner</string> -    <string name="Mouth Position">Mouth Position</string> -	<string name="Nail Polish">Nail Polish</string> -	<string name="Nail Polish Color">Nail Polish Color</string> -	<string name="Neck Length">Neck Length</string> -	<string name="Neck Thickness">Neck Thickness</string> -    <string name="Nose Size">Nose Size</string> -    <string name="Nose Thickness">Nose Thickness</string> -    <string name="Nose Tip Angle">Nose Tip Angle</string> -    <string name="Nose Tip Shape">Nose Tip Shape</string> -    <string name="Nose Width">Nose Width</string> -    <string name="Nostril Division">Nostril Division</string> -    <string name="Nostril Width">Nostril Width</string> -    <string name="Open Front">Open Front</string> -	<string name="Lipstick Color">Lipstick Color</string> -	<string name="Lipstick">Lipstick</string> -	<string name="Lipgloss">Lipgloss</string> -	<string name="Blush">Blush</string> -	<string name="Blush Color">Blush Color</string> -	<string name="Blush Opacity">Blush Opacity</string> -	<string name="Inner Shadow">Inner Shadow</string> -	<string name="In Shdw Color">Inner Shadow Color</string> -	<string name="In Shdw Opacity">Inner Shadow Opacity</string> -	<string name="Body Definition">Body Definition</string> -	<string name="Body Freckles">Body Freckles</string> -	<string name="Facial Definition">Facial Definition</string> -	<string name="Hair Front">Hair: Front</string> -	<string name="Hair Sides">Hair: Sides</string> -	<string name="Hair Back">Hair: Back</string> -	<string name="Front Fringe">Front Fringe</string> -	<string name="Side Fringe">Side Fringe</string> -	<string name="Back Fringe">Back Fringe</string> -	<string name="Hair Sweep">Hair Sweep</string> -	<string name="Pigtails">Pigtails</string> -	<string name="Ponytail">Ponytail</string> -	<string name="Hair Tilt">Hair Tilt</string> -	<string name="Eyebrow Size">Eyebrow Size</string> -	<string name="Eyebrow Density">Eyebrow Density</string> -	<!-- string name="Hair Thickess">Hair Thickess</string    Need a second string for Body Parts > Hair > Facial? --> -	<string name="Sideburns">Sideburns</string> -	<string name="Moustache">Moustache</string> -	<string name="Soulpatch">Soulpatch</string> -	<string name="Chin Curtains">Chin Curtains</string> -    <string name="Outer Eye Corner">Outer Eye Corner</string> -	<string name="Outer Shadow">Outer Shadow</string> -	<string name="Out Shdw Opacity">Outer Shadow Opacity</string> -	<string name="Out Shdw Color">Outer Shadow Color</string>	 -    <string name="Package">Package</string> -    <string name="Pants Crotch">Pants Crotch</string>  -	<string name="Pants Fit">Pants Fit</string> -	<string name="Pants Length">Pants Length</string> -	<string name="Pants Waist">Pants Waist</string> -	<string name="Pants Wrinkles">Pants Wrinkles</string> -    <string name="Part Bangs">Part Bangs</string> -    <string name="Pectorals">Pectorals</string> -    <string name="Platform Height">Platform Height</string> -    <string name="Platform Width">Platform Width</string> -	<string name="Pigment">Pigment</string> -    <string name="Puffy Eyelids">Puffy Eyelids</string> -	<string name="Rainbow Color">Rainbow Color</string> -	<string name="Red Hair">Red Hair</string> -    <string name="Right Part">Right Part</string> -    <string name="Round Forehead">Round Forehead</string> -	<string name="Rosy Complexion">Rosy Complexion</string> -    <string name="Ruddiness">Ruddiness</string> -    <string name="Rumpled Hair">Rumpled Hair</string> -    <string name="Saddle Bags">Saddle Bags</string> -    <string name="Scrawny Leg">Scrawny Leg</string> -    <string name="Shear Back">Shear Back</string> -    <string name="Shear Face">Shear Face</string> -    <string name="Shear Front">Shear Front</string> -    <string name="Shift Mouth">Shift Mouth</string> -	<string name="Shirt Bottom">Shirt Bottom</string> -    <string name="Shirt Fit">Shirt Fit</string> -	<string name="Shirt Wrinkles">Shirt Wrinkles</string> -	<string name="Shoe Height">Shoe Height</string> -    <string name="Shoulders">Shoulders</string> -    <string name="Side Bangs Down">Side Bangs Down</string> -    <string name="Side Bangs Up">Side Bangs Up</string> -    <string name="Sides Hair Down">Sides Hair Down</string> -    <string name="Sides Hair Up">Sides Hair Up</string> -    <string name="Skirt Fit">Skirt Fit</string> -	<string name="Skirt Length">Skirt Length</string> -    <string name="Slanted Forehead">Slanted Forehead</string>  -	<string name="Sleeve Length">Sleeve Length</string> -    <string name="Sleeve Looseness">Sleeve Looseness</string>  -	<string name="Slit Back">Slit: Back</string>  -	<string name="Slit Front">Slit: Front</string>  -	<string name="Slit Left">Slit: Left</string>  -	<string name="Slit Right">Slit: Right</string>  -	<string name="Socks Length">Socks Length</string> -    <string name="Spiked Hair">Spiked Hair</string> -    <string name="Squash/Stretch Head">Squash/Stretch Head</string> -    <string name="Swept Back Hair">Swept Back Hair</string> -    <string name="Swept Forward Hair">Swept Forward Hair</string> -    <string name="Taper Back">Taper Back</string> -    <string name="Taper Front">Taper Front</string> -    <string name="Toe Shape">Toe Shape</string> -    <string name="Toe Thickness">Toe Thickness</string> -	<string name="Toe Length">Toe Length</string> -	<string name="Torso Length">Torso Length</string> -    <string name="Torso Muscles">Torso Muscles</string> -    <string name="Torso Scrawny">Torso Scrawny</string> -    <string name="Upper Bridge">Upper Bridge</string> -    <string name="Upper Cheeks">Upper Cheeks</string> -    <string name="Upper Chin Cleft">Upper Chin Cleft</string> -    <string name="Upper Eyelid Fold">Upper Eyelid Fold</string> -	<string name="Waist Height">Waist Height</string> -	<string name="White Hair">White Hair</string> -    <string name="big belly skirt">big belly skirt</string> -    <string name="bigbutt skirt">bigbutt skirt</string> -    <string name="bustle skirt">Bustle Skirt</string> -    <string name="legs skirt">legs skirt</string> -    <string name="loose skirt">loose skirt</string> -    <string name="poofy skirt">poofy skirt</string> -    <string name="tight skirt">tight skirt</string>	 -	<string name="wrinkles">Wrinkles</string>	 +<string name="5 O'Clock Shadow">5 O'Clock Shadow</string> +<string name="5 O'Clock Shadow bump">5 O'Clock Shadow bump</string> +<string name="All White">All White</string> +<string name="Anime Eyes">Anime Eyes</string> +<string name="Arced">Arced</string> +<string name="Arm Length">Arm Length</string> +<string name="Attached">Attached</string> +<string name="Attached Earlobes">Attached Earlobes</string> +<string name="BELLY">BELLY</string> +<string name="Back Bangs">Back Bangs</string> +<string name="Back Bangs Down">Back Bangs Down</string> +<string name="Back Bangs Up">Back Bangs Up</string> +<string name="Back Fringe">Back Fringe</string> +<string name="Back Hair">Back Hair</string> +<string name="Back Hair Down">Back Hair Down</string> +<string name="Back Hair Up">Back Hair Up</string> +<string name="Baggy">Baggy</string> +<string name="Bangs">Bangs</string> +<string name="Bangs Down">Bangs Down</string> +<string name="Bangs Up">Bangs Up</string> +<string name="Beady Eyes">Beady Eyes</string> +<string name="Belly Size">Belly Size</string> +<string name="Big">Big</string> +<string name="Big Butt">Big Butt</string> +<string name="Big Eyeball">Big Eyeball</string> +<string name="Big Hair Back">Big Hair Back</string> +<string name="Big Hair Front">Big Hair Front</string> +<string name="Big Hair Top">Big Hair Top</string> +<string name="Big Head">Big Head</string> +<string name="Big Pectorals">Big Pectorals</string> +<string name="Big Spikes">Big Spikes</string> +<string name="Black">Black</string> +<string name="Blonde">Blonde</string> +<string name="Blonde Hair">Blonde Hair</string> +<string name="Blush">Blush</string> +<string name="Blush Color">Blush Color</string> +<string name="Blush Opacity">Blush Opacity</string> +<string name="Body Definition">Body Definition</string> +<string name="Body Fat">Body Fat</string> +<string name="Body Freckles">Body Freckles</string> +<string name="Body Thick">Body Thick</string> +<string name="Body Thickness">Body Thickness</string> +<string name="Body Thin">Body Thin</string> +<string name="Bottom">Bottom</string> +<string name="Bottom Left">Bottom Left</string> +<string name="Bottom Right">Bottom Right</string> +<string name="Bottom bump">Bottom bump</string> +<string name="Bow Legged">Bow Legged</string> +<string name="Breast Buoyancy">Breast Buoyancy</string> +<string name="Breast Cleavage">Breast Cleavage</string> +<string name="Breast Size">Breast Size</string> +<string name="Bridge Width">Bridge Width</string> +<string name="Broad">Broad</string> +<string name="Brow Size">Brow Size</string> +<string name="Bug Eyes">Bug Eyes</string> +<string name="Bugged Eyes">Bugged Eyes</string> +<string name="Bulbous">Bulbous</string> +<string name="Bulbous Nose">Bulbous Nose</string> +<string name="Bump base">Bump base</string> +<string name="Bump upperdef">Bump upperdef</string> +<string name="Bushy Eyebrows">Bushy Eyebrows</string> +<string name="Bushy Hair">Bushy Hair</string> +<string name="Butt Size">Butt Size</string> +<string name="CHEST">CHEST</string> +<string name="Center">Center</string> +<string name="Center 2">Center 2</string> +<string name="Chaplin">Chaplin</string> +<string name="Cheek Bones">Cheek Bones</string> +<string name="Chest">Chest</string> +<string name="Chest Size">Chest Size</string> +<string name="Chin">Chin</string> +<string name="Chin Angle">Chin Angle</string> +<string name="Chin Cleft">Chin Cleft</string> +<string name="Chin Curtains">Chin Curtains</string> +<string name="Chin Curtains bump">Chin Curtains bump</string> +<string name="Chin Depth">Chin Depth</string> +<string name="Chin Heavy">Chin Heavy</string> +<string name="Chin In">Chin In</string> +<string name="Chin Out">Chin Out</string> +<string name="Chin-Neck">Chin-Neck</string> +<string name="Clear">Clear</string> +<string name="Cleft">Cleft</string> +<string name="Close Set Eyes">Close Set Eyes</string> +<string name="Closed">Closed</string> +<string name="Closed Back">Closed Back</string> +<string name="Closed Front">Closed Front</string> +<string name="Closed Left">Closed Left</string> +<string name="Closed Right">Closed Right</string> +<string name="Coin Purse">Coin Purse</string> +<string name="Collar Back">Collar Back</string> +<string name="Collar Back Height Cloth">Collar Back Height Cloth</string> +<string name="Collar Back Shadow Height">Collar Back Shadow Height</string> +<string name="Collar Back bump">Collar Back bump</string> +<string name="Collar Front">Collar Front</string> +<string name="Collar Front Height Cloth">Collar Front Height Cloth</string> +<string name="Collar Front Shadow Height">Collar Front Shadow Height</string> +<string name="Collar Front bump">Collar Front bump</string> +<string name="Corner Down">Corner Down</string> +<string name="Corner Normal">Corner Normal</string> +<string name="Corner Up">Corner Up</string> +<string name="Creased">Creased</string> +<string name="Crooked Nose">Crooked Nose</string> +<string name="Cropped Hair">Cropped Hair</string> +<string name="Cuff Flare">Cuff Flare</string> +<string name="Dark">Dark</string> +<string name="Dark Green">Dark Green</string> +<string name="Darker">Darker</string> +<string name="Deep">Deep</string> +<string name="Default Heels">Default Heels</string> +<string name="Default Toe">Default Toe</string> +<string name="Dense">Dense</string> +<string name="Dense hair">Dense hair</string> +<string name="Double Chin">Double Chin</string> +<string name="Downturned">Downturned</string> +<string name="Duffle Bag">Duffle Bag</string> +<string name="Ear Angle">Ear Angle</string> +<string name="Ear Size">Ear Size</string> +<string name="Ear Tips">Ear Tips</string> +<string name="Egg Head">Egg Head</string> +<string name="Eye Bags">Eye Bags</string> +<string name="Eye Color">Eye Color</string> +<string name="Eye Depth">Eye Depth</string> +<string name="Eye Lightness">Eye Lightness</string> +<string name="Eye Opening">Eye Opening</string> +<string name="Eye Pop">Eye Pop</string> +<string name="Eye Size">Eye Size</string> +<string name="Eye Spacing">Eye Spacing</string> +<string name="Eyeball Size">Eyeball Size</string> +<string name="Eyebrow Arc">Eyebrow Arc</string> +<string name="Eyebrow Density">Eyebrow Density</string> +<string name="Eyebrow Density Bump">Eyebrow Density Bump</string> +<string name="Eyebrow Height">Eyebrow Height</string> +<string name="Eyebrow Points">Eyebrow Points</string> +<string name="Eyebrow Size">Eyebrow Size</string> +<string name="Eyebrow Size Bump">Eyebrow Size Bump</string> +<string name="Eyelash Length">Eyelash Length</string> +<string name="Eyeliner">Eyeliner</string> +<string name="Eyeliner Color">Eyeliner Color</string> +<string name="Eyes Back">Eyes Back</string> +<string name="Eyes Bugged">Eyes Bugged</string> +<string name="Eyes Forward">Eyes Forward</string> +<string name="Eyes Long Head">Eyes Long Head</string> +<string name="Eyes Shear Left Up">Eyes Shear Left Up</string> +<string name="Eyes Shear Right Up">Eyes Shear Right Up</string> +<string name="Eyes Short Head">Eyes Short Head</string> +<string name="Eyes Spread">Eyes Spread</string> +<string name="Eyes Sunken">Eyes Sunken</string> +<string name="Eyes Together">Eyes Together</string> +<string name="Face Shear">Face Shear</string> +<string name="Facial Definition">Facial Definition</string> +<string name="Far Set Eyes">Far Set Eyes</string> +<string name="Fat">Fat</string> +<string name="Fat Head">Fat Head</string> +<string name="Fat Lips">Fat Lips</string> +<string name="Fat Lower">Fat Lower</string> +<string name="Fat Lower Lip">Fat Lower Lip</string> +<string name="Fat Torso">Fat Torso</string> +<string name="Fat Upper">Fat Upper</string> +<string name="Fat Upper Lip">Fat Upper Lip</string> +<string name="Female">Female</string> +<string name="Fingerless">Fingerless</string> +<string name="Fingers">Fingers</string> +<string name="Flared Cuffs">Flared Cuffs</string> +<string name="Flat">Flat</string> +<string name="Flat Butt">Flat Butt</string> +<string name="Flat Head">Flat Head</string> +<string name="Flat Toe">Flat Toe</string> +<string name="Foot Size">Foot Size</string> +<string name="Forehead Angle">Forehead Angle</string> +<string name="Forehead Heavy">Forehead Heavy</string> +<string name="Freckles">Freckles</string> +<string name="Front Bangs Down">Front Bangs Down</string> +<string name="Front Bangs Up">Front Bangs Up</string> +<string name="Front Fringe">Front Fringe</string> +<string name="Front Hair">Front Hair</string> +<string name="Front Hair Down">Front Hair Down</string> +<string name="Front Hair Up">Front Hair Up</string> +<string name="Full Back">Full Back</string> +<string name="Full Eyeliner">Full Eyeliner</string> +<string name="Full Front">Full Front</string> +<string name="Full Hair Sides">Full Hair Sides</string> +<string name="Full Sides">Full Sides</string> +<string name="Glossy">Glossy</string> +<string name="Glove Fingers">Glove Fingers</string> +<string name="Glove Fingers bump">Glove Fingers bump</string> +<string name="Glove Length">Glove Length</string> +<string name="Glove Length bump">Glove Length bump</string> +<string name="HEAD">HEAD</string> +<string name="Hair">Hair</string> +<string name="Hair Back">Hair Back</string> +<string name="Hair Front">Hair Front</string> +<string name="Hair Sides">Hair Sides</string> +<string name="Hair Sweep">Hair Sweep</string> +<string name="Hair Thickess">Hair Thickess</string> +<string name="Hair Thickness">Hair Thickness</string> +<string name="Hair Tilt">Hair Tilt</string> +<string name="Hair Tilted Left">Hair Tilted Left</string> +<string name="Hair Tilted Right">Hair Tilted Right</string> +<string name="Hair Volume">Hair Volume</string> +<string name="Hand Size">Hand Size</string> +<string name="Handlebars">Handlebars</string> +<string name="Head Length">Head Length</string> +<string name="Head Shape">Head Shape</string> +<string name="Head Size">Head Size</string> +<string name="Head Stretch">Head Stretch</string> +<string name="Heel Height">Heel Height</string> +<string name="Heel Shape">Heel Shape</string> +<string name="Height">Height</string> +<string name="High">High</string> +<string name="High Heels">High Heels</string> +<string name="High Jaw">High Jaw</string> +<string name="High Platforms">High Platforms</string> +<string name="High and Tight">High and Tight</string> +<string name="Higher">Higher</string> +<string name="Hip Length">Hip Length</string> +<string name="Hip Width">Hip Width</string> +<string name="In">In</string> +<string name="In Shdw Color">In Shdw Color</string> +<string name="In Shdw Opacity">In Shdw Opacity</string> +<string name="Inner Eye Corner">Inner Eye Corner</string> +<string name="Inner Eye Shadow">Inner Eye Shadow</string> +<string name="Inner Shadow">Inner Shadow</string> +<string name="Jacket Collar Back bump">Jacket Collar Back bump</string> +<string name="Jacket Collar Front bump">Jacket Collar Front bump</string> +<string name="Jacket Length">Jacket Length</string> +<string name="Jacket Sleeve Length bump">Jacket Sleeve Length bump</string> +<string name="Jacket Wrinkles">Jacket Wrinkles</string> +<string name="Jaw Angle">Jaw Angle</string> +<string name="Jaw Jut">Jaw Jut</string> +<string name="Jaw Shape">Jaw Shape</string> +<string name="Join">Join</string> +<string name="Jowls">Jowls</string> +<string name="Knee Angle">Knee Angle</string> +<string name="Knock Kneed">Knock Kneed</string> +<string name="L Forearm">L Forearm</string> +<string name="L Lower Leg">L Lower Leg</string> +<string name="L Upper Arm">L Upper Arm</string> +<string name="L Upper Leg">L Upper Leg</string> + +<string name="Large">Large</string> +<string name="Large Hands">Large Hands</string> +<string name="Left">Left</string> +<string name="Left Ear">Left Ear</string> +<string name="Left Eyeball">Left Eyeball</string> +<string name="Left Foot">Left Foot</string> +<string name="Left Hand">Left Hand</string> +<string name="Left Hip">Left Hip</string> +<string name="Left Part">Left Part</string> +<string name="Left Pec">Left Pec</string> +<string name="Left Shoulder">Left Shoulder</string> +<string name="Leg Length">Leg Length</string> +<string name="Leg Muscles">Leg Muscles</string> +<string name="Less">Less</string> +<string name="Less Body Fat">Less Body Fat</string> +<string name="Less Curtains">Less Curtains</string> +<string name="Less Freckles">Less Freckles</string> +<string name="Less Full">Less Full</string> +<string name="Less Gravity">Less Gravity</string> +<string name="Less Love">Less Love</string> +<string name="Less Muscles">Less Muscles</string> +<string name="Less Muscular">Less Muscular</string> +<string name="Less Rosy">Less Rosy</string> +<string name="Less Round">Less Round</string> +<string name="Less Saddle">Less Saddle</string> +<string name="Less Square">Less Square</string> +<string name="Less Volume">Less Volume</string> +<string name="Less soul">Less soul</string> +<string name="Light">Light</string> +<string name="Lighter">Lighter</string> +<string name="Lip Cleft">Lip Cleft</string> +<string name="Lip Cleft Depth">Lip Cleft Depth</string> +<string name="Lip Fullness">Lip Fullness</string> +<string name="Lip Pinkness">Lip Pinkness</string> +<string name="Lip Ratio">Lip Ratio</string> +<string name="Lip Thickness">Lip Thickness</string> +<string name="Lip Width">Lip Width</string> +<string name="Lipgloss">Lipgloss</string> +<string name="Lipstick">Lipstick</string> +<string name="Lipstick Color">Lipstick Color</string> +<string name="Long">Long</string> +<string name="Long Head">Long Head</string> +<string name="Long Hips">Long Hips</string> +<string name="Long Legs">Long Legs</string> +<string name="Long Neck">Long Neck</string> +<string name="Long Pigtails">Long Pigtails</string> +<string name="Long Ponytail">Long Ponytail</string> +<string name="Long Torso">Long Torso</string> +<string name="Long arms">Long arms</string> +<string name="Longcuffs">Longcuffs</string> +<string name="Loose Lower Clothing">Loose Lower Clothing</string> +<string name="Loose Pants">Loose Pants</string> +<string name="Loose Shirt">Loose Shirt</string> +<string name="Loose Sleeves">Loose Sleeves</string> +<string name="Loose Upper Clothing">Loose Upper Clothing</string> +<string name="Love Handles">Love Handles</string> +<string name="Low">Low</string> +<string name="Low Heels">Low Heels</string> +<string name="Low Jaw">Low Jaw</string> +<string name="Low Platforms">Low Platforms</string> +<string name="Low and Loose">Low and Loose</string> +<string name="Lower">Lower</string> +<string name="Lower Bridge">Lower Bridge</string> +<string name="Lower Cheeks">Lower Cheeks</string> +<string name="Lower Clothes Shading">Lower Clothes Shading</string> +<string name="Male">Male</string> +<string name="Middle Part">Middle Part</string> +<string name="More">More</string> +<string name="More Blush">More Blush</string> +<string name="More Body Fat">More Body Fat</string> +<string name="More Curtains">More Curtains</string> +<string name="More Eyeshadow">More Eyeshadow</string> +<string name="More Freckles">More Freckles</string> +<string name="More Full">More Full</string> +<string name="More Gravity">More Gravity</string> +<string name="More Lipstick">More Lipstick</string> +<string name="More Love">More Love</string> +<string name="More Lower Lip">More Lower Lip</string> +<string name="More Muscles">More Muscles</string> +<string name="More Muscular">More Muscular</string> +<string name="More Rosy">More Rosy</string> +<string name="More Round">More Round</string> +<string name="More Saddle">More Saddle</string> +<string name="More Sloped">More Sloped</string> +<string name="More Square">More Square</string> +<string name="More Upper Lip">More Upper Lip</string> +<string name="More Vertical">More Vertical</string> +<string name="More Volume">More Volume</string> +<string name="More soul">More soul</string> +<string name="Moustache">Moustache</string> +<string name="Moustache bump">Moustache bump</string> +<string name="Mouth">Mouth</string> +<string name="Mouth Corner">Mouth Corner</string> +<string name="Mouth Position">Mouth Position</string> +<string name="Mowhawk">Mowhawk</string> +<string name="Muscular">Muscular</string> +<string name="Mutton Chops">Mutton Chops</string> +<string name="NECK">NECK</string> +<string name="Nail Polish">Nail Polish</string> +<string name="Nail Polish Color">Nail Polish Color</string> +<string name="Narrow">Narrow</string> +<string name="Narrow Back">Narrow Back</string> +<string name="Narrow Front">Narrow Front</string> +<string name="Narrow Lips">Narrow Lips</string> +<string name="Natural">Natural</string> +<string name="Neck Length">Neck Length</string> +<string name="Neck Thickness">Neck Thickness</string> +<string name="No Blush">No Blush</string> +<string name="No Eyeliner">No Eyeliner</string> +<string name="No Eyeshadow">No Eyeshadow</string> +<string name="No Heels">No Heels</string> +<string name="No Lipgloss">No Lipgloss</string> +<string name="No Lipstick">No Lipstick</string> +<string name="No Part">No Part</string> +<string name="No Polish">No Polish</string> +<string name="No Red">No Red</string> +<string name="No Spikes">No Spikes</string> +<string name="No White">No White</string> +<string name="No Wrinkles">No Wrinkles</string> +<string name="None">None</string> +<string name="Normal Lower">Normal Lower</string> +<string name="Normal Upper">Normal Upper</string> +<string name="Nose">Nose</string> +<string name="Nose Left">Nose Left</string> +<string name="Nose Right">Nose Right</string> +<string name="Nose Size">Nose Size</string> +<string name="Nose Thickness">Nose Thickness</string> +<string name="Nose Tip Angle">Nose Tip Angle</string> +<string name="Nose Tip Shape">Nose Tip Shape</string> +<string name="Nose Width">Nose Width</string> +<string name="Nostril Division">Nostril Division</string> +<string name="Nostril Width">Nostril Width</string> +<string name="NotHair">NotHair</string> +<string name="Old">Old</string> +<string name="Opaque">Opaque</string> +<string name="Open">Open</string> +<string name="Open Back">Open Back</string> +<string name="Open Front">Open Front</string> +<string name="Open Left">Open Left</string> +<string name="Open Right">Open Right</string> +<string name="Orange">Orange</string> +<string name="Out">Out</string> +<string name="Out Shdw Color">Out Shdw Color</string> +<string name="Out Shdw Opacity">Out Shdw Opacity</string> +<string name="Outer Eye Corner">Outer Eye Corner</string> +<string name="Outer Eye Shadow">Outer Eye Shadow</string> +<string name="Outer Shadow">Outer Shadow</string> +<string name="Overbite">Overbite</string> +<string name="PELVIS">PELVIS</string> +<string name="Package">Package</string> +<string name="Painted Nails">Painted Nails</string> +<string name="Pale">Pale</string> +<string name="Pants Crotch">Pants Crotch</string> +<string name="Pants Fit">Pants Fit</string> +<string name="Pants Length">Pants Length</string> +<string name="Pants Length Cloth">Pants Length Cloth</string> +<string name="Pants Length Shadow">Pants Length Shadow</string> +<string name="Pants Waist">Pants Waist</string> +<string name="Pants Wrinkles">Pants Wrinkles</string> +<string name="Part">Part</string> +<string name="Part Bangs">Part Bangs</string> +<string name="Pectorals">Pectorals</string> +<string name="Pelvis">Pelvis</string> +<string name="Pigment">Pigment</string> +<string name="Pigtails">Pigtails</string> +<string name="Pink">Pink</string> +<string name="Pinker">Pinker</string> +<string name="Platform Height">Platform Height</string> +<string name="Platform Width">Platform Width</string> +<string name="Pointy">Pointy</string> +<string name="Pointy Heels">Pointy Heels</string> +<string name="Pointy Toe">Pointy Toe</string> +<string name="Ponytail">Ponytail</string> +<string name="Poofy Skirt">Poofy Skirt</string> +<string name="Pop Left Eye">Pop Left Eye</string> +<string name="Pop Right Eye">Pop Right Eye</string> +<string name="Puffy">Puffy</string> +<string name="Puffy Eyelids">Puffy Eyelids</string> +<string name="R Forearm">R Forearm</string> +<string name="R Lower Leg">R Lower Leg</string> +<string name="R Upper Arm">R Upper Arm</string> +<string name="R Upper Leg">R Upper Leg</string> +<string name="Rainbow Color">Rainbow Color</string> +<string name="Red Hair">Red Hair</string> +<string name="Red Skin">Red Skin</string> +<string name="Regular">Regular</string> +<string name="Regular Muscles">Regular Muscles</string> +<string name="Right">Right</string> +<string name="Right Ear">Right Ear</string> +<string name="Right Eyeball">Right Eyeball</string> +<string name="Right Foot">Right Foot</string> +<string name="Right Hand">Right Hand</string> +<string name="Right Hip">Right Hip</string> +<string name="Right Part">Right Part</string> +<string name="Right Pec">Right Pec</string> +<string name="Right Shoulder">Right Shoulder</string> +<string name="Rosy Complexion">Rosy Complexion</string> +<string name="Round">Round</string> +<string name="Round Forehead">Round Forehead</string> +<string name="Ruddiness">Ruddiness</string> +<string name="Ruddy">Ruddy</string> +<string name="Rumpled Hair">Rumpled Hair</string> +<string name="Saddle Bags">Saddle Bags</string> +<string name="Saddlebags">Saddlebags</string> +<string name="Scrawny">Scrawny</string> +<string name="Scrawny Leg">Scrawny Leg</string> +<string name="Separate">Separate</string> +<string name="Shading">Shading</string> +<string name="Shadow hair">Shadow hair</string> +<string name="Shallow">Shallow</string> +<string name="Shear Back">Shear Back</string> +<string name="Shear Face">Shear Face</string> +<string name="Shear Front">Shear Front</string> +<string name="Shear Left">Shear Left</string> +<string name="Shear Left Up">Shear Left Up</string> +<string name="Shear Right">Shear Right</string> +<string name="Shear Right Up">Shear Right Up</string> +<string name="Sheared Back">Sheared Back</string> +<string name="Sheared Front">Sheared Front</string> +<string name="Shift Left">Shift Left</string> +<string name="Shift Mouth">Shift Mouth</string> +<string name="Shift Right">Shift Right</string> +<string name="Shirt Bottom">Shirt Bottom</string> +<string name="Shirt Bottom Cloth">Shirt Bottom Cloth</string> +<string name="Shirt Fit">Shirt Fit</string> +<string name="Shirt Shadow Bottom">Shirt Shadow Bottom</string> +<string name="Shirt Wrinkles">Shirt Wrinkles</string> +<string name="Shoe Height">Shoe Height</string> +<string name="Shoe Height bump">Shoe Height bump</string> +<string name="Short">Short</string> +<string name="Short Arms">Short Arms</string> +<string name="Short Legs">Short Legs</string> +<string name="Short Neck">Short Neck</string> +<string name="Short Pigtails">Short Pigtails</string> +<string name="Short Ponytail">Short Ponytail</string> +<string name="Short Sideburns">Short Sideburns</string> +<string name="Short Torso">Short Torso</string> +<string name="Short hips">Short hips</string> +<string name="Shoulders">Shoulders</string> +<string name="Side Bangs">Side Bangs</string> +<string name="Side Bangs Down">Side Bangs Down</string> +<string name="Side Bangs Up">Side Bangs Up</string> +<string name="Side Fringe">Side Fringe</string> +<string name="Sideburns">Sideburns</string> +<string name="Sideburns bump">Sideburns bump</string> +<string name="Sides Hair">Sides Hair</string> +<string name="Sides Hair Down">Sides Hair Down</string> +<string name="Sides Hair Up">Sides Hair Up</string> +<string name="Skinny">Skinny</string> +<string name="Skinny Neck">Skinny Neck</string> +<string name="Skirt Fit">Skirt Fit</string> +<string name="Skirt Length">Skirt Length</string> +<string name="Skull">Skull</string> +<string name="Slanted Forehead">Slanted Forehead</string> +<string name="Sleeve Length">Sleeve Length</string> +<string name="Sleeve Length Cloth">Sleeve Length Cloth</string> +<string name="Sleeve Length Shadow">Sleeve Length Shadow</string> +<string name="Sleeve Length bump">Sleeve Length bump</string> +<string name="Sleeve Looseness">Sleeve Looseness</string> +<string name="Slit Back">Slit Back</string> +<string name="Slit Front">Slit Front</string> +<string name="Slit Left">Slit Left</string> +<string name="Slit Right">Slit Right</string> +<string name="Small">Small</string> +<string name="Small Hands">Small Hands</string> +<string name="Small Head">Small Head</string> +<string name="Smooth">Smooth</string> +<string name="Smooth Hair">Smooth Hair</string> +<string name="Socks Length">Socks Length</string> +<string name="Socks Length bump">Socks Length bump</string> +<string name="Some">Some</string> +<string name="Soulpatch">Soulpatch</string> +<string name="Soulpatch bump">Soulpatch bump</string> +<string name="Sparse">Sparse</string> +<string name="Spiked Hair">Spiked Hair</string> +<string name="Spine">Spine</string> +<string name="Square">Square</string> +<string name="Square Toe">Square Toe</string> +<string name="Squash Head">Squash Head</string> +<string name="Squash/Stretch Head">Squash/Stretch Head</string> +<string name="Stomach">Stomach</string> +<string name="Stretch Head">Stretch Head</string> +<string name="Sunken">Sunken</string> +<string name="Sunken Chest">Sunken Chest</string> +<string name="Sunken Eyes">Sunken Eyes</string> +<string name="Sweep Back">Sweep Back</string> +<string name="Sweep Forward">Sweep Forward</string> +<string name="Swept Back">Swept Back</string> +<string name="Swept Back Hair">Swept Back Hair</string> +<string name="Swept Forward">Swept Forward</string> +<string name="Swept Forward Hair">Swept Forward Hair</string> +<string name="Tall">Tall</string> +<string name="Taper Back">Taper Back</string> +<string name="Taper Front">Taper Front</string> +<string name="Thick Heels">Thick Heels</string> +<string name="Thick Neck">Thick Neck</string> +<string name="Thick Toe">Thick Toe</string> +<string name="Thickness">Thickness</string> +<string name="Thin">Thin</string> +<string name="Thin Eyebrows">Thin Eyebrows</string> +<string name="Thin Lips">Thin Lips</string> +<string name="Thin Nose">Thin Nose</string> +<string name="Tight Chin">Tight Chin</string> +<string name="Tight Cuffs">Tight Cuffs</string> +<string name="Tight Pants">Tight Pants</string> +<string name="Tight Shirt">Tight Shirt</string> +<string name="Tight Skirt">Tight Skirt</string> +<string name="Tight Sleeves">Tight Sleeves</string> +<string name="Tilt Left">Tilt Left</string> +<string name="Tilt Right">Tilt Right</string> +<string name="Toe Shape">Toe Shape</string> +<string name="Toe Thickness">Toe Thickness</string> +<string name="Top">Top</string> +<string name="Top Left">Top Left</string> +<string name="Top Right">Top Right</string> +<string name="Torso Length">Torso Length</string> +<string name="Torso Muscles">Torso Muscles</string> +<string name="Torso Scrawny">Torso Scrawny</string> +<string name="Unattached">Unattached</string> +<string name="Uncreased">Uncreased</string> +<string name="Underbite">Underbite</string> +<string name="Unnatural">Unnatural</string> +<string name="Upper Bridge">Upper Bridge</string> +<string name="Upper Cheeks">Upper Cheeks</string> +<string name="Upper Chin Cleft">Upper Chin Cleft</string> +<string name="Upper Clothes Shading">Upper Clothes Shading</string> +<string name="Upper Eyelid Fold">Upper Eyelid Fold</string> +<string name="Upturned">Upturned</string> +<string name="Very Red">Very Red</string> +<string name="Waist Height">Waist Height</string> +<string name="Waist Height Cloth">Waist Height Cloth</string> +<string name="Waist Height Shadow">Waist Height Shadow</string> +<string name="Well-Fed">Well-Fed</string> +<string name="White Hair">White Hair</string> +<string name="Wide">Wide</string> +<string name="Wide Back">Wide Back</string> +<string name="Wide Front">Wide Front</string> +<string name="Wide Lips">Wide Lips</string> +<string name="Wild">Wild</string> +<string name="Wrinkles">Wrinkles</string>      <!-- Favorites Bar -->      <string name="location_ctrl_add_landmark">Add to My Landmarks</string> diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml index d7369d0726..0dbca318b6 100644 --- a/indra/newview/skins/default/xui/en/widgets/combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml @@ -20,7 +20,9 @@                                image_unselected="DropDown_Off"                                image_selected="DropDown_Selected"                                image_disabled="DropDown_Disabled" /> -  <combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" /> +  <combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" +                        background_visible="true" +                         />    <combo_box.combo_editor name="Combo Text Entry"                            select_on_focus="true"                            font="SansSerifSmall" /> diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml index e470f42d36..6381dce1d6 100644 --- a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml +++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml @@ -2,6 +2,7 @@  <expandable_text   max_height="300" >   <textbox +   more_label="More"     follows="left|top"    name="text"    use_ellipses="true" diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml index 824a815a99..4520768216 100644 --- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml +++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml @@ -12,7 +12,7 @@               draw_stripes="true"               scroll_bar_bg_visible="false"               scroll_bar_bg_color="black" -             background_visible="false" +             background_visible="true"               heading_height="23"               draw_border="false"               draw_heading="false" /> diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml index f0127a9d5a..5914c21b2b 100644 --- a/indra/newview/skins/default/xui/en/widgets/text.xml +++ b/indra/newview/skins/default/xui/en/widgets/text.xml @@ -18,4 +18,5 @@        border_visible="false"         hover="false"         text_color="LabelTextColor" -      v_pad="-1"/> +      v_pad="-1" +      max_length="4096"/> diff --git a/indra/newview/skins/default/xui/es/floater_camera.xml b/indra/newview/skins/default/xui/es/floater_camera.xml index 0246f0d440..3aeb4e5771 100644 --- a/indra/newview/skins/default/xui/es/floater_camera.xml +++ b/indra/newview/skins/default/xui/es/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="move floater" title=""> -	<string name="rotate_tooltip"> +<floater name="camera_floater" title=""> +	<floater.string name="rotate_tooltip">  		Girar la cámara alrededor de lo enfocado -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Hacer zoom con la cámara en lo enfocado -	</string> -	<string name="move_tooltip"> -		Mover la cámara arriba y abajo, izquierda y derecha. -	</string> +	</floater.string> +	<floater.string name="move_tooltip"> +		Mover la cámara arriba y abajo, izquierda y derecha +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Mover la cámara arriba y abajo, izquierda y derecha"/> +		<joystick_zoom name="zoom" tool_tip="Hacer zoom con la cámara en lo enfocado"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/es/floater_color_picker.xml b/indra/newview/skins/default/xui/es/floater_color_picker.xml index c220c48cb0..616c373d18 100644 --- a/indra/newview/skins/default/xui/es/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/es/floater_color_picker.xml @@ -26,6 +26,6 @@  	</text>  	<text name="(Drag below to save.)">  		(Arrástrelo abajo - para guardarlo.) + para guardarlo)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_camera.xml b/indra/newview/skins/default/xui/fr/floater_camera.xml index 9f280b7265..8ea640853f 100644 --- a/indra/newview/skins/default/xui/fr/floater_camera.xml +++ b/indra/newview/skins/default/xui/fr/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="move floater"> -	<string name="rotate_tooltip"> +<floater name="camera_floater"> +	<floater.string name="rotate_tooltip">  		Faire tourner la caméra autour du point central -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Zoomer en direction du point central -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		Déplacer la caméra vers le haut et le bas, la gauche et la droite -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Déplacer la caméra vers le haut et le bas, la gauche et la droite"/> +		<joystick_zoom name="zoom" tool_tip="Zoomer en direction du point central"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_color_picker.xml b/indra/newview/skins/default/xui/fr/floater_color_picker.xml index adab86dac0..94bcad070e 100644 --- a/indra/newview/skins/default/xui/fr/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/fr/floater_color_picker.xml @@ -27,6 +27,6 @@  	</text>  	<text left="8" name="(Drag below to save.)" width="114">  		(Faire glisser dessous -pour enregistrer.) +pour enregistrer)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/it/floater_camera.xml b/indra/newview/skins/default/xui/it/floater_camera.xml index 9655ed2211..823be8f4a1 100644 --- a/indra/newview/skins/default/xui/it/floater_camera.xml +++ b/indra/newview/skins/default/xui/it/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="move floater" title=""> -	<string name="rotate_tooltip"> +<floater name="camera_floater" title=""> +	<floater.string name="rotate_tooltip">  		Ruota la telecamera Intorno all'Inquadratura -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Avvicina la telecamera nell'inquadratura -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		Muovi la telecamera su e giù e a sinistra e destra -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Muovi la telecamera su e giù e a sinistra e destra"/> +		<joystick_zoom name="zoom" tool_tip="Avvicina la telecamera nell'inquadratura"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/it/floater_color_picker.xml b/indra/newview/skins/default/xui/it/floater_color_picker.xml index 93188c29ac..1e6d7bc3f0 100644 --- a/indra/newview/skins/default/xui/it/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/it/floater_color_picker.xml @@ -33,6 +33,6 @@  	</text>  	<text name="(Drag below to save.)">  		(Trascina qui sotto - per salvare.) + per salvare)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_camera.xml b/indra/newview/skins/default/xui/ja/floater_camera.xml index 46e7b1990d..bb87b194a4 100644 --- a/indra/newview/skins/default/xui/ja/floater_camera.xml +++ b/indra/newview/skins/default/xui/ja/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="move floater"> -	<string name="rotate_tooltip"> +<floater name="camera_floater"> +	<floater.string name="rotate_tooltip">  		フォーカスを中心にカメラを回転 -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		フォーカスに向けてカメラをズーム -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		カメラを上下左右に移動 -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="カメラを上下左右に移動"/> +		<joystick_zoom name="zoom" tool_tip="フォーカスに向けてカメラをズーム"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/nl/floater_camera.xml b/indra/newview/skins/default/xui/nl/floater_camera.xml index a6b843a0a2..81a3ed8a58 100644 --- a/indra/newview/skins/default/xui/nl/floater_camera.xml +++ b/indra/newview/skins/default/xui/nl/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="move floater" title=""> -	<string name="rotate_tooltip"> +<floater name="camera_floater" title=""> +	<floater.string name="rotate_tooltip">  		Roteer camera rond focus -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Zoom camera naar focus -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		Beweeg camera omhoog en omlaag, links en rechts -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Beweeg camera omhoog en omlaag, links en rechts"/> +		<joystick_zoom name="zoom" tool_tip="Zoom camera naar focus"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/nl/floater_color_picker.xml b/indra/newview/skins/default/xui/nl/floater_color_picker.xml index 25294e17e2..a357e874f7 100644 --- a/indra/newview/skins/default/xui/nl/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/nl/floater_color_picker.xml @@ -26,6 +26,6 @@  	</text>  	<text name="(Drag below to save.)">  		(Sleep naar beneden  - om op te slaan.) + om op te slaan)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/pl/floater_camera.xml b/indra/newview/skins/default/xui/pl/floater_camera.xml index 24da91c081..5957018144 100755 --- a/indra/newview/skins/default/xui/pl/floater_camera.xml +++ b/indra/newview/skins/default/xui/pl/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="move floater" title=""> -	<string name="rotate_tooltip"> +<floater name="camera_floater" title=""> +	<floater.string name="rotate_tooltip">  		Obracaj kamerę wokół obiektu -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Najedź kamerą w kierunku obiektu -	</string> -	<string name="move_tooltip"> +	</floater.string> +	<floater.string name="move_tooltip">  		Poruszaj kamerą w dół/górę oraz w prawo/lewo -	</string> +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Poruszaj kamerą w dół/górę oraz w prawo/lewo"/> +		<joystick_zoom name="zoom" tool_tip="Najedź kamerą w kierunku obiektu"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/pl/floater_color_picker.xml b/indra/newview/skins/default/xui/pl/floater_color_picker.xml index a380423cdf..d6ffe1837a 100755 --- a/indra/newview/skins/default/xui/pl/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/pl/floater_color_picker.xml @@ -26,6 +26,6 @@  		Obecny Kolor:  	</text>  	<text name="(Drag below to save.)"> -		(Przeciągnij tutaj.) +		(Przeciągnij tutaj)  	</text>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_camera.xml b/indra/newview/skins/default/xui/pt/floater_camera.xml index 4dc6997606..b61e261148 100644 --- a/indra/newview/skins/default/xui/pt/floater_camera.xml +++ b/indra/newview/skins/default/xui/pt/floater_camera.xml @@ -1,12 +1,16 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="move floater" title=""> -	<string name="rotate_tooltip"> +<floater name="camera_floater" title=""> +	<floater.string name="rotate_tooltip">  		Girar a Câmera ao redor do Foco -	</string> -	<string name="zoom_tooltip"> +	</floater.string> +	<floater.string name="zoom_tooltip">  		Aproximar a Câmera in direção ao Foco -	</string> -	<string name="move_tooltip"> -		Mover a Câmera Para Cima e Para Baixo, Para a Esquerda e Para a Direita -	</string> +	</floater.string> +	<floater.string name="move_tooltip"> +		Mover a Câmera para Cima e para Baixo, para a Esquerda e para a Direita +	</floater.string> +	<panel name="controls"> +		<joystick_track name="cam_track_stick" tool_tip="Mover a Câmera para Cima e para Baixo, para a Esquerda e para a Direita"/> +		<joystick_zoom name="zoom" tool_tip="Aproximar a Câmera in direção ao Foco"/> +	</panel>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_color_picker.xml b/indra/newview/skins/default/xui/pt/floater_color_picker.xml index 95dd53ccd4..76da972b5d 100644 --- a/indra/newview/skins/default/xui/pt/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/pt/floater_color_picker.xml @@ -27,6 +27,6 @@  	</text>  	<text name="(Drag below to save.)">  		(Arraste abaixo - para salvar.) + para salvar)  	</text>  </floater> diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp new file mode 100644 index 0000000000..135c5ab501 --- /dev/null +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -0,0 +1,481 @@ +/**  + * @file llmediadataclient_test.cpp + * @brief LLMediaDatClient tests + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2009, 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 <iostream> +#include "../test/lltut.h" + +#include "llsdserialize.h" +#include "llerrorcontrol.h" +#include "llhttpstatuscodes.h" + +#include "../llmediadataclient.h" +#include "../llvovolume.h" + +#include "../../llprimitive/llmediaentry.cpp" +#include "../../llprimitive/lltextureentry.cpp" +#include "../../llmessage/tests/llcurl_stub.cpp" + +#include <boost/lexical_cast.hpp> + +#define VALID_OBJECT_ID   "3607d5c4-644b-4a8a-871a-8b78471af2a2" +#define VALID_OBJECT_ID_1 "11111111-1111-1111-1111-111111111111" +#define VALID_OBJECT_ID_2 "22222222-2222-2222-2222-222222222222" +#define VALID_OBJECT_ID_3 "33333333-3333-3333-3333-333333333333" +#define VALID_OBJECT_ID_4 "44444444-4444-4444-4444-444444444444" + +#define FAKE_OBJECT_MEDIA_CAP_URL "foo_ObjectMedia" +#define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL "foo_ObjectMediaNavigate" +#define FAKE_OBJECT_MEDIA_CAP_URL_503 "foo_ObjectMedia_503" +#define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR "foo_ObjectMediaNavigate_ERROR" + +#define MEDIA_DATA "\ +<array>														\ +<string>foo</string>										\ +<string>bar</string>										\ +<string>baz</string>										\ +</array>" + +#define _DATA_URLS(ID,DIST,INT,URL1,URL2) "					\ +<llsd>											\ +  <map>											\ +    <key>uuid</key>								\ +    <string>" ID "</string>						\ +    <key>distance</key>											\ +    <real>" DIST "</real>										\ +    <key>interest</key>											\ +    <real>" INT "</real>											\ +    <key>cap_urls</key>											\ +    <map>														\ +      <key>ObjectMedia</key>									\ +      <string>" URL1 "</string>			\ +      <key>ObjectMediaNavigate</key>							\ +      <string>" URL2 "</string>	\ +    </map>														\ +    <key>media_data</key>                                       \ +	" MEDIA_DATA "												\ +  </map>														\ +</llsd>" + +#define _DATA(ID,DIST,INT) _DATA_URLS(ID,DIST,INT,FAKE_OBJECT_MEDIA_CAP_URL,FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL) + +const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","1.0"); +	 +#define STR(I) boost::lexical_cast<std::string>(I) + +#define LOG_TEST(N) LL_DEBUGS("LLMediaDataClient") << "\n" <<			\ +"================================================================================\n" << \ +"===================================== TEST " #N " ===================================\n" << \ +"================================================================================\n" << LL_ENDL; + +LLSD *gPostRecords = NULL; + +// stubs: +void LLHTTPClient::post( +		const std::string& url, +		const LLSD& body, +		LLHTTPClient::ResponderPtr responder, +		const LLSD& headers, +		const F32 timeout) +{ +	LLSD record; +	record["url"] = url; +	record["body"] = body; +	record["headers"] = headers; +	record["timeout"] = timeout; +	gPostRecords->append(record); +	 +	// Magic URL that triggers a 503: +	if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 ) +	{ +		responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason"); +	} +	else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)  +	{ +		LLSD result; +		LLSD error; +		error["code"] = LLObjectMediaNavigateClient::ERROR_PERMISSION_DENIED_CODE; +		result["error"] = error; +		responder->result(result); +	} +	else { +		responder->result(LLSD()); +	} +} + +const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; + +class LLMediaDataClientObjectTest : public LLMediaDataClientObject +{ +public: +	LLMediaDataClientObjectTest(const char *data)  +		{ +			std::istringstream d(data); +			LLSDSerialize::fromXML(mRep, d); +			mNumBounceBacks = 0; +             +           // std::cout << ll_pretty_print_sd(mRep) << std::endl; +           // std::cout << "ID: " << getID() << std::endl; +		} +	LLMediaDataClientObjectTest(const LLSD &rep)  +		: mRep(rep), mNumBounceBacks(0) {} +	~LLMediaDataClientObjectTest() +		{ LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClientObjectTest" << LL_ENDL; } +	 +	virtual U8 getMediaDataCount() const  +		{ return mRep["media_data"].size(); } +	virtual LLSD getMediaDataLLSD(U8 index) const +		{ return mRep["media_data"][(LLSD::Integer)index]; } +	virtual LLUUID getID() const  +		{ return mRep["uuid"]; } +	virtual void mediaNavigateBounceBack(U8 index) +		{ +			mNumBounceBacks++; +		} +	 +	virtual bool hasMedia() const +		{ return mRep.has("media_data"); } +	 +	virtual void updateObjectMediaData(LLSD const &media_data_array) +		{ mRep["media_data"] = media_data_array; } +	 +	virtual F64 getDistanceFromAvatar() const +		{ return (LLSD::Real)mRep["distance"]; } +	 +	virtual F64 getTotalMediaInterest() const +		{ return (LLSD::Real)mRep["interest"]; } + +	virtual std::string getCapabilityUrl(const std::string &name) const  +		{ return mRep["cap_urls"][name]; } + +	int getNumBounceBacks() const +		{ return mNumBounceBacks; } +	 +private: +	LLSD mRep; +	int mNumBounceBacks; +}; + + +namespace tut +{ +    struct mediadataclient +    { +		mediadataclient() { +			gPostRecords = &mLLSD; +			 +// 			LLError::setDefaultLevel(LLError::LEVEL_DEBUG); +// 			LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG); +//			LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG); +		} +		LLSD mLLSD; +    }; +     +	typedef test_group<mediadataclient> mediadataclient_t; +	typedef mediadataclient_t::object mediadataclient_object_t; +	tut::mediadataclient_t tut_mediadataclient("mediadataclient"); +     +    void ensure(const std::string &msg, int value, int expected) +    { +        std::string m = msg; +        m += " value: " + STR(value); +        m += ", expected: " + STR(expected); +        ensure(m, value == expected); +    } +     +    void ensure(const std::string &msg, const std::string & value, const std::string & expected) +    { +        std::string m = msg; +        m += " value: " + value; +        m += ", expected: " + expected; +        ensure(m, value == expected); +    } +     +    void ensure(const std::string &msg, const LLUUID & value, const LLUUID & expected) +    { +        std::string m = msg; +        m += " value: " + value.asString(); +        m += ", expected: " + expected.asString(); +        ensure(m, value == expected); +    } +     +    void ensure_llsd(const std::string &msg, const LLSD & value, const char *expected) +    { +        LLSD expected_llsd; +        std::istringstream e(expected); +        LLSDSerialize::fromXML(expected_llsd, e); +    +        std::string value_str = ll_pretty_print_sd(value); +        std::string expected_str = ll_pretty_print_sd(expected_llsd); +        std::string m = msg; +        m += " value: " + value_str; +        m += ", expected: " + expected_str; +        ensure(m, value_str == expected_str); +    } + +	////////////////////////////////////////////////////////////////////////////////////////// +	 +	template<> template<> +	void mediadataclient_object_t::test<1>() +	{ +		// +		// Test fetchMedia() +		// +		LOG_TEST(1); +		 +		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); +		int num_refs_start = o->getNumRefs(); +		{ +			// queue time w/ no delay ensures that LLEventTimer::updateClass() will hit the tick() +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,4);   +			mdc->fetchMedia(o); + +			// Make sure no posts happened yet... +			ensure("post records", gPostRecords->size(), 0); + +			LLEventTimer::updateClass(); +		 +			ensure("post records", gPostRecords->size(), 1); +			ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL); +			ensure("post GET", (*gPostRecords)[0]["body"]["verb"], "GET"); +			ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); +			ensure("queue empty", mdc->isEmpty()); +		} +		 +		// Make sure everyone's destroyed properly +		ensure("REF COUNT", o->getNumRefs(), num_refs_start); +    } + +	////////////////////////////////////////////////////////////////////////////////////////// + +	template<> template<> +	void mediadataclient_object_t::test<2>() +	{ +		// +		// Test updateMedia() +		// +		LOG_TEST(2); + +		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); +		{ +			// queue time w/ no delay ensures that LLEventTimer::updateClass() will hit the tick() +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,4);   +			mdc->updateMedia(o); +			ensure("post records", gPostRecords->size(), 0); +			LLEventTimer::updateClass(); +		 +			ensure("post records", gPostRecords->size(), 1); +			ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL); +			ensure("post UPDATE", (*gPostRecords)[0]["body"]["verb"], "UPDATE"); +			ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); +			ensure_llsd("post data llsd", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_MEDIA_DATA_KEY],  +						"<llsd>" MEDIA_DATA "</llsd>"); +			ensure("queue empty", mdc->isEmpty()); +		} + +		ensure("REF COUNT", o->getNumRefs(), 1); +	} + +	////////////////////////////////////////////////////////////////////////////////////////// + +    template<> template<> +    void mediadataclient_object_t::test<3>() +    { +		// +		// Test navigate() +		// +		LOG_TEST(3); + +		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); +		{		 +			LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(0,0,4); +			const char *TEST_URL = "http://example.com"; +			mdc->navigate(o, 0, TEST_URL); +			ensure("post records", gPostRecords->size(), 0); +			LLEventTimer::updateClass(); + +			// ensure no bounce back +			ensure("bounce back", dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), 0); +		 +			ensure("post records", gPostRecords->size(), 1); +			ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL); +			ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); +			ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0); +			ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL); +			ensure("queue empty", mdc->isEmpty()); +		} +		ensure("REF COUNT", o->getNumRefs(), 1); +    } +	 +	////////////////////////////////////////////////////////////////////////////////////////// + +    template<> template<> +    void mediadataclient_object_t::test<4>() +    { +		// +		// Test queue ordering +		// +		LOG_TEST(4); + +		LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest( +			_DATA(VALID_OBJECT_ID_1,"3.0","1.0")); +		LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest( +			_DATA(VALID_OBJECT_ID_2,"1.0","1.0")); +		LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest( +			_DATA(VALID_OBJECT_ID_3,"2.0","1.0")); +		{ +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,4);   +			const char *ORDERED_OBJECT_IDS[] = { VALID_OBJECT_ID_2, VALID_OBJECT_ID_3, VALID_OBJECT_ID_1 }; +			mdc->fetchMedia(o1); +			mdc->fetchMedia(o2); +			mdc->fetchMedia(o3); + +			// Make sure no posts happened yet... +			ensure("post records", gPostRecords->size(), 0); + +			// tick 3 times... +			LLEventTimer::updateClass(); +			ensure("post records", gPostRecords->size(), 1); +			LLEventTimer::updateClass(); +			ensure("post records", gPostRecords->size(), 2); +			LLEventTimer::updateClass(); +			ensure("post records", gPostRecords->size(), 3); +		 +			for( int i=0; i < 3; i++ ) +			{ +				ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL); +				ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET"); +				ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(),  +					   LLUUID(ORDERED_OBJECT_IDS[i])); +			} + +			ensure("queue empty", mdc->isEmpty()); +		} +		ensure("refcount of o1", o1->getNumRefs(), 1); +		ensure("refcount of o2", o2->getNumRefs(), 1); +		ensure("refcount of o3", o3->getNumRefs(), 1); +    } + +	////////////////////////////////////////////////////////////////////////////////////////// + +	template<> template<> +	void mediadataclient_object_t::test<5>() +	{ +		// +		// Test fetchMedia() getting a 503 error +		// +		LOG_TEST(5); +		 +		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest( +			_DATA_URLS(VALID_OBJECT_ID, +					   "1.0", +					   "1.0", +					   FAKE_OBJECT_MEDIA_CAP_URL_503, +					   FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL)); +		int num_refs_start = o->getNumRefs(); +		{ +			const int NUM_RETRIES = 5; +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,NUM_RETRIES); + +			// This should generate a retry +			mdc->fetchMedia(o); + +			// Make sure no posts happened yet... +			ensure("post records before", gPostRecords->size(), 0); + +			// Once, causes retry +			// Second, fires retry timer +			// Third, fires queue timer again +			for (int i=0; i<NUM_RETRIES; ++i) +			{ +				LLEventTimer::updateClass(); +				ensure("post records " + STR(i), gPostRecords->size(), i+1); +				LLEventTimer::updateClass(); +			} + +			// Do some extre pumps to make sure no other timer work occurs. +			LLEventTimer::updateClass(); +			LLEventTimer::updateClass(); +			LLEventTimer::updateClass(); +			 +			// Make sure there were 2 posts +			ensure("post records after", gPostRecords->size(), NUM_RETRIES); +			for (int i=0; i<NUM_RETRIES; ++i) +			{ +				ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL_503); +				ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET"); +				ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); +			} +			ensure("queue empty", mdc->isEmpty()); +		} +		 +		// Make sure everyone's destroyed properly +		ensure("REF COUNT", o->getNumRefs(), num_refs_start); +    } + +    template<> template<> +    void mediadataclient_object_t::test<6>() +    { +		// +		// Test navigate() with a bounce back +		// +		LOG_TEST(6); + +		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest( +			_DATA_URLS(VALID_OBJECT_ID, +					   "1.0", +					   "1.0", +					   FAKE_OBJECT_MEDIA_CAP_URL, +					   FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)); +		{		 +			LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(0,0,4); +			const char *TEST_URL = "http://example.com"; +			mdc->navigate(o, 0, TEST_URL); +			ensure("post records", gPostRecords->size(), 0); +			LLEventTimer::updateClass(); + +			// ensure bounce back +			ensure("bounce back",  +				   dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), +				   1); +			 +			ensure("post records", gPostRecords->size(), 1); +			ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR); +			ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); +			ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0); +			ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL); +			ensure("queue empty", mdc->isEmpty()); +		} +		ensure("REF COUNT", o->getNumRefs(), 1); +    } + +	 +} diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index d3b0a2e47e..a670db699e 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -269,8 +269,8 @@ class WindowsManifest(ViewerManifest):          # For google-perftools tcmalloc allocator.          if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): -                self.path("libtcmalloc_minimal.dll") -                self.end_prefix() +            self.path("libtcmalloc_minimal.dll") +            self.end_prefix()      def nsi_file_commands(self, install=True): @@ -393,6 +393,8 @@ class WindowsManifest(ViewerManifest):          # We use the Unicode version of NSIS, available from          # http://www.scratchpaper.com/          NSIS_path = 'C:\\Program Files\\NSIS\\Unicode\\makensis.exe' +        if not os.path.exists(NSIS_path): +            NSIS_path = os.path.expandvars('${ProgramFiles(x86)}\\NSIS\\Unicode\\makensis.exe')          self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile))          # self.remove(self.dst_path_of(tempfile))          # If we're on a build machine, sign the code using our Authenticode certificate. JC @@ -538,7 +540,7 @@ class DarwinManifest(ViewerManifest):          # make sure we don't have stale files laying about          self.remove(sparsename, finalname) -        self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % { +        self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 500 -layout SPUD' % {                  'sparse':sparsename,                  'vol':volname}) diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 463eedb4fd..98ad8af02d 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -14,6 +14,7 @@ include(LScript)  include(Linking)  include(Tut)  include(Boost) +include(GoogleMock)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} @@ -24,6 +25,7 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ${LSCRIPT_INCLUDE_DIRS} +    ${GOOGLEMOCK_INCLUDE_DIRS}      )  set(test_SOURCE_FILES @@ -126,6 +128,7 @@ target_link_libraries(test      ${LLXML_LIBRARIES}      ${LSCRIPT_LIBRARIES}      ${LLCOMMON_LIBRARIES} +    ${GOOGLEMOCK_LIBRARIES}      ${APRICONV_LIBRARIES}      ${PTHREAD_LIBRARY}      ${WINDOWS_LIBRARIES} @@ -145,12 +148,18 @@ endif (WINDOWS)  get_target_property(TEST_EXE test LOCATION) +SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) + +SET(TEST_LD_CMD  +  ${CMAKE_COMMAND}  +  -DLD_LIBRARY_PATH=${ARCH_PREBUILT_DIRS}:/usr/lib +  -DTEST_CMD:STRING="${TEST_CMD}"  +  -P ${CMAKE_SOURCE_DIR}/cmake/RunBuildTest.cmake +  ) +  add_custom_command(    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt -  COMMAND ${TEST_EXE} -  ARGS -    --output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt -    --touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt +  COMMAND ${TEST_LD_CMD}    DEPENDS test    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}    COMMENT "C++ unit tests" diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 2f50d872ee..721e9da917 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -54,6 +54,11 @@  #	include "ctype_workaround.h"  #endif +#ifndef LL_WINDOWS +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#endif +  namespace tut  {  	std::string sSourceDir; @@ -235,6 +240,11 @@ void wouldHaveCrashed(const std::string& message)  int main(int argc, char **argv)  { +	// The following line must be executed to initialize Google Mock +	// (and Google Test) before running the tests. +#ifndef LL_WINDOWS +	::testing::InitGoogleMock(&argc, argv); +#endif  	LLError::initForApplication(".");  	LLError::setFatalFunction(wouldHaveCrashed);  	LLError::setDefaultLevel(LLError::LEVEL_ERROR); diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index 7869763302..f9568a9b5d 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -2033,6 +2033,10 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e  		case MEDIA_EVENT_PLUGIN_FAILED:  			std::cerr <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED" << std::endl;  		break; + +		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: +			std::cerr <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl; +		break;  	}  }  | 
