Commits

Merov Linden  committed c8b88d9 Merge

Sync with viewer-development

  • Participants
  • Parent commits 5c9b189, 9d2b325

Comments (0)

Files changed (75)

File autobuild.xml

File contents unchanged.

File indra/cmake/OpenSSL.cmake

File contents unchanged.

File indra/integration_tests/llimage_libtest/llimage_libtest.cpp

 #include "llimagetga.h"
 #include "llimagej2c.h"
 #include "lldir.h"
+#include "lldiriterator.h"
 
 // system libraries
 #include <iostream>
 	{
 		// If file name is a pattern, iterate to get each file name and store
 		std::string next_name;
-		while (gDirUtilp->getNextFileInDir(dir,name,next_name))
+		LLDirIterator iter(dir, name);
+		while (iter.next(next_name))
 		{
 			std::string file_name = dir + gDirUtilp->getDirDelimiter() + next_name;
 			input_filenames.push_back(file_name);

File indra/llcommon/lleventtimer.cpp

 void LLEventTimer::updateClass() 
 {
 	std::list<LLEventTimer*> completed_timers;
-
+	for (instance_iter iter = beginInstances(); iter != endInstances(); ) 
 	{
-		LLInstanceTrackerScopedGuard guard;
-		for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ) 
-		{
-			LLEventTimer& timer = *iter++;
-			F32 et = timer.mEventTimer.getElapsedTimeF32();
-			if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
-				timer.mEventTimer.reset();
-				if ( timer.tick() )
-				{
-					completed_timers.push_back( &timer );
-				}
+		LLEventTimer& timer = *iter++;
+		F32 et = timer.mEventTimer.getElapsedTimeF32();
+		if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
+			timer.mEventTimer.reset();
+			if ( timer.tick() )
+			{
+				completed_timers.push_back( &timer );
 			}
 		}
 	}

File indra/llcommon/llfasttimer_class.cpp

 // static
 void LLFastTimer::DeclareTimer::updateCachedPointers()
 {
-	DeclareTimer::LLInstanceTrackerScopedGuard guard;
 	// propagate frame state pointers to timer declarations
-	for (DeclareTimer::instance_iter it = guard.beginInstances();
-		it != guard.endInstances();
-		++it)
+	for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 	{
 		// update cached pointer
 		it->mFrameState = &it->mTimer.getFrameState();
 
 	// set up initial tree
 	{
-		NamedTimer::LLInstanceTrackerScopedGuard guard;
-		for (instance_iter it = guard.beginInstances();
-		     it != guard.endInstances();
-		     ++it)
+		for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 		{
 			NamedTimer& timer = *it;
 			if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
 		LLSD sd;
 
 		{
-			NamedTimer::LLInstanceTrackerScopedGuard guard;
-			for (NamedTimer::instance_iter it = guard.beginInstances();
-			     it != guard.endInstances();
-			     ++it)
+			for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 			{
 				NamedTimer& timer = *it;
 				FrameState& info = timer.getFrameState();
 		llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size());
 	}
 
-	// sort timers by dfs traversal order to improve cache coherency
+	// sort timers by DFS traversal order to improve cache coherency
 	std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS());
 
 	// update pointers into framestatelist now that we've sorted it
 
 	// reset for next frame
 	{
-		NamedTimer::LLInstanceTrackerScopedGuard guard;
-		for (NamedTimer::instance_iter it = guard.beginInstances();
-		     it != guard.endInstances();
-		     ++it)
+		for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 		{
 			NamedTimer& timer = *it;
 			
 
 	// reset all history
 	{
-		NamedTimer::LLInstanceTrackerScopedGuard guard;
-		for (NamedTimer::instance_iter it = guard.beginInstances();
-		     it != guard.endInstances();
-		     ++it)
+		for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 		{
 			NamedTimer& timer = *it;
 			if (&timer != NamedTimerFactory::instance().getRootTimer()) 
 
 #else
 //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp
-// These use QueryPerformanceCounter, which is arguably fine and also works on amd architectures.
+// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.
 U32 LLFastTimer::getCPUClockCount32()
 {
 	return (U32)(get_clock_count()>>8);

File indra/llcommon/llinstancetracker.h

 {
 	typedef typename std::map<KEY, T*> InstanceMap;
 	typedef LLInstanceTracker<T, KEY> MyT;
-	typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
-	typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
 public:
-	/// Dereferencing key_iter gives you a const KEY&
-	typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter;
-	/// Dereferencing instance_iter gives you a T&
-	typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter;
+	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
+	{
+	public:
+		typedef boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag> super_t;
+		
+		instance_iter(const typename InstanceMap::iterator& it)
+		:	mIterator(it)
+		{
+			++sIterationNestDepth;
+		}
+
+		~instance_iter()
+		{
+			--sIterationNestDepth;
+		}
+
+
+	private:
+		friend class boost::iterator_core_access;
+
+		void increment() { mIterator++; }
+		bool equal(instance_iter const& other) const
+		{
+			return mIterator == other.mIterator;
+		}
+
+		T& dereference() const
+		{
+			return *(mIterator->second);
+		}
+
+		typename InstanceMap::iterator mIterator;
+	};
+
+	class key_iter : public boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag>
+	{
+	public:
+		typedef boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag> super_t;
+
+		key_iter(typename InstanceMap::iterator& it)
+			:	mIterator(it)
+		{
+			++sIterationNestDepth;
+		}
+
+		key_iter(const key_iter& other)
+			:	mIterator(other.mIterator)
+		{
+			++sIterationNestDepth;
+		}
+
+		~key_iter()
+		{
+			--sIterationNestDepth;
+		}
+
+
+	private:
+		friend class boost::iterator_core_access;
+
+		void increment() { mIterator++; }
+		bool equal(key_iter const& other) const
+		{
+			return mIterator == other.mIterator;
+		}
+
+		KEY& dereference() const
+		{
+			return const_cast<KEY&>(mIterator->first);
+		}
+
+		typename InstanceMap::iterator mIterator;
+	};
 
 	static T* getInstance(const KEY& k)
 	{
 		return (found == getMap_().end()) ? NULL : found->second;
 	}
 
+	static instance_iter beginInstances() 
+	{	
+		return instance_iter(getMap_().begin()); 
+	}
+
+	static instance_iter endInstances() 
+	{
+		return instance_iter(getMap_().end());
+	}
+
+	static S32 instanceCount() { return getMap_().size(); }
+
 	static key_iter beginKeys()
 	{
-		return boost::make_transform_iterator(getMap_().begin(),
-											  boost::bind(&InstanceMap::value_type::first, _1));
+		return key_iter(getMap_().begin());
 	}
 	static key_iter endKeys()
 	{
-		return boost::make_transform_iterator(getMap_().end(),
-											  boost::bind(&InstanceMap::value_type::first, _1));
+		return key_iter(getMap_().end());
 	}
-	static instance_iter beginInstances()
-	{
-		return instance_iter(boost::make_transform_iterator(getMap_().begin(),
-															boost::bind(&InstanceMap::value_type::second, _1)));
-	}
-	static instance_iter endInstances()
-	{
-		return instance_iter(boost::make_transform_iterator(getMap_().end(),
-															boost::bind(&InstanceMap::value_type::second, _1)));
-	}
-	static S32 instanceCount() { return getMap_().size(); }
+
 protected:
 	LLInstanceTracker(KEY key) { add_(key); }
-	virtual ~LLInstanceTracker() { remove_(); }
+	virtual ~LLInstanceTracker() 
+	{ 
+		// it's unsafe to delete instances of this type while all instances are being iterated over.
+		llassert(sIterationNestDepth == 0);
+		remove_(); 		
+	}
 	virtual void setKey(KEY key) { remove_(); add_(key); }
-	virtual const KEY& getKey() const { return mKey; }
+	virtual const KEY& getKey() const { return mInstanceKey; }
 
 private:
 	void add_(KEY key) 
 	{ 
-		mKey = key; 
+		mInstanceKey = key; 
 		getMap_()[key] = static_cast<T*>(this); 
 	}
 	void remove_()
 	{
-		getMap_().erase(mKey);
+		getMap_().erase(mInstanceKey);
 	}
 
     static InstanceMap& getMap_()
 
 private:
 
-	KEY mKey;
+	KEY mInstanceKey;
+	static S32 sIterationNestDepth;
 };
 
+template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
+
 /// explicit specialization for default case where KEY is T*
 /// use a simple std::set<T*>
 template<typename T>
 	typedef typename std::set<T*> InstanceSet;
 	typedef LLInstanceTracker<T, T*> MyT;
 public:
-	/// Dereferencing key_iter gives you a T* (since T* is the key)
-	typedef typename InstanceSet::iterator key_iter;
-	/// Dereferencing instance_iter gives you a T&
-	typedef boost::indirect_iterator<key_iter> instance_iter;
 
 	/// for completeness of analogy with the generic implementation
 	static T* getInstance(T* k) { return k; }
 	static S32 instanceCount() { return getSet_().size(); }
 
-	// Instantiate this to get access to iterators for this type.  It's a 'guard' in the sense
-	// that it treats deletes of this type as errors as long as there is an instance of
-	// this class alive in scope somewhere (i.e. deleting while iterating is bad).
-	class LLInstanceTrackerScopedGuard
+	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
 	{
 	public:
-		LLInstanceTrackerScopedGuard()
+		instance_iter(const typename InstanceSet::iterator& it)
+		:	mIterator(it)
 		{
 			++sIterationNestDepth;
 		}
 
-		~LLInstanceTrackerScopedGuard()
+		instance_iter(const instance_iter& other)
+		:	mIterator(other.mIterator)
+		{
+			++sIterationNestDepth;
+		}
+
+		~instance_iter()
 		{
 			--sIterationNestDepth;
 		}
 
-		static instance_iter beginInstances() {	return instance_iter(getSet_().begin()); }
-		static instance_iter endInstances() { return instance_iter(getSet_().end()); }
-		static key_iter beginKeys() { return getSet_().begin(); }
-		static key_iter endKeys()   { return getSet_().end(); }
+	private:
+		friend class boost::iterator_core_access;
+
+		void increment() { mIterator++; }
+		bool equal(instance_iter const& other) const
+		{
+			return mIterator == other.mIterator;
+		}
+
+		T& dereference() const
+		{
+			return **mIterator;
+		}
+
+		typename InstanceSet::iterator mIterator;
 	};
 
+	static instance_iter beginInstances() {	return instance_iter(getSet_().begin()); }
+	static instance_iter endInstances() { return instance_iter(getSet_().end()); }
+
 protected:
 	LLInstanceTracker()
 	{
 		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.  This assert will probably be turned on early in the next development cycle.
-		//llassert(sIterationNestDepth == 0);
 		getSet_().insert(static_cast<T*>(this));
 	}
 	virtual ~LLInstanceTracker()
 
 	LLInstanceTracker(const LLInstanceTracker& other)
 	{
-		//llassert(sIterationNestDepth == 0);
 		getSet_().insert(static_cast<T*>(this));
 	}
 

File indra/llcommon/tests/llinstancetracker_test.cpp

         ensure_equals(Keyed::instanceCount(), 0);
     }
 
-    template<> template<>
-    void object::test<2>()
-    {
-        ensure_equals(Unkeyed::instanceCount(), 0);
-        {
-            Unkeyed one;
-            ensure_equals(Unkeyed::instanceCount(), 1);
-            Unkeyed* found = Unkeyed::getInstance(&one);
-            ensure_equals(found, &one);
-            {
-                boost::scoped_ptr<Unkeyed> two(new Unkeyed);
-                ensure_equals(Unkeyed::instanceCount(), 2);
-                Unkeyed* found = Unkeyed::getInstance(two.get());
-                ensure_equals(found, two.get());
-            }
-            ensure_equals(Unkeyed::instanceCount(), 1);
-        }
-        ensure_equals(Unkeyed::instanceCount(), 0);
-    }
+  //  template<> template<>
+  //  void object::test<2>()
+  //  {
+  //      ensure_equals(Unkeyed::instanceCount(), 0);
+  //      {
+  //          Unkeyed one;
+  //          ensure_equals(Unkeyed::instanceCount(), 1);
+  //          Unkeyed* found = Unkeyed::getInstance(&one);
+  //          ensure_equals(found, &one);
+  //          {
+  //              boost::scoped_ptr<Unkeyed> two(new Unkeyed);
+  //              ensure_equals(Unkeyed::instanceCount(), 2);
+  //              Unkeyed* found = Unkeyed::getInstance(two.get());
+  //              ensure_equals(found, two.get());
+  //          }
+  //          ensure_equals(Unkeyed::instanceCount(), 1);
+  //      }
+  //      ensure_equals(Unkeyed::instanceCount(), 0);
+  //  }
 
-    template<> template<>
-    void object::test<3>()
-    {
-        Keyed one("one"), two("two"), three("three");
-        // We don't want to rely on the underlying container delivering keys
-        // in any particular order. That allows us the flexibility to
-        // reimplement LLInstanceTracker using, say, a hash map instead of a
-        // std::map. We DO insist that every key appear exactly once.
-        typedef std::vector<std::string> StringVector;
-        StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
-        std::sort(keys.begin(), keys.end());
-        StringVector::const_iterator ki(keys.begin());
-        ensure_equals(*ki++, "one");
-        ensure_equals(*ki++, "three");
-        ensure_equals(*ki++, "two");
-        // Use ensure() here because ensure_equals would want to display
-        // mismatched values, and frankly that wouldn't help much.
-        ensure("didn't reach end", ki == keys.end());
+  //  template<> template<>
+  //  void object::test<3>()
+  //  {
+  //      Keyed one("one"), two("two"), three("three");
+  //      // We don't want to rely on the underlying container delivering keys
+  //      // in any particular order. That allows us the flexibility to
+  //      // reimplement LLInstanceTracker using, say, a hash map instead of a
+  //      // std::map. We DO insist that every key appear exactly once.
+  //      typedef std::vector<std::string> StringVector;
+  //      StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
+  //      std::sort(keys.begin(), keys.end());
+  //      StringVector::const_iterator ki(keys.begin());
+  //      ensure_equals(*ki++, "one");
+  //      ensure_equals(*ki++, "three");
+  //      ensure_equals(*ki++, "two");
+  //      // Use ensure() here because ensure_equals would want to display
+  //      // mismatched values, and frankly that wouldn't help much.
+  //      ensure("didn't reach end", ki == keys.end());
 
-        // Use a somewhat different approach to order independence with
-        // beginInstances(): explicitly capture the instances we know in a
-        // set, and delete them as we iterate through.
-        typedef std::set<Keyed*> InstanceSet;
-        InstanceSet instances;
-        instances.insert(&one);
-        instances.insert(&two);
-        instances.insert(&three);
-        for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
-             ii != iend; ++ii)
-        {
-            Keyed& ref = *ii;
-            ensure_equals("spurious instance", instances.erase(&ref), 1);
-        }
-        ensure_equals("unreported instance", instances.size(), 0);
-    }
+  //      // Use a somewhat different approach to order independence with
+  //      // beginInstances(): explicitly capture the instances we know in a
+  //      // set, and delete them as we iterate through.
+  //      typedef std::set<Keyed*> InstanceSet;
+  //      InstanceSet instances;
+  //      instances.insert(&one);
+  //      instances.insert(&two);
+  //      instances.insert(&three);
+  //      for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
+  //           ii != iend; ++ii)
+  //      {
+  //          Keyed& ref = *ii;
+  //          ensure_equals("spurious instance", instances.erase(&ref), 1);
+  //      }
+  //      ensure_equals("unreported instance", instances.size(), 0);
+  //  }
 
-    template<> template<>
-    void object::test<4>()
-    {
-        Unkeyed one, two, three;
-        typedef std::set<Unkeyed*> KeySet;
-        KeySet keys;
-        keys.insert(&one);
-        keys.insert(&two);
-        keys.insert(&three);
-	{
-		Unkeyed::LLInstanceTrackerScopedGuard guard;
-		for (Unkeyed::key_iter ki(guard.beginKeys()), kend(guard.endKeys());
-		     ki != kend; ++ki)
-		{
-			ensure_equals("spurious key", keys.erase(*ki), 1);
-		}
-	}
-        ensure_equals("unreported key", keys.size(), 0);
-
-        KeySet instances;
-        instances.insert(&one);
-        instances.insert(&two);
-        instances.insert(&three);
-	{
-		Unkeyed::LLInstanceTrackerScopedGuard guard;
-		for (Unkeyed::instance_iter ii(guard.beginInstances()), iend(guard.endInstances());
-		     ii != iend; ++ii)
-		{
-			Unkeyed& ref = *ii;
-			ensure_equals("spurious instance", instances.erase(&ref), 1);
-		}
-	}
-        ensure_equals("unreported instance", instances.size(), 0);
-    }
+  //  template<> template<>
+  //  void object::test<4>()
+  //  {
+  //      Unkeyed one, two, three;
+  //      typedef std::set<Unkeyed*> KeySet;
+  //  
+  //      KeySet instances;
+  //      instances.insert(&one);
+  //      instances.insert(&two);
+  //      instances.insert(&three);
+	
+		//for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances()); ii != iend; ++ii)
+		//{
+		//	Unkeyed& ref = *ii;
+		//	ensure_equals("spurious instance", instances.erase(&ref), 1);
+		//}
+	
+  //      ensure_equals("unreported instance", instances.size(), 0);
+  //  }
 } // namespace tut

File indra/llrender/llgl.cpp

 void LLGLNamePool::upkeepPools()
 {
 	LLMemType mt(LLMemType::MTYPE_UPKEEP_POOLS);
-	tracker_t::LLInstanceTrackerScopedGuard guard;
-	for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
+	for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
 	{
 		LLGLNamePool & pool = *iter;
 		pool.upkeep();
 //static
 void LLGLNamePool::cleanupPools()
 {
-	tracker_t::LLInstanceTrackerScopedGuard guard;
-	for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
+	for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
 	{
 		LLGLNamePool & pool = *iter;
 		pool.cleanup();

File indra/llui/CMakeLists.txt

     llaccordionctrl.cpp
     llaccordionctrltab.cpp
     llbadge.cpp
+	llbadgeholder.cpp
     llbadgeowner.cpp
     llbutton.cpp
     llcheckboxctrl.cpp
     llaccordionctrl.h
     llaccordionctrltab.h
     llbadge.h
+	llbadgeholder.h
     llbadgeowner.h
     llbutton.h
     llcallbackmap.h

File indra/llui/llbadge.cpp

 	, image_color("image_color")
 	, label("label")
 	, label_color("label_color")
+	, label_offset_horiz("label_offset_horiz")
+	, label_offset_vert("label_offset_vert")
 	, location("location", LLRelPos::TOP_LEFT)
 	, location_percent_hcenter("location_percent_hcenter")
 	, location_percent_vcenter("location_percent_vcenter")
 	comp &= (image_color() == a.image_color());
 	comp &= (label() == a.label());
 	comp &= (label_color() == a.label_color());
+	comp &= (label_offset_horiz() == a.label_offset_horiz());
+	comp &= (label_offset_vert() == a.label_offset_vert());
 	comp &= (location() == a.location());
 	comp &= (location_percent_hcenter() == a.location_percent_hcenter());
 	comp &= (location_percent_vcenter() == a.location_percent_vcenter());
 	, mImageColor(p.image_color)
 	, mLabel(p.label)
 	, mLabelColor(p.label_color)
+	, mLabelOffsetHoriz(p.label_offset_horiz)
+	, mLabelOffsetVert(p.label_offset_vert)
 	, mLocation(p.location)
 	, mLocationPercentHCenter(0.5f)
 	, mLocationPercentVCenter(0.5f)
 {
 }
 
+bool LLBadge::addToView(LLView * view)
+{
+	bool child_added = view->addChild(this);
+
+	if (child_added)
+	{
+		setShape(view->getLocalRect());
+	}
+
+	return child_added;
+}
+
 void LLBadge::setLabel(const LLStringExplicit& label)
 {
 	mLabel = label;
 			// Draw the label
 			//
 
-			mGLFont->render(badge_label_wstring, badge_label_begin_offset,
-							badge_center_x, badge_center_y,
+			mGLFont->render(badge_label_wstring,
+							badge_label_begin_offset,
+							badge_center_x + mLabelOffsetHoriz,
+							badge_center_y + mLabelOffsetVert,
 							mLabelColor % alpha,
 							LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position
 							LLFontGL::NORMAL, // normal text (not bold, italics, etc.)

File indra/llui/llbadge.h

 		Optional< std::string >			label;
 		Optional< LLUIColor >			label_color;
 
+		Optional< S32 >					label_offset_horiz;
+		Optional< S32 >					label_offset_vert;
+
 		Optional< LLRelPos::Location >	location;
 		Optional< U32 >					location_percent_hcenter;
 		Optional< U32 >					location_percent_vcenter;
 public:
 
 	~LLBadge();
-	
+
+	bool				addToView(LLView * view);
+
 	virtual void		draw();
 
 	const std::string	getLabel() const { return wstring_to_utf8str(mLabel); }
 	LLUIString				mLabel;
 	LLUIColor				mLabelColor;
 
+	S32						mLabelOffsetHoriz;
+	S32						mLabelOffsetVert;
+
 	LLRelPos::Location		mLocation;
 	F32						mLocationPercentHCenter;
 	F32						mLocationPercentVCenter;

File indra/llui/llbadgeholder.cpp

+/** 
+ * @file llbadgeholder.cpp
+ * @brief Source for badge holders
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llbadgeholder.h"
+
+#include "llbadge.h"
+#include "llview.h"
+
+
+bool LLBadgeHolder::addBadge(LLBadge * badge)
+{
+	bool badge_added = false;
+
+	LLView * this_view = dynamic_cast<LLView *>(this);
+
+	if (this_view && mAcceptsBadge)
+	{
+		badge_added = badge->addToView(this_view);
+	}
+
+	return badge_added;
+}

File indra/llui/llbadgeholder.h

+/** 
+ * @file llbadgeholder.h
+ * @brief Header for badge holders
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLBADGEHOLDER_H
+#define LL_LLBADGEHOLDER_H
+
+//
+// Classes
+//
+
+class LLBadge;
+
+class LLBadgeHolder
+{
+public:
+
+	LLBadgeHolder(bool acceptsBadge)
+		: mAcceptsBadge(acceptsBadge)
+	{
+	}
+
+	void setAcceptsBadge(bool acceptsBadge) { mAcceptsBadge = acceptsBadge; }
+	bool acceptsBadge() const { return mAcceptsBadge; }
+
+	virtual bool addBadge(LLBadge * badge);
+
+private:
+
+	bool		mAcceptsBadge;
+
+};
+
+#endif  // LL_LLBADGEHOLDER_H

File indra/llui/llbadgeowner.cpp

 
 #include "linden_common.h"
 
+#include "llbadgeholder.h"
 #include "llbadgeowner.h"
 #include "llpanel.h"
 
 	}
 }
 
-void LLBadgeOwner::addBadgeToParentPanel()
+bool LLBadgeOwner::addBadgeToParentPanel()
 {
+	bool badge_added = false;
+
 	LLView * owner_view = mBadgeOwnerView.get();
 	
 	if (mBadge && owner_view)
 	{
-		// Badge parent is badge owner by default
-		LLView * badge_parent = owner_view;
+		LLBadgeHolder * badge_holder = NULL;
 
-		// Find the appropriate parent for the badge
+		// Find the appropriate holder for the badge
 		LLView * parent = owner_view->getParent();
 
 		while (parent)
 		{
-			LLPanel * parent_panel = dynamic_cast<LLPanel *>(parent);
+			LLBadgeHolder * badge_holder_panel = dynamic_cast<LLBadgeHolder *>(parent);
 
-			if (parent_panel && parent_panel->acceptsBadge())
+			if (badge_holder_panel && badge_holder_panel->acceptsBadge())
 			{
-				badge_parent = parent;
+				badge_holder = badge_holder_panel;
 				break;
 			}
 
 			parent = parent->getParent();
 		}
 
-		if (badge_parent)
+		if (badge_holder)
 		{
-			badge_parent->addChild(mBadge);
+			badge_added = badge_holder->addBadge(mBadge);
 		}
 		else
 		{
-			llwarns << "Unable to find parent panel for badge " << mBadge->getName() << " on " << owner_view->getName() << llendl;
+			// Badge parent is fallback badge owner if no valid holder exists in the hierarchy
+			badge_added = mBadge->addToView(owner_view);
 		}
 	}
+
+	return badge_added;
 }
 
 LLBadge* LLBadgeOwner::createBadge(const LLBadge::Params& p)

File indra/llui/llbadgeowner.h

 	LLBadgeOwner(LLHandle< LLView > viewHandle);
 
 	void initBadgeParams(const LLBadge::Params& p);
-	void addBadgeToParentPanel();
+	bool addBadgeToParentPanel();
 	
 	bool badgeHasParent() const { return (mBadge && mBadge->getParent()); }
 

File indra/llui/llcombobox.cpp

 			return FALSE;
 		}
 		// if selection has changed, pop open list
-		else if (mList->getLastSelectedItem() != last_selected_item ||
-				(key == KEY_DOWN || key == KEY_UP) && !mList->isEmpty())
+		else if (mList->getLastSelectedItem() != last_selected_item 
+					|| ((key == KEY_DOWN || key == KEY_UP)
+						&& mList->getCanSelect()
+						&& !mList->isEmpty()))
 		{
 			showList();
 		}

File indra/llui/llconsole.cpp

 // static
 void LLConsole::updateClass()
 {	
-	LLInstanceTrackerScopedGuard guard;
-
-	for (instance_iter it = guard.beginInstances(); it != guard.endInstances(); ++it)
+	for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 	{
 		it->update();
 	} 

File indra/llui/llfloater.cpp

 void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
 	LLPanel::reshape(width, height, called_from_parent);
-	storeRectControl();
 }
 
 void LLFloater::releaseFocus()
 	const LLRect old_rect = getRect();
 	LLView::handleReshape(new_rect, by_user);
 
+	if (by_user)
+	{
+		storeRectControl();
+	}
+
 	// if not minimized, adjust all snapped dependents to new shape
 	if (!isMinimized())
 	{
 
 LLFloaterView::LLFloaterView (const Params& p)
 :	LLUICtrl (p),
-
 	mFocusCycleMode(FALSE),
 	mMinimizePositionVOffset(0),
 	mSnapOffsetBottom(0),
 // By default, adjust vertical.
 void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	reshapeFloater(width, height, called_from_parent, ADJUST_VERTICAL_YES);
-}
-
-// When reshaping this view, make the floaters follow their closest edge.
-void LLFloaterView::reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical)
-{
 	S32 old_width = getRect().getWidth();
 	S32 old_height = getRect().getHeight();
 
 			// "No vertical adjustment" usually means that the bottom of the view
 			// has been pushed up or down.  Hence we want the floaters to follow
 			// the top.
-			if (!adjust_vertical)
-			{
-				follow_flags |= FOLLOWS_TOP;
-			}
-			else if (top_offset < bottom_offset)
+			if (top_offset < bottom_offset)
 			{
 				follow_flags |= FOLLOWS_TOP;
 			}
 	mAutoTile = p.auto_tile;
 	mOpenCentered = p.open_centered;
 
-	if (p.save_rect)
+	if (p.save_rect && mRectControl.empty())
 	{
 		mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
 	}
 }
 
 LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");
+static LLFastTimer::DeclareTimer FTM_EXTERNAL_FLOATER_LOAD("Load Extern Floater Reference");
 
 bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node)
 {
-	Params params(LLUICtrlFactory::getDefaultParams<LLFloater>());
+	Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
+	Params params(default_params);
+
 	LLXUIParser parser;
 	parser.readXUI(node, params, filename); // *TODO: Error checking
 
+	std::string xml_filename = params.filename;
+
+	if (!xml_filename.empty())
+	{
+		LLXMLNodePtr referenced_xml;
+
+		if (output_node)
+		{
+			//if we are exporting, we want to export the current xml
+			//not the referenced xml
+			Params output_params;
+			parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName());
+			setupParamsForExport(output_params, parent);
+			output_node->setName(node->getName()->mString);
+			parser.writeXUI(output_node, output_params, &default_params);
+			return TRUE;
+		}
+
+		LLUICtrlFactory::instance().pushFileName(xml_filename);
+
+		LLFastTimer _(FTM_EXTERNAL_FLOATER_LOAD);
+		if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
+		{
+			llwarns << "Couldn't parse panel from: " << xml_filename << llendl;
+
+			return FALSE;
+		}
+
+		parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());
+
+		// add children using dimensions from referenced xml for consistent layout
+		setShape(params.rect);
+		LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance());
+
+		LLUICtrlFactory::instance().popFileName();
+	}
+
+
 	if (output_node)
 	{
 		Params output_params(params);
 	{
 		params.rect.left.set(0);
 	}
-
 	params.from_xui = true;
 	applyXUILayout(params, parent);
  	initFromParams(params);
 	
 	return res;
 }
+
+void LLFloater::stackWith(LLFloater& other)
+{
+	static LLUICachedControl<S32> floater_offset ("UIFloaterOffset", 16);
+
+	LLRect next_rect;
+	if (other.getHost())
+	{
+		next_rect = other.getHost()->getRect();
+	}
+	else
+	{
+		next_rect = other.getRect();
+	}
+	next_rect.translate(floater_offset, -floater_offset);
+
+	next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
+	
+	mRectControl.clear(); // don't save rect of stacked floaters
+	setShape(next_rect);
+}
+

File indra/llui/llfloater.h

 
 	LLHandle<LLFloater> getHandle() const { return mHandle; }
 	const LLSD& 	getKey() { return mKey; }
-	BOOL		 	matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
+	virtual bool	matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
 	
 	const std::string& getInstanceName() { return mInstanceName; }
 	
 
 	virtual void    setTornOff(bool torn_off) { mTornOff = torn_off; }
 
+	void			stackWith(LLFloater& other);
+
 	// Return a closeable floater, if any, given the current focus.
 	static LLFloater* getClosableFloaterFromFocus(); 
 
 	void			updateTransparency(ETypeTransparency transparency_type);
 		
 protected:
-
-	void			setRectControl(const std::string& rectname) { mRectControl = rectname; };
-
 	virtual void    applySavedVariables();
 
 	void			applyRectControl();
 public:
 
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-	void reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical);
-
 	/*virtual*/ void draw();
 	/*virtual*/ LLRect getSnapRect() const;
 	/*virtual*/ void refresh();

File indra/llui/llfloaterreg.cpp

 }
 
 //static
-LLRect LLFloaterReg::getFloaterRect(const std::string& name)
+LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
 {
 	LLRect rect;
 	const std::string& groupname = sGroupMap[name];
 		instance_list_t& list = sInstanceMap[groupname];
 		if (!list.empty())
 		{
-			static LLUICachedControl<S32> floater_offset ("UIFloaterOffset", 16);
-			LLFloater* last_floater = list.back();
-			if (last_floater->getHost())
-			{
-				rect = last_floater->getHost()->getRect();
-			}
-			else
-			{
-				rect = last_floater->getRect();
-			}
-			rect.translate(floater_offset, -floater_offset);
+			return list.back();
 		}
 	}
-	return rect;
+	return NULL;
 }
 
 //static
 				}
 					
 				// Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
-				res->mKey = key;
+				if (res->mKey.isUndefined()) 
+				{
+						res->mKey = key;
+				}
 				res->setInstanceName(name);
 				res->applySavedVariables(); // Can't apply rect and dock state until setting instance name
 				if (res->mAutoTile && !res->getHost() && index > 0)
 				{
-					const LLRect& cur_rect = res->getRect();
-					LLRect next_rect = getFloaterRect(groupname);
-					next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, cur_rect.getWidth(), cur_rect.getHeight());
-					res->setRect(next_rect);
-					res->setRectControl(LLStringUtil::null); // don't save rect of tiled floaters
-					gFloaterView->adjustToFitScreen(res, true);
+					LLFloater* last_floater = getLastFloaterInGroup(groupname);
+					if (last_floater)
+					{
+						res->stackWith(*last_floater);
+						gFloaterView->adjustToFitScreen(res, true);
+					}
 				}
 				else
 				{

File indra/llui/llfloaterreg.h

 					const std::string& groupname = LLStringUtil::null);
 
 	// Helpers
-	static LLRect getFloaterRect(const std::string& name);
+	static LLFloater* getLastFloaterInGroup(const std::string& name);
 	
 	// Find / get (create) / remove / destroy
 	static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());

File indra/llui/lllayoutstack.cpp

 //static 
 void LLLayoutStack::updateClass()
 {
-	LLInstanceTrackerScopedGuard guard;
-	for (LLLayoutStack::instance_iter it = guard.beginInstances();
-	     it != guard.endInstances();
-	     ++it)
+	for (instance_iter it = beginInstances(); it != endInstances(); ++it)
 	{
 		it->updateLayout();
 	}

File indra/llui/llpanel.cpp

 
 LLPanel::LLPanel(const LLPanel::Params& p)
 :	LLUICtrl(p),
+	LLBadgeHolder(p.accepts_badge),
 	mBgVisible(p.background_visible),
 	mBgOpaque(p.background_opaque),
 	mBgOpaqueColor(p.bg_opaque_color()),
 	mCommitCallbackRegistrar(false),
 	mEnableCallbackRegistrar(false),
 	mXMLFilename(p.filename),
-	mVisibleSignal(NULL),
-	mAcceptsBadge(p.accepts_badge)
+	mVisibleSignal(NULL)
 	// *NOTE: Be sure to also change LLPanel::initFromParams().  We have too
 	// many classes derived from LLPanel to retrofit them all to pass in params.
 {
 	mBgOpaqueImageOverlay = p.bg_opaque_image_overlay;
 	mBgAlphaImageOverlay = p.bg_alpha_image_overlay;
 
-	mAcceptsBadge = p.accepts_badge;
+	setAcceptsBadge(p.accepts_badge);
 }
 
 static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup");
 
 		if (!xml_filename.empty())
 		{
-			LLUICtrlFactory::instance().pushFileName(xml_filename);
-
-			LLFastTimer timer(FTM_EXTERNAL_PANEL_LOAD);
 			if (output_node)
 			{
 				//if we are exporting, we want to export the current xml
 				return TRUE;
 			}
 		
+			LLUICtrlFactory::instance().pushFileName(xml_filename);
+
+			LLFastTimer timer(FTM_EXTERNAL_PANEL_LOAD);
 			if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
 			{
 				llwarns << "Couldn't parse panel from: " << xml_filename << llendl;

File indra/llui/llpanel.h

 #include "lluiimage.h"
 #include "lluistring.h"
 #include "v4color.h"
+#include "llbadgeholder.h"
 #include <list>
 #include <queue>
 
  * With or without border,
  * Can contain LLUICtrls.
  */
-class LLPanel : public LLUICtrl
+class LLPanel : public LLUICtrl, public LLBadgeHolder
 {
 public:
 	struct LocalizedString : public LLInitParam::Block<LocalizedString>
 	
 	boost::signals2::connection setVisibleCallback( const commit_signal_t::slot_type& cb );
 
-	bool acceptsBadge() const { return mAcceptsBadge; }
-
 protected:
 	// Override to set not found list
 	LLButton*		getDefaultButton() { return mDefaultBtn; }
 	std::string		mHelpTopic;         // the name of this panel's help topic to display in the Help Viewer
 	typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t;
 	static factory_stack_t	sFactoryStack;
+
+	// for setting the xml filename when building panel in context dependent cases
+	std::string		mXMLFilename;
 	
 private:
-	bool			mAcceptsBadge;
 	BOOL			mBgVisible;				// any background at all?
 	BOOL			mBgOpaque;				// use opaque color or image
 	LLUIColor		mBgOpaqueColor;
 	typedef std::map<std::string, std::string> ui_string_map_t;
 	ui_string_map_t	mUIStrings;
 
-	// for setting the xml filename when building panel in context dependent cases
-	std::string		mXMLFilename;
 
 }; // end class LLPanel
 

File indra/llui/llsdparam.h

 			LLParamSDParser parser;
 			parser.readSD(sd, *this);
 		}
+
+		operator LLSD() const
+		{
+			LLParamSDParser parser;
+			LLSD sd;
+			parser.writeSD(sd, *this);
+			return sd;
+		}
 		
 		LLSDParamAdapter(const T& val)
+		: T(val)
 		{
 			T::operator=(val);
 		}

File indra/llui/llui.cpp

 		alpha("alpha"),
 		control("")
 	{
-		updateBlockFromValue();
+		updateBlockFromValue(false);
 	}
 
 	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
 		}
 	}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool make_block_authoritative)
 	{
 		LLColor4 color = getValue();
-		red.set(color.mV[VRED], false);
-		green.set(color.mV[VGREEN], false);
-		blue.set(color.mV[VBLUE], false);
-		alpha.set(color.mV[VALPHA], false);
-		control.set("", false);
+		red.set(color.mV[VRED], make_block_authoritative);
+		green.set(color.mV[VGREEN], make_block_authoritative);
+		blue.set(color.mV[VBLUE], make_block_authoritative);
+		alpha.set(color.mV[VALPHA], make_block_authoritative);
+		control.set("", make_block_authoritative);
 	}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
 			updateValue(LLFontGL::getFontDefault());
 		}
 		addSynonym(name, "");
-		updateBlockFromValue();
+		updateBlockFromValue(false);
 	}
 
 	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
 		}
 	}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool make_block_authoritative)
 	{
 		if (getValue())
 		{
-			name.set(LLFontGL::nameFromFont(getValue()), false);
-			size.set(LLFontGL::sizeFromFont(getValue()), false);
-			style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), false);
+			name.set(LLFontGL::nameFromFont(getValue()), make_block_authoritative);
+			size.set(LLFontGL::sizeFromFont(getValue()), make_block_authoritative);
+			style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), make_block_authoritative);
 		}
 	}
 
 		width("width"),
 		height("height")
 	{
-		updateBlockFromValue();
+		updateBlockFromValue(false);
 	}
 
 	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
 		updateValue(rect);
 	}
 	
