Commits

Scott Lawrence committed a546c64 Merge

merge changes for storm-1064

  • Participants
  • Parent commits c9fe42c, f024f60

Comments (0)

Files changed (545)

 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
 92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
 63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
+4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
+4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
+b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
+b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release
+92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
+f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
+f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
+4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start
 viewer-beta.build_debug_release_separately = true
 viewer-beta.build_viewer_update_version_manager = true
 
+viewer-pre-beta.viewer_channel = "Second Life Beta Viewer"
+viewer-pre-beta.login_channel = "Second Life Beta Viewer"
+viewer-pre-beta.build_debug_release_separately = true
+viewer-pre-beta.build_viewer_update_version_manager = true
+
 # ========================================
 # Viewer Release
 # ========================================
 viewer-release.build_viewer_update_version_manager = true
 viewer-release.release-viewer.jira = DRTVWR-13
 
+viewer-pre-release.viewer_channel = "Second Life Release"
+viewer-pre-release.login_channel = "Second Life Release"
+viewer-pre-release.build_debug_release_separately = true
+viewer-pre-release.build_viewer_update_version_manager = true
+#viewer-pre-release.release-viewer.jira = DRTVWR-13
+
 # ========================================
 # aimee
 # ========================================

doc/contributions.txt

 	VWR-24315
 	VWR-24317
 	VWR-24320
-    VWR-24321
+	VWR-24321
+	VWR-24337
  	VWR-24354
 	VWR-24366
 	VWR-24519
+	VWR-24520
 	SNOW-84
 	SNOW-477
 	SNOW-744
     VWR-1095
 Cron Stardust
 	VWR-10579
+	VWR-25120
 Cypren Christenson
 	STORM-417
 Dale Glass
 	STORM-1040
 	VWR-17801
 	VWR-24347
+	STORM-975
 	STORM-990
+	STORM-1020
 	STORM-1064
 Kage Pixel
 	VWR-11
 	STORM-288
 	STORM-799
 	STORM-800
+	STORM-1001
     VWR-24217
 Kunnis Basiat
 	VWR-82

indra/cmake/FindLLQtWebkit.cmake

     else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
         set(_PACKAGE_ARGS libllqtwebkit)
     endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-    if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_LESS "2.8")
+    if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_LESS "2.8.2")
       # As virtually nobody will have a pkg-config file for this, do this check always quiet.
-      # Unfortunately cmake 2.8 or higher is required for pkg_check_modules to have a 'QUIET'.
+      # Unfortunately cmake 2.8.2 or higher is required for pkg_check_modules to have a 'QUIET'.
       set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
     endif ()
     pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})

indra/linux_updater/linux_updater.cpp

 	std::vector<std::string> paths;
 	LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ','
 
+	for(std::vector<std::string>::iterator it = paths.begin(), end_it = paths.end();
+		it != end_it;
+		++it)
+	{
+		(*it) = gDirUtilp->findSkinnedFilename(*it, base_xml_name);
+	}
+
 	// suck the translation xml files into memory
 	LLXMLNodePtr root;
-	bool success = LLXMLNode::getLayeredXMLNode(base_xml_name, root, paths);
+	bool success = LLXMLNode::getLayeredXMLNode(root, paths);
 	if (!success)
 	{
 		// couldn't load string table XML

indra/llcommon/llprocesslauncher.cpp

 	char *args2 = new char[args.size() + 1];
 	strcpy(args2, args.c_str());
 
-	if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo ) )
+	if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, mWorkingDir.c_str(), &sinfo, &pinfo ) )
 	{
 		// TODO: do better than returning the OS-specific error code on failure...
 		result = GetLastError();

indra/llcommon/llversionviewer.h

 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 2;
-const S32 LL_VERSION_MINOR = 5;
-const S32 LL_VERSION_PATCH = 2;
+const S32 LL_VERSION_MINOR = 6;
+const S32 LL_VERSION_PATCH = 1;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";

indra/llmath/v3math.h

 F32	dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b
 F32	dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component
 LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
+LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
+LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
 LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
 
 inline LLVector3::LLVector3(void)
 	return project_axis * (a * project_axis);
 }
 
+inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
+{
+	return projected_vec(a, b);
+}
+
+inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)
+{
+	return a - projected_vec(a, b);
+}
+
+
 inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
 {
 	return LLVector3(

indra/llplugin/llpluginprocessparent.cpp

 void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
 {	
 	mProcess.setExecutable(launcher_filename);
+	mProcess.setWorkingDirectory(plugin_dir);
 	mPluginFile = plugin_filename;
 	mPluginDir = plugin_dir;
 	mCPUUsage = 0.0f;

indra/llprimitive/lltextureentry.cpp

 
 S32 LLTextureEntry::setMediaTexGen(U8 media)
 {
-	if (mMediaFlags != media)
-	{
-		mMediaFlags = media;
-
-		// Special code for media handling
-		if( hasMedia() && mMediaEntry == NULL)
-		{
-			mMediaEntry = new LLMediaEntry;
-		}
-        else if ( ! hasMedia() && mMediaEntry != NULL)
-        {
-            delete mMediaEntry;
-            mMediaEntry = NULL;
-        }
-
-		return TEM_CHANGE_MEDIA;
-	}
-	return TEM_CHANGE_NONE;
+	S32 result = TEM_CHANGE_NONE;
+	result |= setTexGen(media & TEM_TEX_GEN_MASK);
+	result |= setMediaFlags(media & TEM_MEDIA_MASK);
+	return result;
 }
 
 S32 LLTextureEntry::setBumpmap(U8 bump)

indra/llui/lldockcontrol.cpp

-/** 
- * @file lldockcontrol.cpp
- * @brief Creates a panel of a specific kind for a toast
- *
- * $LicenseInfo:firstyear=2000&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 "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) :
-		mDockWidget(dockWidget),
-		mDockableFloater(dockableFloater),
-		mDockTongue(dockTongue),
-		mDockTongueX(0),
-		mDockTongueY(0)
-{
-	mDockAt = dockAt;
-
-	if (dockableFloater->isDocked())
-	{
-		on();
-	}
-	else
-	{
-		off();
-	}
-
-	if (!(get_allowed_rect_callback))
-	{
-		mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
-	}
-	else
-	{
-		mGetAllowedRectCallback = get_allowed_rect_callback;
-	}
-
-	if (dockWidget != NULL) 
-	{
-		repositionDockable();
-	}
-
-	if (mDockWidget != NULL)
-	{
-		mDockWidgetVisible = isDockVisible();
-	}
-	else
-	{
-		mDockWidgetVisible = false;
-	}
-}
-
-LLDockControl::~LLDockControl()
-{
-}
-
-void LLDockControl::setDock(LLView* dockWidget)
-{
-	mDockWidget = dockWidget;
-	if (mDockWidget != NULL)
-	{
-		repositionDockable();
-		mDockWidgetVisible = isDockVisible();
-	}
-	else
-	{
-		mDockWidgetVisible = false;
-	}
-}
-
-void LLDockControl::getAllowedRect(LLRect& rect)
-{
-	rect = mDockableFloater->getRootView()->getRect();
-}
-
-void LLDockControl::repositionDockable()
-{
-	LLRect dockRect = mDockWidget->calcScreenRect();
-	LLRect rootRect;
-	mGetAllowedRectCallback(rootRect);
-
-	// recalculate dockable position if dock position changed, dock visibility changed,
-	// root view rect changed or recalculation is forced
-	if (mPrevDockRect != dockRect  || mDockWidgetVisible != isDockVisible()
-			|| mRootRect != rootRect || mRecalculateDocablePosition)
-	{
-		// undock dockable and off() if dock not visible
-		if (!isDockVisible())
-		{
-			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
-		{
-			if(mEnabled)
-			{
-				moveDockable();
-			}
-			LLDockableFloater* dockable_floater =
-					dynamic_cast<LLDockableFloater*> (mDockableFloater);
-			if(dockable_floater != NULL)
-			{
-				dockable_floater->onDockShown();
-			}
-		}
-
-		mPrevDockRect = dockRect;
-		mRootRect = rootRect;
-		mRecalculateDocablePosition = false;
-		mDockWidgetVisible = isDockVisible();
-	}
-}
-
-bool LLDockControl::isDockVisible()
-{
-	bool res = true;
-
-	if (mDockWidget != NULL)
-	{
-		//we should check all hierarchy
-		res = mDockWidget->isInVisibleChain();
-		if (res)
-		{
-			LLRect dockRect = mDockWidget->calcScreenRect();
-
-			switch (mDockAt)
-			{
-			case LEFT: // to keep compiler happy
-				break;
-			case BOTTOM:
-			case TOP:
-			{
-				// check is dock inside parent rect
-				// assume that parent for all dockable flaoters
-				// is the root view
-				LLRect dockParentRect =
-						mDockWidget->getRootView()->calcScreenRect();
-				if (dockRect.mRight <= dockParentRect.mLeft
-						|| dockRect.mLeft >= dockParentRect.mRight)
-				{
-					res = false;
-				}
-				break;
-			}
-			default:
-				break;
-			}
-		}
-	}
-
-	return res;
-}
-
-void LLDockControl::moveDockable()
-{
-	// calculate new dockable position
-	LLRect dockRect = mDockWidget->calcScreenRect();
-	LLRect rootRect;
-	mGetAllowedRectCallback(rootRect);
-
-	bool use_tongue = false;
-	LLDockableFloater* dockable_floater =
-			dynamic_cast<LLDockableFloater*> (mDockableFloater);
-	if (dockable_floater != NULL)
-	{
-		use_tongue = dockable_floater->getUseTongue();
-	}
-
-	LLRect dockableRect = mDockableFloater->calcScreenRect();
-	S32 x = 0;
-	S32 y = 0;
-	LLRect dockParentRect;
-	switch (mDockAt)
-	{
-	case LEFT:
-		x = dockRect.mLeft;
-		y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
-		// check is dockable inside root view rect
-		if (x < rootRect.mLeft)
-		{
-			x = rootRect.mLeft;
-		}
-		if (x + dockableRect.getWidth() > rootRect.mRight)
-		{
-			x = rootRect.mRight - dockableRect.getWidth();
-		}
-		
-		mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
-		
-		mDockTongueY = dockRect.mTop;
-		break;
-
-	case TOP:
-		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
-		y = dockRect.mTop + dockableRect.getHeight();
-		// unique docking used with dock tongue, so add tongue height to the Y coordinate
-		if (use_tongue)
-		{
-			y += mDockTongue->getHeight();
-
-			if ( y > rootRect.mTop)
-			{
-				y = rootRect.mTop;
-			}
-		}
-
-		// check is dockable inside root view rect
-		if (x < rootRect.mLeft)
-		{
-			x = rootRect.mLeft;
-		}
-		if (x + dockableRect.getWidth() > rootRect.mRight)
-		{
-			x = rootRect.mRight - dockableRect.getWidth();
-		}
-
-
-		// calculate dock tongue position
-		dockParentRect = mDockWidget->getParent()->calcScreenRect();
-		if (dockRect.getCenterX() < dockParentRect.mLeft)
-		{
-			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
-		}
-		else if (dockRect.getCenterX() > dockParentRect.mRight)
-		{
-			mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
-		}
-		else
-		{
-			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
-		}
-		mDockTongueY = dockRect.mTop;
-
-		break;
-	case BOTTOM:
-		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
-		y = dockRect.mBottom;
-		// unique docking used with dock tongue, so add tongue height to the Y coordinate
-		if (use_tongue)
-		{
-			y -= mDockTongue->getHeight();
-		}
-
-		// check is dockable inside root view rect
-		if (x < rootRect.mLeft)
-		{
-			x = rootRect.mLeft;
-		}
-		if (x + dockableRect.getWidth() > rootRect.mRight)
-		{
-			x = rootRect.mRight - dockableRect.getWidth();
-		}
-
-		// calculate dock tongue position
-		dockParentRect = mDockWidget->getParent()->calcScreenRect();
-		if (dockRect.getCenterX() < dockParentRect.mLeft)
-		{
-			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
-		}
-		else if (dockRect.getCenterX() > dockParentRect.mRight)
-		{
-			mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
-		}
-		else
-		{
-			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
-		}
-		mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
-
-		break;
-	}
-
-	S32 max_available_height = rootRect.getHeight() - mDockTongueY - mDockTongue->getHeight();
-
-	// A floater should be shrunk so it doesn't cover a part of its docking tongue and
-	// there is a space between a dockable floater and a control to which it is docked.
-	if (use_tongue && dockableRect.getHeight() >= max_available_height)
-	{
-		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
-		mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
-	}
-	else
-	{
-		// move dockable
-		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
-				dockableRect.getHeight());
-	}
-	LLRect localDocableParentRect;
-	mDockableFloater->getParent()->screenRectToLocal(dockableRect,
-			&localDocableParentRect);
-	mDockableFloater->setRect(localDocableParentRect);
-
-	mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
-			&mDockTongueX, &mDockTongueY);
-
-}
-
-void LLDockControl::on()
-{
-	 if (isDockVisible())
-	{
-		mEnabled = true;
-		mRecalculateDocablePosition = true;
-	}
-}
-
-void LLDockControl::off()
-{
-	mEnabled = false;
-}
-
-void LLDockControl::forceRecalculatePosition()
-{
-	mRecalculateDocablePosition = true;
-}
-
-void LLDockControl::drawToungue()
-{
-	bool use_tongue = false;
-	LLDockableFloater* dockable_floater =
-			dynamic_cast<LLDockableFloater*> (mDockableFloater);
-	if (dockable_floater != NULL)
-	{
-		use_tongue = dockable_floater->getUseTongue();
-	}
-
-	if (mEnabled && use_tongue)
-	{
-		mDockTongue->draw(mDockTongueX, mDockTongueY);
-	}
-}
-
+/** 
+ * @file lldockcontrol.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&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 "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) :
+		mDockWidget(dockWidget),
+		mDockableFloater(dockableFloater),
+		mDockTongue(dockTongue),
+		mDockTongueX(0),
+		mDockTongueY(0)
+{
+	mDockAt = dockAt;
+
+	if (dockableFloater->isDocked())
+	{
+		on();
+	}
+	else
+	{
+		off();
+	}
+
+	if (!(get_allowed_rect_callback))
+	{
+		mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
+	}
+	else
+	{
+		mGetAllowedRectCallback = get_allowed_rect_callback;
+	}
+
+	if (dockWidget != NULL) 
+	{
+		repositionDockable();
+	}
+
+	if (mDockWidget != NULL)
+	{
+		mDockWidgetVisible = isDockVisible();
+	}
+	else
+	{
+		mDockWidgetVisible = false;
+	}
+}
+
+LLDockControl::~LLDockControl()
+{
+}
+
+void LLDockControl::setDock(LLView* dockWidget)
+{
+	mDockWidget = dockWidget;
+	if (mDockWidget != NULL)
+	{
+		repositionDockable();
+		mDockWidgetVisible = isDockVisible();
+	}
+	else
+	{
+		mDockWidgetVisible = false;
+	}
+}
+
+void LLDockControl::getAllowedRect(LLRect& rect)
+{
+	rect = mDockableFloater->getRootView()->getRect();
+}
+
+void LLDockControl::repositionDockable()
+{
+	LLRect dockRect = mDockWidget->calcScreenRect();
+	LLRect rootRect;
+	mGetAllowedRectCallback(rootRect);
+
+	// recalculate dockable position if dock position changed, dock visibility changed,
+	// root view rect changed or recalculation is forced
+	if (mPrevDockRect != dockRect  || mDockWidgetVisible != isDockVisible()
+			|| mRootRect != rootRect || mRecalculateDocablePosition)
+	{
+		// undock dockable and off() if dock not visible
+		if (!isDockVisible())
+		{
+			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
+		{
+			if(mEnabled)
+			{
+				moveDockable();
+			}
+			LLDockableFloater* dockable_floater =
+					dynamic_cast<LLDockableFloater*> (mDockableFloater);
+			if(dockable_floater != NULL)
+			{
+				dockable_floater->onDockShown();
+			}
+		}
+
+		mPrevDockRect = dockRect;
+		mRootRect = rootRect;
+		mRecalculateDocablePosition = false;
+		mDockWidgetVisible = isDockVisible();
+	}
+}
+
+bool LLDockControl::isDockVisible()
+{
+	bool res = true;
+
+	if (mDockWidget != NULL)
+	{
+		//we should check all hierarchy
+		res = mDockWidget->isInVisibleChain();
+		if (res)
+		{
+			LLRect dockRect = mDockWidget->calcScreenRect();
+
+			switch (mDockAt)
+			{
+			case LEFT: // to keep compiler happy
+				break;
+			case BOTTOM:
+			case TOP:
+			{
+				// check is dock inside parent rect
+				// assume that parent for all dockable flaoters
+				// is the root view
+				LLRect dockParentRect =
+						mDockWidget->getRootView()->calcScreenRect();
+				if (dockRect.mRight <= dockParentRect.mLeft
+						|| dockRect.mLeft >= dockParentRect.mRight)
+				{
+					res = false;
+				}
+				break;
+			}
+			default:
+				break;
+			}
+		}
+	}
+
+	return res;
+}
+
+void LLDockControl::moveDockable()
+{
+	// calculate new dockable position
+	LLRect dockRect = mDockWidget->calcScreenRect();
+	LLRect rootRect;
+	mGetAllowedRectCallback(rootRect);
+
+	bool use_tongue = false;
+	LLDockableFloater* dockable_floater =
+			dynamic_cast<LLDockableFloater*> (mDockableFloater);
+	if (dockable_floater != NULL)
+	{
+		use_tongue = dockable_floater->getUseTongue();
+	}
+
+	LLRect dockableRect = mDockableFloater->calcScreenRect();
+	S32 x = 0;
+	S32 y = 0;
+	LLRect dockParentRect;
+	switch (mDockAt)
+	{
+	case LEFT:
+		x = dockRect.mLeft;
+		y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
+		// check is dockable inside root view rect
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
+		
+		mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
+		
+		mDockTongueY = dockRect.mTop;
+		break;
+
+	case TOP:
+		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+		y = dockRect.mTop + dockableRect.getHeight();
+		// unique docking used with dock tongue, so add tongue height to the Y coordinate
+		if (use_tongue)
+		{
+			y += mDockTongue->getHeight();
+
+			if ( y > rootRect.mTop)
+			{
+				y = rootRect.mTop;
+			}
+		}
+
+		// check is dockable inside root view rect
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
+
+
+		// calculate dock tongue position
+		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		if (dockRect.getCenterX() < dockParentRect.mLeft)
+		{
+			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+		}
+		else if (dockRect.getCenterX() > dockParentRect.mRight)
+		{
+			mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+		}
+		else
+		{
+			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+		}
+		mDockTongueY = dockRect.mTop;
+
+		break;
+	case BOTTOM:
+		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+		y = dockRect.mBottom;
+		// unique docking used with dock tongue, so add tongue height to the Y coordinate
+		if (use_tongue)
+		{
+			y -= mDockTongue->getHeight();
+		}
+
+		// check is dockable inside root view rect
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
+
+		// calculate dock tongue position
+		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		if (dockRect.getCenterX() < dockParentRect.mLeft)
+		{
+			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+		}
+		else if (dockRect.getCenterX() > dockParentRect.mRight)
+		{
+			mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+		}
+		else
+		{
+			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+		}
+		mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
+
+		break;
+	}
+
+	S32 max_available_height = rootRect.getHeight() - (rootRect.mBottom -  mDockTongueY) - mDockTongue->getHeight();
+
+	// A floater should be shrunk so it doesn't cover a part of its docking tongue and
+	// there is a space between a dockable floater and a control to which it is docked.
+	if (use_tongue && dockableRect.getHeight() >= max_available_height)
+	{
+		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
+		mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
+	}
+	else
+	{
+		// move dockable
+		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+				dockableRect.getHeight());
+	}
+	LLRect localDocableParentRect;
+	mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+			&localDocableParentRect);
+	mDockableFloater->setRect(localDocableParentRect);
+
+	mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+			&mDockTongueX, &mDockTongueY);
+
+}
+
+void LLDockControl::on()
+{
+	 if (isDockVisible())
+	{
+		mEnabled = true;
+		mRecalculateDocablePosition = true;
+	}
+}
+
+void LLDockControl::off()
+{
+	mEnabled = false;
+}
+
+void LLDockControl::forceRecalculatePosition()
+{
+	mRecalculateDocablePosition = true;
+}
+
+void LLDockControl::drawToungue()
+{
+	bool use_tongue = false;
+	LLDockableFloater* dockable_floater =
+			dynamic_cast<LLDockableFloater*> (mDockableFloater);
+	if (dockable_floater != NULL)
+	{
+		use_tongue = dockable_floater->getUseTongue();
+	}
+
+	if (mEnabled && use_tongue)
+	{
+		mDockTongue->draw(mDockTongueX, mDockTongueY);
+	}
+}
+

indra/llui/llfloater.cpp

 
 LLRect LLFloaterView::getSnapRect() const
 {
-	LLRect snap_rect = getRect();
-	snap_rect.mBottom += mSnapOffsetBottom;
-	snap_rect.mRight  -= mSnapOffsetRight;
+	LLRect snap_rect = getLocalRect();
+
+	LLView* snap_view = mSnapView.get();
+	if (snap_view)
+	{
+		snap_view->localRectToOtherView(snap_view->getLocalRect(), &snap_rect, this);
+	}
 
 	return snap_rect;
 }

indra/llui/llfloater.h

 	// value is not defined.
 	S32 getZOrder(LLFloater* child);
 
-	void setSnapOffsetBottom(S32 offset) { mSnapOffsetBottom = offset; }
-	void setSnapOffsetRight(S32 offset) { mSnapOffsetRight = offset; }
+	void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; }
 
 private:
+	LLHandle<LLView>	mSnapView;
 	BOOL			mFocusCycleMode;
 	S32				mSnapOffsetBottom;
 	S32				mSnapOffsetRight;

indra/llui/llnotifications.cpp

 
 bool LLNotifications::uniqueHandler(const LLSD& payload)
 {
+	std::string cmd = payload["sigtype"];
+
 	LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
 	if (pNotif && pNotif->hasUniquenessConstraints()) 
 	{
-		if (payload["sigtype"].asString() == "add")
+		if (cmd == "add")
 		{
 			// not a duplicate according to uniqueness criteria, so we keep it
 			// and store it for future uniqueness checks
 			mUniqueNotifications.insert(std::make_pair(pNotif->getName(), pNotif));
 		}
-		else if (payload["sigtype"].asString() == "delete")
+		else if (cmd == "delete")
 		{
 			mUniqueNotifications.erase(pNotif->getName());
 		}
 {
 	LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
 	
-	if (!pNotif || !pNotif->hasUniquenessConstraints())
+	std::string cmd = payload["sigtype"];
+
+	if (!pNotif || cmd != "add")
 	{
 		return false;
 	}
 
-	// checks against existing unique notifications
+	// Update the existing unique notification with the data from this particular instance...
+	// This guarantees that duplicate notifications will be collapsed to the one
+	// most recently triggered
 	for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
 		existing_it != mUniqueNotifications.end();
 		++existing_it)
 			// of this unique notification and update it
 			existing_notification->updateFrom(pNotif);
 			// then delete the new one
-			pNotif->cancel();
+			cancel(pNotif);
 		}
 	}
 
 	// usage LLStopWhenHandled combiner in LLStandardSignal
 	LLNotifications::instance().getChannel("Unique")->
         connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
-// failedUniquenessTest slot isn't necessary
-//	LLNotifications::instance().getChannel("Unique")->
-//        connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
+	LLNotifications::instance().getChannel("Unique")->
+        connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
 	LLNotifications::instance().getChannel("Ignore")->
 		connectFailedFilter(&handleIgnoredNotification);
 	LLNotifications::instance().getChannel("VisibilityRules")->
 		connectFailedFilter(&visibilityRuleMached);
 }
 
-bool LLNotifications::addTemplate(const std::string &name, 
-								  LLNotificationTemplatePtr theTemplate)
-{
-	if (mTemplates.count(name))
-	{
-		llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl;
-		return false;
-	}
-	mTemplates[name] = theTemplate;
-	return true;
-}
 
 LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name)
 {
 	}
 }
 
+void addPathIfExists(const std::string& new_path, std::vector<std::string>& paths)
+{
+	if (gDirUtilp->fileExists(new_path))
+	{
+		paths.push_back(new_path);
+	}
+}
+
 bool LLNotifications::loadTemplates()
 {
-	const std::string xml_filename = "notifications.xml";
-	std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
+	std::vector<std::string> search_paths;
+	
+	std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
+	std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
 
+	addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths);
+
+	std::string base_filename = search_paths.front();
 	LLXMLNodePtr root;
-	BOOL success  = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+	BOOL success  = LLXMLNode::getLayeredXMLNode(root, search_paths);
 	
 	if (!success || root.isNull() || !root->hasName( "notifications" ))
 	{
-		llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+		llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
 		return false;
 	}
 
 	LLNotificationTemplate::Notifications params;
 	LLXUIParser parser;
-	parser.readXUI(root, params, full_filename);
+	parser.readXUI(root, params, base_filename);
 
 	if(!params.validateBlock())
 	{
-		llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+		llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
 		return false;
 	}
 
 				replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
 			}
 		}
-		addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it)));
+		mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it));
 	}
 
 	return true;
 
 void LLNotifications::cancel(LLNotificationPtr pNotif)
 {
-	if (pNotif == NULL) return;
+	if (pNotif == NULL || pNotif->isCancelled()) return;
 
 	LLNotificationSet::iterator it=mItems.find(pNotif);
 	if (it == mItems.end())
 	for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++)
 	{
 		// An empty type/tag/name string will match any notification, so only do the comparison when the string is non-empty in the rule.
-
 		lldebugs 
 			<< "notification \"" << n->getName() << "\" " 
 			<< "testing against " << ((*it)->mVisible?"show":"hide") << " rule, "
 				// Response property is empty.  Cancel this notification.
 				lldebugs << "cancelling notification " << n->getName() << llendl;
 
-				n->cancel();
+				cancel(n);
 			}
 			else
 			{

indra/llui/llnotifications.h

 
 	friend class LLSingleton<LLNotifications>;
 public:
-	// load notification descriptions from file; 
-	// OK to call more than once because it will reload
-	bool loadTemplates();  
-	
+	// load all notification descriptions from file
+	// calling more than once will overwrite existing templates
+	// but never delete a template
+	bool loadTemplates();
+
 	// load visibility rules from file; 
 	// OK to call more than once because it will reload
 	bool loadVisibilityRules();  
 	LLNotificationChannelPtr pHistoryChannel;
 	LLNotificationChannelPtr pExpirationChannel;
 	
-	// put your template in
-	bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
 	TemplateMap mTemplates;
 
 	VisibilityRuleList mVisibilityRules;

indra/llui/llradiogroup.cpp

 		}
 		else
 		{
-			llwarns << "LLRadioGroup::setValue: value not found: " << value.asString() << llendl;
+			setSelectedIndex(-1, TRUE);
 		}
 	}
 }

indra/llui/lluictrlfactory.cpp

 bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
 {
 	LLFastTimer timer(FTM_XML_PARSE);
-	return LLXMLNode::getLayeredXMLNode(xui_filename, root, LLUI::getXUIPaths());
+	
+	std::vector<std::string> paths;
+	std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename);
+	if (!path.empty())
+	{
+		paths.push_back(path);
+	}
+
+	std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename);
+	if (!localize_path.empty() && localize_path != path)
+	{
+		paths.push_back(localize_path);
+	}
+
+	if (paths.empty())
+	{
+		// sometimes whole path is passed in as filename
+		paths.push_back(xui_filename);
+	}
+
+	return LLXMLNode::getLayeredXMLNode(root, paths);
 }
 
 
 
 std::string LLUICtrlFactory::getCurFileName() 
 { 
-	return mFileNames.empty() ? "" : gDirUtilp->getWorkingDir() + gDirUtilp->getDirDelimiter() + mFileNames.back(); 
+	return mFileNames.empty() ? "" : mFileNames.back(); 
 }
 
 

indra/llui/llview.cpp

 	}
 	else
 	{
-		llerrs << "LLView::removeChild called with non-child" << llendl;
+		llwarns << child->getName() << "is not a child of " << getName() << llendl;
 	}
 	updateBoundingRect();
 }
 	translate( left - getRect().mLeft, bottom - getRect().mBottom );
 }
 
-BOOL LLView::localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) const
+BOOL LLView::localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, const LLView* other_view) const
 {
 	const LLView* cur_view = this;
 	const LLView* root_view = NULL;
 	return FALSE;
 }
 
-BOOL LLView::localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const
+BOOL LLView::localRectToOtherView( const LLRect& local, LLRect* other, const LLView* other_view ) const
 {
 	LLRect cur_rect = local;
 	const LLView* cur_view = this;

indra/llui/llview.h

 	BOOL blockMouseEvent(S32 x, S32 y) const;
 
 	// See LLMouseHandler virtuals for screenPointToLocal and localPointToScreen
-	BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) const;
-	BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const;
+	BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, const LLView* other_view) const;
+	BOOL localRectToOtherView( const LLRect& local, LLRect* other, const LLView* other_view ) const;
 	void screenRectToLocal( const LLRect& screen, LLRect* local ) const;
 	void localRectToScreen( const LLRect& local, LLRect* screen ) const;
 	

indra/llvfs/lldir.cpp

 	{
 		if (!search_path_iter->empty())
 		{
-			std::string filename_and_path = (*search_path_iter) + getDirDelimiter() + filename;
+			std::string filename_and_path = (*search_path_iter);
+			if (!filename.empty())
+			{
+				filename_and_path += getDirDelimiter() + filename;
+			}
 			if (fileExists(filename_and_path))
 			{
 				return filename_and_path;

indra/llxml/llcontrol.cpp

 	return num_saved;
 }
 
-U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values)