-	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue()
+	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue(bool make_block_authoritative)
 	{
 		// because of the ambiguity in specifying a rect by position and/or dimensions
-		// we clear the "provided" flag so that values from xui/etc have priority
-		// over those calculated from the rect object
+		// we use the lowest priority pairing so that any valid pairing in xui 
+		// will override those calculated from the rect object
+		// in this case, that is left+width and bottom+height
+		LLRect& value = getValue();
 
-		LLRect& value = getValue();
-		left.set(value.mLeft, false);
-		right.set(value.mRight, false);
-		bottom.set(value.mBottom, false);
-		top.set(value.mTop, false);
-		width.set(value.getWidth(), false);
-		height.set(value.getHeight(), false);
+		left.set(value.mLeft, make_block_authoritative);
+		width.set(value.getWidth(), make_block_authoritative);
+
+		bottom.set(value.mBottom, make_block_authoritative);
+		height.set(value.getHeight(), make_block_authoritative);
 	}
 
 	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
 		x("x"),
 		y("y")
 	{
-		updateBlockFromValue();
+		updateBlockFromValue(false);
 	}
 
 	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
 		updateValue(LLCoordGL(x, y));
 	}
 	
-	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue()
+	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue(bool make_block_authoritative)
 	{
-		x.set(getValue().mX, false);
-		y.set(getValue().mY, false);
+		x.set(getValue().mX, make_block_authoritative);
+		y.set(getValue().mY, make_block_authoritative);
 	}
 
 

File indra/llui/llui.h

 		ParamValue(const LLRect& value);
 
 		void updateValueFromBlock();
-		void updateBlockFromValue();
+		void updateBlockFromValue(bool make_block_authoritative);
 	};
 
 	template<>
 
 		ParamValue(const LLUIColor& color);
 		void updateValueFromBlock();
-		void updateBlockFromValue();
+		void updateBlockFromValue(bool make_block_authoritative);
 	};
 
 	template<>
 
 		ParamValue(const LLFontGL* value);
 		void updateValueFromBlock();
-		void updateBlockFromValue();
+		void updateBlockFromValue(bool make_block_authoritative);
 	};
 
 	template<>
 
 		ParamValue(const LLCoordGL& val);
 		void updateValueFromBlock();
-		void updateBlockFromValue();
+		void updateBlockFromValue(bool make_block_authoritative);
 	};
 }
 

File indra/llui/lluiimage.cpp

 		}
 	}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative)
 	{
 		if (getValue() == NULL)
 		{
-			name.set("none", false);
+			name.set("none", make_block_authoritative);
 		}
 		else
 		{
-			name.set(getValue()->getName(), false);
+			name.set(getValue()->getName(), make_block_authoritative);
 		}
 	}
 

File indra/llui/lluiimage.h

 		ParamValue(LLUIImage* const& image)
 		:	super_t(image)
 		{
-			updateBlockFromValue();
+			updateBlockFromValue(false);
 			addSynonym(name, "name");
 		}
 
 		void updateValueFromBlock();
-		void updateBlockFromValue();
+		void updateBlockFromValue(bool make_block_authoritative);
 	};
 
 	// Need custom comparison function for our test app, which only loads

File indra/llui/tests/llurlentry_stub.cpp

 	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock() 
 	{}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
 	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
 	{}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
 	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
 	{}
 
 	

File indra/llui/tests/llurlmatch_test.cpp

 	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
 	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
 	{}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
 	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
 	{}
 	
 	bool ParamCompare<LLUIImage*, false>::equals(

File indra/llxuixml/llinitparam.h

 			if (src_typed_param.isProvided()
 				&& (overwrite || !dst_typed_param.isProvided()))
 			{
-				dst_typed_param.clearValueName();
 				dst_typed_param.set(src_typed_param.getValue());
 				return true;
 			}
 		:	mValue(value),
 			mValueAge(VALUE_AUTHORITATIVE),
 			mKeyVersion(0),
-			mValidatedVersion(-1)
+			mValidatedVersion(-1),
+			mValidated(false)
 		{}
 
 		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation)
 		{
 			derived_t& typed_param = static_cast<derived_t&>(*this);
-			// type to apply parse direct value T
+			// try to parse direct value T
 			if (name_stack.first == name_stack.second)
 			{
 				if(parser.readValue(typed_param.mValue))
 				{
+					typed_param.mValueAge = VALUE_AUTHORITATIVE;
+					typed_param.updateBlockFromValue(false);
+
 					typed_param.clearValueName();
-					typed_param.mValueAge = VALUE_AUTHORITATIVE;
-					typed_param.updateBlockFromValue();
 
 					return true;
 				}
 			}
 
 			// fall back on parsing block components for T
-			// if we deserialized at least one component...
-			if (typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation))
-			{
-				return true;
-			}
-
-			return false;
+			return typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation);
 		}
 
 		void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const
 		{
-			const self_t& typed_param = static_cast<const self_t&>(*this);
-			const self_t* diff_param = static_cast<const self_t*>(diff_block);
+			const derived_t& typed_param = static_cast<const derived_t&>(*this);
+			const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
 			
 			std::string key = typed_param.getValueName();
 
 					// be exported as <color green="1"/>, since it was probably the intent of the user to 
 					// be specific about the RGB color values.  This also fixes an issue where we distinguish
 					// between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
-					block_t::serializeBlock(parser, name_stack, NULL);
+
+					if (typed_param.mValueAge == VALUE_AUTHORITATIVE)
+					{
+						// if the value is authoritative but the parser doesn't accept the value type
+						// go ahead and make a copy, and splat the value out to its component params
+						// and serialize those params
+						derived_t copy(typed_param);
+						copy.updateBlockFromValue(true);
+						copy.block_t::serializeBlock(parser, name_stack, NULL);
+					}
+					else
+					{
+						block_t::serializeBlock(parser, name_stack, NULL);
+					}
 				}
 			}
 		}
 		{ 
 			BaseBlock::paramChanged(changed_param, user_provided);
 			if (user_provided)
-		{
+			{
 				// a parameter changed, so our value is out of date
 				mValueAge = VALUE_NEEDS_UPDATE;
 			}
 			mValueAge = VALUE_AUTHORITATIVE;
 			mValue = val;
 			typed_param.clearValueName();
-			static_cast<derived_t*>(const_cast<self_t*>(this))->updateBlockFromValue();
+			static_cast<derived_t*>(this)->updateBlockFromValue(false);
 		}
 
 		value_assignment_t getValue() const
 		mutable bool 		mValidated; // lazy validation flag
 
 	private:
-
 		mutable T			mValue;
 		mutable EValueAge	mValueAge;
 	};

File indra/newview/app_settings/settings.xml

     <key>AFKTimeout</key>
     <map>
       <key>Comment</key>
-      <string>Time before automatically setting AFK (away from keyboard) mode (seconds, 0=never). 
-        Valid values are: 0, 120, 300, 600, 1800</string>
+            <string>
+                Time before automatically setting AFK (away from keyboard) mode (seconds, 0=never).
+                Valid values are: 0, 120, 300, 600, 1800
+</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
       <key>Value</key>
         <real>2.0</real>
     </map>
-    <key>LastInventoryInboxExpand</key>
-    <map>
-        <key>Comment</key>
-        <string>The last time the received items inbox was expanded.</string>
-        <key>Persist</key>
-        <integer>1</integer>
-        <key>Type</key>
-        <string>String</string>
-        <key>Value</key>
-        <string />
-    </map>
     <key>LCDDestination</key>
     <map>
       <key>Comment</key>
     <key>ToastButtonWidth</key>
     <map>
       <key>Comment</key>
-      <string>Default width of buttons in the toast. 
+            <string>
+                Default width of buttons in the toast.
       Notes:
       If required width will be less then this one, a button will be reshaped to default size , otherwise to required
-      Change of this parameter will affect the layout of buttons in notification toast.</string>
+                Change of this parameter will affect the layout of buttons in notification toast.
+</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
     <key>Type</key>
     <string>Boolean</string>
     <key>Value</key>
-    <string>0</string>
+      <integer>0</integer>
   </map>
     <key>PrecachingDelay</key>
     <map>
     <key>RenderPerformanceTest</key>
     <map>
       <key>Comment</key>
-      <string>Disable rendering of everything but in-world content for 
-        performance testing</string>
+            <string>
+                Disable rendering of everything but in-world content for
+                performance testing
+</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
         <integer>650</integer>
         <integer>490</integer>
         <integer>0</integer>
-      </array>    
-    </map>
-   <key>HelpFloaterOpen</key>
+        </array>
+        </map>
+    <key>HelpFloaterOpen</key>
     <map>
       <key>Comment</key>
       <string>Show Help Floater on login?</string>

File indra/newview/app_settings/settings_per_account.xml

         <key>Value</key>
             <string />
         </map>
+    <key>LastInventoryInboxExpand</key>
+       <map>
+            <key>Comment</key>
+            <string>The last time the received items inbox was expanded.</string>
+            <key>Persist</key>
+            <integer>1</integer>
+            <key>Type</key>
+            <string>String</string>
+            <key>Value</key>
+            <string />
+        </map>
     <key>LastLogoff</key>
         <map>
         <key>Comment</key>

File indra/newview/llavataractions.cpp

 	// PROFILES: open in webkit window
 	const bool show_chrome = false;
 	static LLCachedControl<LLRect> profile_rect(gSavedSettings, "WebProfileRect");
-	LLFloaterWebContent::create(url, "", agent_id.asString(), show_chrome, profile_rect);
+	LLFloaterWebContent::create(LLFloaterWebContent::Params().
+							url(url).
+							id(agent_id.asString()).
+							show_chrome(show_chrome).
+							window_class("profile").
+							preferred_media_size(profile_rect));
 }
 
 // static
 //static 
 bool LLAvatarActions::profileVisible(const LLUUID& id)
 {
-	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("web_content", id.asString()));
+	LLSD sd;
+	sd["id"] = id;
+	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("profile", sd));
 	return browser && browser->isShown();
 }
 
 //static 
 void LLAvatarActions::hideProfile(const LLUUID& id)
 {
-	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("web_content", id.asString()));
+	LLSD sd;
+	sd["id"] = id;
+	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("profile", sd));
 	if (browser)
 	{
 		browser->closeFloater();

File indra/newview/llfloaterproperties.cpp

 LLMultiProperties::LLMultiProperties()
 	: LLMultiFloater(LLSD())
 {
-	// *TODO: There should be a .xml file for this
-	const LLRect& nextrect = LLFloaterReg::getFloaterRect("properties"); // place where the next properties should show up
-	if (nextrect.getWidth() > 0)
+	// start with a small rect in the top-left corner ; will get resized
+	LLRect rect;
+	rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 20, 20);
+	setRect(rect);
+	LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("properties");
+	if (last_floater)
 	{
-		setRect(nextrect);
-	}
-	else
-	{
-		// start with a small rect in the top-left corner ; will get resized
-		LLRect rect;
-		rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 20, 20);
-		setRect(rect);
+		stackWith(*last_floater);
 	}
 	setTitle(LLTrans::getString("MultiPropertiesTitle"));
 	buildTabContainer();

File indra/newview/llfloatersearch.cpp

 		}
 
 		// create the LLSD arguments for the search floater
-		LLSD args;
-		args["category"] = category;
-		args["id"] = LLURI::unescape(search_text);
+		LLFloaterSearch::Params p;
+		p.search.category = category;
+		p.search.query = LLURI::unescape(search_text);
 
 		// open the search floater and perform the requested search
-		LLFloaterReg::showInstance("search", args);
+		LLFloaterReg::showInstance("search", p);
 		return true;
 	}
 };
 LLSearchHandler gSearchHandler;
 
-LLFloaterSearch::LLFloaterSearch(const LLSD& key) :
-	LLFloater(key),
-	LLViewerMediaObserver(),
-	mBrowser(NULL),
+LLFloaterSearch::SearchQuery::SearchQuery()
+:	category("category", ""),
+	query("query")
+{}
+
+LLFloaterSearch::LLFloaterSearch(const Params& key) :
+	LLFloaterWebContent(key),
 	mSearchGodLevel(0)
 {
 	// declare a map that transforms a category name into
 
 BOOL LLFloaterSearch::postBuild()
 {
-	mBrowser = getChild<LLMediaCtrl>("browser");
-	mBrowser->addObserver(this);
+	LLFloaterWebContent::postBuild();
+	mWebBrowser->addObserver(this);
 
 	return TRUE;
 }
 
 void LLFloaterSearch::onOpen(const LLSD& key)
 {
-	search(key);
+	Params p(key);
+	p.trusted_content = true;
+	p.allow_address_entry = false;
+
+	LLFloaterWebContent::onOpen(p);
+	search(p.search);
 }
 
 void LLFloaterSearch::onClose(bool app_quitting)
 {
+	LLFloaterWebContent::onClose(app_quitting);
 	// tear down the web view so we don't show the previous search
 	// result when the floater is opened next time
 	destroy();
 }
 
-void LLFloaterSearch::handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event)
-{
-	switch (event) 
-	{
-	case MEDIA_EVENT_NAVIGATE_BEGIN:
-		getChild<LLUICtrl>("status_text")->setValue(getString("loading_text"));