dessie linden avatar dessie linden committed 3e39921 Merge

merged in 2.6.2 Beta 1 code

Comments (0)

Files changed (61)

 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
+9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
+9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
+56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
 # oz
 # ================
 
-oz_viewer-devreview.build_debug_release_separately = true
+oz-viewer-devreview.build_debug_release_separately = true
+oz_viewer-poreview.build_debug_release_separately = true
 oz-project-1.build_debug_release_separately = true
 oz-project-2.build_debug_release_separately = true
 oz-project-3.build_debug_release_separately = true

indra/integration_tests/CMakeLists.txt

 # -*- cmake -*-
 
 add_subdirectory(llui_libtest)
+add_subdirectory(llimage_libtest)

indra/integration_tests/llimage_libtest/CMakeLists.txt

+# -*- cmake -*-
+
+# Integration tests of the llimage library (JPEG2000, PNG, jpeg, etc... images reading and writing)
+
+project (llimage_libtest)
+
+include(00-Common)
+include(LLCommon)
+include(Linking)
+include(LLSharedLibs)
+include(LLImage)
+include(LLImageJ2COJ) 
+include(LLKDU)
+include(LLMath)
+include(LLVFS)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLVFS_INCLUDE_DIRS}
+    ${LLIMAGE_INCLUDE_DIRS}
+    ${LLMATH_INCLUDE_DIRS}
+    )
+
+set(llimage_libtest_SOURCE_FILES
+    llimage_libtest.cpp
+    )
+
+set(llimage_libtest_HEADER_FILES
+    CMakeLists.txt
+    llimage_libtest.h
+    )
+
+set_source_files_properties(${llimage_libtest_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES})
+
+add_executable(llimage_libtest
+    WIN32
+    MACOSX_BUNDLE
+    ${llimage_libtest_SOURCE_FILES}
+)
+
+set_target_properties(llimage_libtest
+    PROPERTIES
+    WIN32_EXECUTABLE
+    FALSE
+)
+
+# OS-specific libraries
+if (DARWIN)
+  include(CMakeFindFrameworks)
+  find_library(COREFOUNDATION_LIBRARY CoreFoundation)
+  set(OS_LIBRARIES ${COREFOUNDATION_LIBRARY})
+elseif (WINDOWS)
+#  set(OS_LIBRARIES)
+elseif (LINUX)
+#  set(OS_LIBRARIES)
+else (DARWIN)
+  message(FATAL_ERROR "Unknown platform")
+endif (DARWIN)
+
+# Libraries on which this application depends on
+# Sort by high-level to low-level
+target_link_libraries(llimage_libtest
+	${LLCOMMON_LIBRARIES}
+	${LLVFS_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLKDU_LIBRARIES}
+    ${KDU_LIBRARY}
+    ${LLIMAGEJ2COJ_LIBRARIES}
+    ${OS_LIBRARIES}
+    )
+	
+if (DARWIN)
+  # Path inside the app bundle where we'll need to copy libraries
+  set(LLIMAGE_LIBTEST_DESTINATION_DIR
+    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llimage_libtest.app/Contents/Resources
+  )
+  # Create the Contents/Resources directory
+  add_custom_command(
+    TARGET llimage_libtest POST_BUILD
+    COMMAND ${CMAKE_COMMAND}
+    ARGS
+      -E
+      make_directory
+      ${LLIMAGE_LIBTEST_DESTINATION_DIR}
+    COMMENT "Creating Resources directory in app bundle."
+  ) 
+else (DARWIN)
+  set(LLIMAGE_LIBTEST_DESTINATION_DIR
+    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+  )
+endif (DARWIN)
+
+get_target_property(BUILT_LLCOMMON llcommon LOCATION)
+add_custom_command(TARGET llimage_libtest POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON}  ${LLIMAGE_LIBTEST_DESTINATION_DIR}
+  DEPENDS ${BUILT_LLCOMMON}
+)
+
+if (DARWIN)
+  # Copy the required libraries to the package app
+  add_custom_command(TARGET llimage_libtest POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libapr-1.0.3.7.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
+    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libapr-1.0.3.7.dylib
+  )
+ add_custom_command(TARGET llimage_libtest POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libaprutil-1.0.3.8.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
+    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libaprutil-1.0.3.8.dylib
+  )
+  add_custom_command(TARGET llimage_libtest POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
+    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexception_handler.dylib
+  )
+  add_custom_command(TARGET llimage_libtest POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexpat.0.5.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
+    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexpat.0.5.0.dylib
+  )
+endif (DARWIN)
+
+if (WINDOWS)
+  # Check indra/test_apps/llplugintest/CMakeLists.txt for an example of what to copy over for Windows and how
+endif (WINDOWS)
+
+# Ensure people working on the viewer don't break this library
+# *NOTE: This could be removed, or only built by TeamCity, if the build
+# and link times become too long.
+add_dependencies(viewer llimage_libtest)
+
+ll_deploy_sharedlibs_command(llimage_libtest) 

indra/integration_tests/llimage_libtest/llimage_libtest.cpp

+/** 
+ * @file llimage_libtest.cpp
+ * @author Merov Linden
+ * @brief Integration test for the llimage library
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 "llpointer.h"
+#include "lltimer.h"
+
+#include "llimage_libtest.h"
+
+// Linden library includes
+#include "llimage.h"
+#include "llimagejpeg.h"
+#include "llimagepng.h"
+#include "llimagebmp.h"
+#include "llimagetga.h"
+#include "llimagej2c.h"
+#include "lldir.h"
+
+// system libraries
+#include <iostream>
+
+// doc string provided when invoking the program with --help 
+static const char USAGE[] = "\n"
+"usage:\tllimage_libtest [options]\n"
+"\n"
+" -h, --help\n"
+"        Print this help\n"
+" -i, --input <file1 .. file2>\n"
+"        List of image files to load and convert. Patterns with wild cards can be used.\n"
+" -o, --output <file1 .. file2> OR <type>\n"
+"        List of image files to create (assumes same order as for input files)\n"
+"        OR 3 letters file type extension to convert each input file into.\n"
+" -log, --logmetrics <metric>\n"
+"        Log performance data for <metric>. Results in <metric>.slp\n"
+"        Note: so far, only ImageCompressionTester has been tested.\n"
+" -r, --analyzeperformance\n"
+"        Create a report comparing <metric>_baseline.slp with current <metric>.slp\n"
+"        Results in <metric>_report.csv"
+" -s, --image-stats\n"
+"        Output stats for each input and output image.\n"
+"\n";
+
+// true when all image loading is done. Used by metric logging thread to know when to stop the thread.
+static bool sAllDone = false;
+
+// Create an empty formatted image instance of the correct type from the filename
+LLPointer<LLImageFormatted> create_image(const std::string &filename)
+{
+	std::string exten = gDirUtilp->getExtension(filename);
+	U32 codec = LLImageBase::getCodecFromExtension(exten);
+	
+	LLPointer<LLImageFormatted> image;
+	switch (codec)
+	{
+		case IMG_CODEC_BMP:
+			image = new LLImageBMP();
+			break;
+		case IMG_CODEC_TGA:
+			image = new LLImageTGA();
+			break;
+		case IMG_CODEC_JPEG:
+			image = new LLImageJPEG();
+			break;
+		case IMG_CODEC_J2C:
+			image = new LLImageJ2C();
+			break;
+		case IMG_CODEC_PNG:
+			image = new LLImagePNG();
+			break;
+		default:
+			return NULL;
+	}
+	
+	return image;
+}
+
+void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &filename)
+{
+	// Print out some statistical data on the image
+	std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl;
+
+	std::cout << "    with : " << (int)(image->getWidth())       << ", height : " << (int)(image->getHeight())       << std::endl;
+	std::cout << "    comp : " << (int)(image->getComponents())  << ", levels : " << (int)(image->getDiscardLevel()) << std::endl;
+	std::cout << "    head : " << (int)(image->calcHeaderSize()) << ",   data : " << (int)(image->getDataSize())     << std::endl;
+
+	return;
+}
+
+// Load an image from file and return a raw (decompressed) instance of its data
+LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_stats)
+{
+	LLPointer<LLImageFormatted> image = create_image(src_filename);
+
+	if (!image->load(src_filename))
+	{
+		return NULL;
+	}
+	
+	if(	(image->getComponents() != 3) && (image->getComponents() != 4) )
+	{
+		std::cout << "Image files with less than 3 or more than 4 components are not supported\n";
+		return NULL;
+	}
+	
+	if (output_stats)
+	{
+		output_image_stats(image, src_filename);
+	}
+	
+	LLPointer<LLImageRaw> raw_image = new LLImageRaw;
+	if (!image->decode(raw_image, 0.0f))
+	{
+		return NULL;
+	}
+	
+	return raw_image;
+}
+
+// Save a raw image instance into a file
+bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, bool output_stats)
+{
+	LLPointer<LLImageFormatted> image = create_image(dest_filename);
+	
+	if (!image->encode(raw_image, 0.0f))
+	{
+		return false;
+	}
+	
+	if (output_stats)
+	{
+		output_image_stats(image, dest_filename);
+	}
+
+	return image->save(dest_filename);
+}
+
+void store_input_file(std::list<std::string> &input_filenames, const std::string &path)
+{
+	// Break the incoming path in its components
+	std::string dir = gDirUtilp->getDirName(path);
+	std::string name = gDirUtilp->getBaseFileName(path);
+	std::string exten = gDirUtilp->getExtension(path);
+
+	// std::cout << "store_input_file : " << path << ", dir : " << dir << ", name : " << name << ", exten : " << exten << std::endl;
+	
+	// If extension is not an image type or "*", exit
+	// Note: we don't support complex patterns for the extension like "j??"
+	// Note: on most shells, the pattern expansion is done by the shell so that pattern matching limitation is actually not a problem
+	if ((exten.compare("*") != 0) && (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID))
+	{
+		return;
+	}
+
+	if ((name.find('*') != -1) || ((name.find('?') != -1)))
+	{
+		// 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))
+		{
+			std::string file_name = dir + gDirUtilp->getDirDelimiter() + next_name;
+			input_filenames.push_back(file_name);
+		}
+	}
+	else
+	{
+		// Verify that the file does exist before storing 
+		if (gDirUtilp->fileExists(path))
+		{
+			input_filenames.push_back(path);
+		}
+		else
+		{
+			std::cout << "store_input_file : the file " << path << " could not be found" << std::endl;
+		}
+	}	
+}
+
+void store_output_file(std::list<std::string> &output_filenames, std::list<std::string> &input_filenames, const std::string &path)
+{
+	// Break the incoming path in its components
+	std::string dir = gDirUtilp->getDirName(path);
+	std::string name = gDirUtilp->getBaseFileName(path);
+	std::string exten = gDirUtilp->getExtension(path);
+	
+	// std::cout << "store_output_file : " << path << ", dir : " << dir << ", name : " << name << ", exten : " << exten << std::endl;
+	
+	if (dir.empty() && exten.empty())
+	{
+		// If dir and exten are empty, we interpret the name as a file extension type name and will iterate through input list to populate the output list
+		exten = name;
+		// Make sure the extension is an image type
+		if (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID)
+		{
+			return;
+		}
+		std::string delim = gDirUtilp->getDirDelimiter();
+		std::list<std::string>::iterator in_file  = input_filenames.begin();
+		std::list<std::string>::iterator end = input_filenames.end();
+		for (; in_file != end; ++in_file)
+		{
+			dir = gDirUtilp->getDirName(*in_file);
+			name = gDirUtilp->getBaseFileName(*in_file,true);
+			std::string file_name;
+			if (!dir.empty())
+			{
+				file_name = dir + delim + name + "." + exten;
+			}
+			else
+			{
+				file_name = name + "." + exten;
+			}
+			output_filenames.push_back(file_name);
+		}
+	}
+	else
+	{
+		// Make sure the extension is an image type
+		if (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID)
+		{
+			return;
+		}
+		// Store the path
+		output_filenames.push_back(path);
+	}
+}
+
+// Holds the metric gathering output in a thread safe way
+class LogThread : public LLThread
+{
+public:
+	std::string mFile;
+
+	LogThread(std::string& test_name) : LLThread("llimage_libtest log")
+	{
+		std::string file_name = test_name + std::string(".slp");
+		mFile = file_name;
+	}
+		
+	void run()
+	{
+		std::ofstream os(mFile.c_str());
+			
+		while (!sAllDone)
+		{
+			LLFastTimer::writeLog(os);
+			os.flush();
+			ms_sleep(32);
+		}
+		LLFastTimer::writeLog(os);
+		os.flush();
+		os.close();
+	}		
+};
+
+int main(int argc, char** argv)
+{
+	// List of input and output files
+	std::list<std::string> input_filenames;
+	std::list<std::string> output_filenames;
+	bool analyze_performance = false;
+	bool image_stats = false;
+
+	// Init whatever is necessary
+	ll_init_apr();
+	LLImage::initClass();
+	LogThread* fast_timer_log_thread = NULL;	// For performance and metric gathering
+
+	// Analyze command line arguments
+	for (int arg = 1; arg < argc; ++arg)
+	{
+		if (!strcmp(argv[arg], "--help") || !strcmp(argv[arg], "-h"))
+		{
+            // Send the usage to standard out
+            std::cout << USAGE << std::endl;
+			return 0;
+		}
+		else if ((!strcmp(argv[arg], "--input") || !strcmp(argv[arg], "-i")) && arg < argc-1)
+		{
+			std::string file_name = argv[arg+1];
+			while (file_name[0] != '-')		// if arg starts with '-', we consider it's not a file name but some other argument
+			{
+				// std::cout << "input file name : " << file_name << std::endl;				
+				store_input_file(input_filenames, file_name);
+				arg += 1;					// Skip that arg now we know it's a file name
+				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
+					break;
+				file_name = argv[arg+1];	// Next argument and loop over
+			}
+		}
+		else if ((!strcmp(argv[arg], "--output") || !strcmp(argv[arg], "-o")) && arg < argc-1)
+		{
+			std::string file_name = argv[arg+1];
+			while (file_name[0] != '-')		// if arg starts with '-', we consider it's not a file name but some other argument
+			{
+				// std::cout << "output file name : " << file_name << std::endl;				
+				store_output_file(output_filenames, input_filenames, file_name);
+				arg += 1;					// Skip that arg now we know it's a file name
+				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
+					break;
+				file_name = argv[arg+1];	// Next argument and loop over
+			}
+		}
+		else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log"))
+		{
+			// '--logmetrics' needs to be specified with a named test metric argument
+			// Note: for the moment, only ImageCompressionTester has been tested
+			std::string test_name;
+			if ((arg + 1) < argc)
+			{
+				test_name = argv[arg+1];
+			}
+			if (((arg + 1) >= argc) || (test_name[0] == '-'))
+			{
+				// We don't have an argument left in the arg list or the next argument is another option
+				std::cout << "No --logmetrics argument given, no perf data will be gathered" << std::endl;
+			}
+			else
+			{
+				LLFastTimer::sMetricLog = TRUE;
+				LLFastTimer::sLogName = test_name;
+				arg += 1;					// Skip that arg now we know it's a valid test name
+				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
+					break;
+			}
+		}
+		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-r"))
+		{
+			analyze_performance = true;
+		}
+		else if (!strcmp(argv[arg], "--image-stats") || !strcmp(argv[arg], "-s"))
+		{
+			image_stats = true;
+		}
+	}
+		
+	// Check arguments consistency. Exit with proper message if inconsistent.
+	if (input_filenames.size() == 0)
+	{
+		std::cout << "No input file, nothing to do -> exit" << std::endl;
+		return 0;
+	}
+	if (analyze_performance && !LLFastTimer::sMetricLog)
+	{
+		std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -r) -> exit" << std::endl;
+		return 0;
+	}
+	
+
+	// Create the logging thread if required
+	if (LLFastTimer::sMetricLog)
+	{
+		LLFastTimer::sLogLock = new LLMutex(NULL);
+		fast_timer_log_thread = new LogThread(LLFastTimer::sLogName);
+		fast_timer_log_thread->start();
+	}
+	
+	// Perform action on each input file
+	std::list<std::string>::iterator in_file  = input_filenames.begin();
+	std::list<std::string>::iterator out_file = output_filenames.begin();
+	std::list<std::string>::iterator in_end = input_filenames.end();
+	std::list<std::string>::iterator out_end = output_filenames.end();
+	for (; in_file != in_end; ++in_file)
+	{
+		// Load file
+		LLPointer<LLImageRaw> raw_image = load_image(*in_file, image_stats);
+		if (!raw_image)
+		{
+			std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
+			continue;
+		}
+	
+		// Save file
+		if (out_file != out_end)
+		{
+			if (!save_image(*out_file, raw_image, image_stats))
+			{
+				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;
+			}
+			else
+			{
+				std::cout << *in_file << " -> " << *out_file << std::endl;
+			}
+			++out_file;
+		}
+	}
+
+	// Stop the perf gathering system if needed
+	if (LLFastTimer::sMetricLog)
+	{
+		LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName);
+		sAllDone = true;
+	}
+	
+	// Output perf data if requested by user
+	if (analyze_performance)
+	{
+		std::cout << "Analyzing performance" << std::endl;
+		
+		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
+		std::string current_name  = LLFastTimer::sLogName + ".slp"; 
+		std::string report_name   = LLFastTimer::sLogName + "_report.csv";
+		
+		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name);
+	}
+	
+	// Cleanup and exit
+	LLImage::cleanupClass();
+	if (fast_timer_log_thread)
+	{
+		fast_timer_log_thread->shutdown();
+	}
+	
+	return 0;
+}

indra/integration_tests/llimage_libtest/llimage_libtest.h

+/** 
+ * @file llimage_libtest.h
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 LLIMAGE_LIBTEST_H
+#define LLIMAGE_LIBTEST_H
+
+
+#endif

indra/llcommon/llmetricperformancetester.cpp

 	sTesterMap.insert(std::make_pair(name, tester));
 	return TRUE;
 }
-	
+
+/*static*/ 
+void LLMetricPerformanceTesterBasic::deleteTester(std::string name)
+{
+	name_tester_map_t::iterator tester = sTesterMap.find(name);
+	if (tester != sTesterMap.end())
+	{
+		delete tester->second;
+		sTesterMap.erase(tester);
+	}
+}
+
 /*static*/ 
 LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name) 
 {
 	return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));
 }
 
+/*static*/ 
+LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& is)
+{
+	LLSD ret;
+	LLSD cur;
 	
+	while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+	{
+		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
+		{
+			std::string label = iter->first;
+			
+			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ;
+			if(tester)
+			{
+				ret[label]["Name"] = iter->second["Name"] ;
+				
+				S32 num_of_metrics = tester->getNumberOfMetrics() ;
+				for(S32 index = 0 ; index < num_of_metrics ; index++)
+				{
+					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ;
+				}
+			}
+		}
+	}
+	
+	return ret;
+}
+
+/*static*/ 
+void LLMetricPerformanceTesterBasic::doAnalysisMetrics(std::string baseline, std::string target, std::string output)
+{
+	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters())
+	{
+		return ;
+	}
+	
+	// Open baseline and current target, exit if one is inexistent
+	std::ifstream base_is(baseline.c_str());
+	std::ifstream target_is(target.c_str());
+	if (!base_is.is_open() || !target_is.is_open())
+	{
+		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl;
+		base_is.close();
+		target_is.close();
+		return;
+	}
+	
+	//analyze baseline
+	LLSD base = analyzeMetricPerformanceLog(base_is);
+	base_is.close();
+	
+	//analyze current
+	LLSD current = analyzeMetricPerformanceLog(target_is);
+	target_is.close();
+	
+	//output comparision
+	std::ofstream os(output.c_str());
+	
+	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n"; 
+	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ; 
+		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter)
+	{
+		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	
+		tester->analyzePerformance(&os, &base, &current) ;
+	}
+	
+	os.flush();
+	os.close();
+}
+
+
 //----------------------------------------------------------------------------------------------
 // LLMetricPerformanceTesterBasic : Tester instance methods
 //----------------------------------------------------------------------------------------------

indra/llcommon/llmetricperformancetester.h

 	 */
 	virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ;
 
+	static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ;
+
 	/**
 	 * @return Returns the number of the test metrics in this tester instance.
 	 */
 private:
 	void preOutputTestResults(LLSD* sd) ;
 	void postOutputTestResults(LLSD* sd) ;
+	static LLSD analyzeMetricPerformanceLog(std::istream& is) ;
 
 	std::string mName ;							// Name of this tester instance
 	S32 mCount ;								// Current record count
 	static LLMetricPerformanceTesterBasic* getTester(std::string name) ;
 	
 	/**
+	 * @return Delete the named tester from the list 
+	 * @param[in] name - Name of the tester instance to delete.
+	 */
+	static void deleteTester(std::string name);
+
+	/**
 	 * @return Returns TRUE if that metric *or* the default catch all metric has been requested to be logged
 	 * @param[in] name - Name of the tester queried.
 	 */

indra/llcommon/llversionviewer.h

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

indra/llimage/llimage.h

 	// subclasses must return a prefered file extension (lowercase without a leading dot)
 	virtual std::string getExtension() = 0;
 	// calcHeaderSize() returns the maximum size of header;
-	//   0 indicates we don't know have a header and have to lead the entire file
+	//   0 indicates we don't have a header and have to read the entire file
 	virtual S32 calcHeaderSize() { return 0; };
 	// calcDataSize() returns how many bytes to read to load discard_level (including header)
 	virtual S32 calcDataSize(S32 discard_level);
 	// calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes
 	virtual S32 calcDiscardLevelBytes(S32 bytes);
-	// getRawDiscardLevel()by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
+	// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
 	virtual S8  getRawDiscardLevel() { return mDiscardLevel; }
 	
 	BOOL load(const std::string& filename);

indra/llimage/llimagej2c.cpp

 
 LLImageCompressionTester::~LLImageCompressionTester()
 {
+	outputTestResults();
 	LLImageJ2C::sTesterp = NULL;
 }
 

indra/newview/llchathistory.cpp

 			if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
 			{
 				// for object IMs, create a secondlife:///app/objectim SLapp
-				std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString();
-				url += "?name=" + chat.mFromName;
-				url += "&owner=" + chat.mOwnerID.asString();
-
-				std::string slurl = args["slurl"].asString();
-				if (slurl.empty())
-				{
-				    LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent);
-				    if(region)
-				      {
-					LLSLURL region_slurl(region->getName(), chat.mPosAgent);
-					slurl = region_slurl.getLocationString();
-				      }
-				}
-				url += "&slurl=" + LLURI::escape(slurl);
+				std::string url = LLViewerChat::getSenderSLURL(chat, args);
 
 				// set the link for the object name to be the objectim SLapp
 				// (don't let object names with hyperlinks override our objectim Url)

indra/newview/llchatitemscontainerctrl.cpp

 		{
 			LLStyle::Params style_params_name;
 
-			std::string href;
-
-			if (mSourceType == CHAT_SOURCE_AGENT)
-			{
-				href = LLSLURL("agent", mFromID, "about").getSLURLString();
-			}
-			else
-			{
-				href = LLSLURL("object", mFromID, "inspect").getSLURLString();
-			}
-
 			LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 			style_params_name.color(user_name_color);
 
 			style_params_name.font.name(font_name);
 			style_params_name.font.size(font_style_size);
 
-			style_params_name.link_href = href;
+			style_params_name.link_href = notification["sender_slurl"].asString();
 			style_params_name.is_link = true;
 
 			msg_text->appendText(str_sender, FALSE, style_params_name);

indra/newview/llexternaleditor.cpp

 #include "llviewerprecompiledheaders.h"
 #include "llexternaleditor.h"
 
+#include "lltrans.h"
 #include "llui.h"
 
 // static
 // static
 const std::string LLExternalEditor::sSetting = "ExternalEditor";
 
-bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& override)
+LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env_var, const std::string& override)
 {
 	std::string cmd = findCommand(env_var, override);
 	if (cmd.empty())
 	{
-		llwarns << "Empty editor command" << llendl;
-		return false;
+		llwarns << "Editor command is empty or not set" << llendl;
+		return EC_NOT_SPECIFIED;
 	}
 
 	// Add the filename marker if missing.
 	if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s)
 	{
 		llwarns << "Error parsing editor command" << llendl;
-		return false;
+		return EC_PARSE_ERROR;
 	}
 
 	// Check executable for existence.
 	if (!LLFile::isfile(bin_path))
 	{
 		llwarns << "Editor binary [" << bin_path << "] not found" << llendl;
-		return false;
+		return EC_BINARY_NOT_FOUND;
 	}
 
 	// Save command.
 	}
 	llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl;
 
-	return true;
+	return EC_SUCCESS;
 }
 
-bool LLExternalEditor::run(const std::string& file_path)
+LLExternalEditor::EErrorCode LLExternalEditor::run(const std::string& file_path)
 {
 	std::string args = mArgs;
 	if (mProcess.getExecutable().empty() || args.empty())
 	{
 		llwarns << "Editor command not set" << llendl;
-		return false;
+		return EC_NOT_SPECIFIED;
 	}
 
 	// Substitute the filename marker in the command with the actual passed file name.
 		mProcess.orphan();
 	}
 
-	return result == 0;
+	return result == 0 ? EC_SUCCESS : EC_FAILED_TO_RUN;
+}
+
+// static
+std::string LLExternalEditor::getErrorMessage(EErrorCode code)
+{
+	switch (code)
+	{
+	case EC_SUCCESS: 			return LLTrans::getString("ok");
+	case EC_NOT_SPECIFIED: 		return LLTrans::getString("ExternalEditorNotSet");
+	case EC_PARSE_ERROR:		return LLTrans::getString("ExternalEditorCommandParseError");
+	case EC_BINARY_NOT_FOUND:	return LLTrans::getString("ExternalEditorNotFound");
+	case EC_FAILED_TO_RUN:		return LLTrans::getString("ExternalEditorFailedToRun");
+	}
+
+	return LLTrans::getString("Unknown");
 }
 
 // static

indra/newview/llexternaleditor.h

 
 public:
 
+	typedef enum e_error_code {
+		EC_SUCCESS,				/// No error.
+		EC_NOT_SPECIFIED,		/// Editor path not specified.
+		EC_PARSE_ERROR,			/// Editor command parsing error.
+		EC_BINARY_NOT_FOUND,	/// Could find the editor binary (missing or not quoted).
+		EC_FAILED_TO_RUN,		/// Could not execute the editor binary.
+	} EErrorCode;
+
 	/**
 	 * Set editor command.
 	 *
 	 * First tries the override, then a predefined setting (sSetting),
 	 * then the environment variable.
 	 *
-	 * @return Command if found, empty string otherwise.
+	 * @return EC_SUCCESS if command is valid and refers to an existing executable,
+	 *         EC_NOT_SPECIFIED or EC_FAILED_TO_RUNan on error.
 	 *
 	 * @see sSetting
 	 */
-	bool setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null);
+	EErrorCode setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null);
 
 	/**
 	 * Run the editor with the given file.
 	 *
 	 * @param file_path File to edit.
-	 * @return true on success, false on error.
+	 * @return EC_SUCCESS on success, error code on error.
 	 */
-	bool run(const std::string& file_path);
+	EErrorCode run(const std::string& file_path);
+
+	/**
+	 * Get a meaningful error message for the given status code.
+	 */
+	static std::string getErrorMessage(EErrorCode code);
 
 private:
 

indra/newview/llfasttimerview.cpp

 	os.close();
 }
 
-//-------------------------
-//static
-LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is)
-{
-	LLSD ret;
-	LLSD cur;
-
-	while (!is.eof() && LLSDSerialize::fromXML(cur, is))
-	{
-		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
-		{
-			std::string label = iter->first;
-
-			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ;
-			if(tester)
-			{
-				ret[label]["Name"] = iter->second["Name"] ;
-
-				S32 num_of_metrics = tester->getNumberOfMetrics() ;
-				for(S32 index = 0 ; index < num_of_metrics ; index++)
-				{
-					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ;
-				}
-			}
-		}
-	}
-		
-	return ret;
-}
-
 //static
 void LLFastTimerView::outputAllMetrics()
 {
 }
 
 //static
-void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target, std::string output)
-{
-	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters())
-	{
-		return ;
-	}
-
-	// Open baseline and current target, exit if one is inexistent
-	std::ifstream base_is(baseline.c_str());
-	std::ifstream target_is(target.c_str());
-	if (!base_is.is_open() || !target_is.is_open())
-	{
-		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl;
-		base_is.close();
-		target_is.close();
-		return;
-	}
-
-	//analyze baseline
-	LLSD base = analyzeMetricPerformanceLog(base_is);
-	base_is.close();
-
-	//analyze current
-	LLSD current = analyzeMetricPerformanceLog(target_is);
-	target_is.close();
-
-	//output comparision
-	std::ofstream os(output.c_str());
-	
-	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n"; 
-	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ; 
-		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter)
-	{
-		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	
-		tester->analyzePerformance(&os, &base, &current) ;
-	}
-	
-	os.flush();
-	os.close();
-}
-
-//static
 void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)
 {
 	if(LLFastTimer::sLog)
 
 	if(LLFastTimer::sMetricLog)
 	{
-		doAnalysisMetrics(baseline, target, output) ;
+		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;
 		return ;
 	}
 }

indra/newview/llfasttimerview.h

 
 private:
 	static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ;
-	static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ;
-	static LLSD analyzeMetricPerformanceLog(std::istream& is) ;
 	static LLSD analyzePerformanceLogDefault(std::istream& is) ;
 
 public:

indra/newview/llfloatertopobjects.cpp

 			have_extended_data = true;
 			msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
 			msg->getF32("DataExtended", "MonoScore", mono_score, block);
-			msg->getS32(_PREHASH_ReportData,"PublicURLs",public_urls,block);
+			msg->getS32("DataExtended", "PublicURLs", public_urls, block);
 		}
 
 		LLSD element;

indra/newview/llfloateruipreview.cpp

 			cmd_override = bin + " " + args;
 		}
 	}
-	if (!mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override))
+
+	LLExternalEditor::EErrorCode status = mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override);
+	if (status != LLExternalEditor::EC_SUCCESS)
 	{
-		std::string warning = "Select an editor by setting the environment variable LL_XUI_EDITOR "
-			"or the ExternalEditor setting or specifying its path in the \"Editor Path\" field.";
+		std::string warning;
+
+		if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
+		{
+			warning = getString("ExternalEditorNotSet");
+		}
+		else
+		{
+			warning = LLExternalEditor::getErrorMessage(status);
+		}
+
 		popupAndPrintWarning(warning);
 		return;
 	}
 
 	// Run the editor.
-	if (!mExternalEditor.run(file_path))
+	if (mExternalEditor.run(file_path) != LLExternalEditor::EC_SUCCESS)
 	{
-		popupAndPrintWarning("Failed to run editor");
+		popupAndPrintWarning(LLExternalEditor::getErrorMessage(status));
 		return;
 	}
 }

indra/newview/llnearbychathandler.cpp

 	}
 	*/
 
+	// Add a nearby chat toast.
 	LLUUID id;
 	id.generate();
 
 		notification["text_color"] = r_color_name;
 		notification["color_alpha"] = r_color_alpha;
 		notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
+
+		// Pass sender info so that it can be rendered properly (STORM-1021).
+		notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
+
 		channel->addNotification(notification);	
 	}
 

indra/newview/llpreviewscript.cpp

 	// Open it in external editor.
 	{
 		LLExternalEditor ed;
+		LLExternalEditor::EErrorCode status;
+		std::string msg;
 
-		if (!ed.setCommand("LL_SCRIPT_EDITOR"))
+		status = ed.setCommand("LL_SCRIPT_EDITOR");
+		if (status != LLExternalEditor::EC_SUCCESS)
 		{
-			std::string msg = "Select an editor by setting the environment variable LL_SCRIPT_EDITOR "
-				"or the ExternalEditor setting"; // *TODO: localize
+			if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
+			{
+				msg = getString("external_editor_not_set");
+			}
+			else
+			{
+				msg = LLExternalEditor::getErrorMessage(status);
+			}
+
 			LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
 			return;
 		}
 
-		ed.run(filename);
+		status = ed.run(filename);
+		if (status != LLExternalEditor::EC_SUCCESS)
+		{
+			msg = LLExternalEditor::getErrorMessage(status);
+			LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+		}
 	}
 }
 

indra/newview/llsidetray.cpp

 		LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab_name);
 		if (!floater_tab) return NULL;
 
-		floater_tab->openFloater(panel_name);
+		floater_tab->openFloater(tab_name);
 	}
 
 	LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());

indra/newview/llviewerchat.cpp

 #include "llagent.h" 	// gAgent		
 #include "lluicolortable.h"
 #include "llviewercontrol.h" // gSavedSettings
+#include "llviewerregion.h"
+#include "llworld.h"
 #include "llinstantmessage.h" //SYSTEM_FROM
 
 // LLViewerChat
 
 }
 
+//static
+std::string LLViewerChat::getSenderSLURL(const LLChat& chat, const LLSD& args)
+{
+	switch (chat.mSourceType)
+	{
+	case CHAT_SOURCE_AGENT:
+		return LLSLURL("agent", chat.mFromID, "about").getSLURLString();
+
+	case CHAT_SOURCE_OBJECT:
+		return getObjectImSLURL(chat, args);
+
+	default:
+		llwarns << "Getting SLURL for an unsupported sender type: " << chat.mSourceType << llendl;
+	}
+
+	return LLStringUtil::null;
+}
+
+//static
+std::string LLViewerChat::getObjectImSLURL(const LLChat& chat, const LLSD& args)
+{
+	std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString();
+	url += "?name=" + chat.mFromName;
+	url += "&owner=" + chat.mOwnerID.asString();
+
+	std::string slurl = args["slurl"].asString();
+	if (slurl.empty())
+	{
+		LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent);
+		if(region)
+		{
+			LLSLURL region_slurl(region->getName(), chat.mPosAgent);
+			slurl = region_slurl.getLocationString();
+		}
+	}
+
+	url += "&slurl=" + LLURI::escape(slurl);
+
+	return url;
+}

indra/newview/llviewerchat.h

 	static LLFontGL* getChatFont();
 	static S32 getChatFontSize();
 	static void formatChatMsg(const LLChat& chat, std::string& formated_msg);
+	static std::string getSenderSLURL(const LLChat& chat, const LLSD& args);
+
+private:
+	static std::string getObjectImSLURL(const LLChat& chat, const LLSD& args);
 
 };
 

indra/newview/skins/default/xui/en/floater_ui_preview.xml

  title="XUI PREVIEW TOOL"
  translate="false"
  width="750">
+    <string name="ExternalEditorNotSet">
+Select an editor by setting the environment variable LL_XUI_EDITOR
+or the ExternalEditor setting
+or specifying its path in the "Editor Path" field.</string>
     <panel
      bottom="640"
      follows="left|top|right|bottom"

indra/newview/skins/default/xui/en/menu_attachment_self.xml

      function="Self.EnableStandUp" />
   </menu_item_call>
   <menu_item_call
-  label="Change Outfit"
+  label="My Appearance"
   name="Change Outfit">
     <menu_item_call.on_click
      function="CustomizeAvatar" />

indra/newview/skins/default/xui/en/menu_avatar_self.xml

         </menu_item_call>
     </context_menu>
      <menu_item_call
-     label="Change Outfit"
+     label="My Appearance"
      layout="topleft"
      name="Chenge Outfit">
         <menu_item_call.on_click

indra/newview/skins/default/xui/en/menu_viewer.xml

              parameter="agent" />
         </menu_item_call>
         <menu_item_call
-         label="Change Outfit"
+         label="My Appearance"
          name="ChangeOutfit">
             <menu_item_call.on_click
              function="CustomizeAvatar" />

indra/newview/skins/default/xui/en/notifications.xml

 
   <notification
    icon="alertmodal.tga"
-   name="AddClassified"
-   type="alertmodal">
-Classified ads appear in the &apos;Classified&apos; section of the Search directory and on [http://secondlife.com/community/classifieds secondlife.com] for one week.
-Fill out your ad, then click &apos;Publish...&apos; to add it to the directory.
-You&apos;ll be asked for a price to pay when clicking Publish.
-Paying more makes your ad appear higher in the list, and also appear higher when people search for keywords.
-    <tag>confirm</tag>
-    <usetemplate
-     ignoretext="How to create a new Classified ad"
-     name="okcancelignore"
-     notext="Cancel"
-     yestext="OK"/>
-  </notification>
-
-  <notification
-   icon="alertmodal.tga"
    name="DeleteClassified"
    type="alertmodal">
 Delete classified &apos;[NAME]&apos;?

indra/newview/skins/default/xui/en/panel_script_ed.xml

      name="Title">
         Script: [NAME]
     </panel.string>
+    <panel.string
+     name="external_editor_not_set">
+        Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
+    </panel.string>
     <menu_bar
      bg_visible="false"
      follows="left|top"

indra/newview/skins/default/xui/en/strings.xml

   <string name="DeleteItem">Delete selected item?</string>
 
   <string name="EmptyOutfitText">There are no items in this outfit</string>
+ 
+ <!-- External editor status codes -->
+ <string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string>
+ <string name="ExternalEditorNotFound">Cannot find the external editor you specified.
+Try enclosing path to the editor with double quotes.
+(e.g. "/path to my/editor" "%s")</string>
+ <string name="ExternalEditorCommandParseError">Error parsing the external editor command.</string>
+ <string name="ExternalEditorFailedToRun">External editor failed to run.</string>
 
   <!-- Key names begin -->
   <string name="Esc">Esc</string>

indra/newview/skins/minimal/xui/de/floater_media_browser.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_about" title="MEDIEN-BROWSER">
+	<floater.string name="home_page_url">
+		http://www.secondlife.com
+	</floater.string>
+	<floater.string name="support_page_url">
+		http://support.secondlife.com
+	</floater.string>
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button label="Zurück" name="back"/>
+			<button label="Vorwärts" name="forward"/>
+			<button label="Neu laden" name="reload"/>
+			<button label="Los" name="go"/>
+		</layout_panel>
+		<layout_panel name="time_controls">
+			<button label="zurück" name="rewind"/>
+			<button label="anhalten" name="stop"/>
+			<button label="vorwärts" name="seek"/>
+		</layout_panel>
+		<layout_panel name="parcel_owner_controls">
+			<button label="Aktuelle Seite an Parzelle senden" name="assign"/>
+		</layout_panel>
+		<layout_panel name="external_controls">
+			<button label="In meinem Browser öffnen" name="open_browser"/>
+			<check_box label="Immer in meinem Browser öffnen" name="open_always"/>
+			<button label="Schließen" name="close"/>
+		</layout_panel>
+	</layout_stack>
+</floater>

indra/newview/skins/minimal/xui/de/floater_web_content.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_web_content" title="">
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button name="back" tool_tip="Rückwärts"/>
+			<button name="forward" tool_tip="Vorwärts"/>
+			<button name="stop" tool_tip="Navigation stoppen"/>
+			<button name="reload" tool_tip="Seite neu laden"/>
+			<combo_box name="address" tool_tip="URL hier eingeben"/>
+			<icon name="media_secure_lock_flag" tool_tip="Sicheres Browsen"/>
+			<button name="popexternal" tool_tip="Aktuelle URL im Desktop-Browser öffnen"/>
+		</layout_panel>
+	</layout_stack>
+</floater>

indra/newview/skins/minimal/xui/de/menu_inspect_self_gear.xml

-<?xml version="1.0" encoding="utf-8"?>
-<menu name="Gear Menu">
-	<menu_item_call label="Hinsetzen" name="sit_down_here"/>
-	<menu_item_call label="Aufstehen" name="stand_up"/>
-	<menu_item_call label="Outfit ändern" name="change_outfit"/>
-	<menu_item_call label="Mein Profil" name="my_profile"/>
-	<menu_item_call label="Meine Freunde" name="my_friends"/>
-	<menu_item_call label="Meine Gruppen" name="my_groups"/>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Gear Menu">
+	<menu_item_call label="Hinsetzen" name="Sit Down Here"/>
+	<menu_item_call label="Aufstehen" name="Stand Up"/>
+	<menu_item_call label="Meine Freunde" name="Friends..."/>
+	<menu_item_call label="Mein Profil" name="Profile..."/>
 	<menu_item_call label="Fehler in Texturen beseitigen" name="Debug..."/>
-</menu>
+</toggleable_menu>

indra/newview/skins/minimal/xui/de/notifications.xml

+<?xml version="1.0" encoding="utf-8"?>
+<notifications>
+	<notification name="UserGiveItem">
+		[NAME_SLURL] bietet Ihnen [ITEM_SLURL] an. Zur Verwendung dieses Artikels müssen Sie in den erweiterten Modus umschalten, wo Sie den Artikel in Ihrem Inventar finden werden. Um in den erweiterten Modus umzuschalten, beenden Sie die Anwendung, starten Sie sie neu und ändern Sie die Moduseinstellung auf dem Anmeldebildschirm.
+		<form name="form">
+			<button name="Show" text="Artikel behalten"/>
+			<button name="Discard" text="Artikel ablehnen"/>
+			<button name="Mute" text="Benutzer blockieren"/>
+		</form>
+	</notification>
+	<notification name="ObjectGiveItem">
+		Ein Objekt namens &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt;, das [NAME_SLURL] gehört, bietet Ihnen [ITEM_SLURL] an. Zur Verwendung dieses Artikels müssen Sie in den erweiterten Modus umschalten, wo Sie den Artikel in Ihrem Inventar finden werden. Um in den erweiterten Modus umzuschalten, beenden Sie die Anwendung, starten Sie sie neu und ändern Sie die Moduseinstellung auf dem Anmeldebildschirm.
+		<form name="form">
+			<button name="Keep" text="Artikel behalten"/>
+			<button name="Discard" text="Artikel ablehnen"/>
+			<button name="Mute" text="Objekt blockieren"/>
+		</form>
+	</notification>
+</notifications>

indra/newview/skins/minimal/xui/de/panel_bottomtray.xml

 			<bottomtray_button label="Ansicht" name="camera_btn" tool_tip="Kamerasteuerung anzeigen/ausblenden"/>
 		</layout_panel>
 		<layout_panel name="avatar_and_destinations_panel">
-			<radio_group name="avatar_and_destination_btns">
-				<radio_item name="destination_btn" value="0"/>
-				<radio_item name="avatar_btn" value="1"/>
-			</radio_group>
+			<bottomtray_button label="Ziele" name="destination_btn" tool_tip="Zeigt Leutefenster an"/>
+		</layout_panel>
+		<layout_panel name="avatar_and_destinations_panel">
+			<bottomtray_button label="Mein Avatar" name="avatar_btn"/>
 		</layout_panel>
 		<layout_panel name="people_panel">
 			<bottomtray_button label="Leute" name="show_people_button" tool_tip="Zeigt Leutefenster an"/>

indra/newview/skins/minimal/xui/de/panel_group_control_panel.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_im_control_panel">
+	<layout_stack name="vertical_stack">
+		<layout_panel name="end_call_btn_panel">
+			<button label="Anruf beenden" name="end_call_btn"/>
+		</layout_panel>
+		<layout_panel name="voice_ctrls_btn_panel">
+			<button label="Voice-Steuerung öffnen" name="voice_ctrls_btn"/>
+		</layout_panel>
+	</layout_stack>
+</panel>

indra/newview/skins/minimal/xui/de/panel_login.xml

 			<text name="mode_selection_text">
 				Modus:
 			</text>
-			<combo_box name="mode_combo">
-				<combo_box.item label="Einfach (Standard)" name="Basic"/>
+			<combo_box name="mode_combo" tool_tip="Wählen Sie den gewünschten Modus aus. Basis: schnelles, einfaches Erkunden und Chatten. Erweitert: Zugriff auf zusätzliche Funktionen.">
+				<combo_box.item label="Basis" name="Basic"/>
 				<combo_box.item label="Erweitert" name="Advanced"/>
 			</combo_box>
 		</layout_panel>

indra/newview/skins/minimal/xui/es/floater_media_browser.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_about" title="EXPLORADOR DE MEDIA">
+	<floater.string name="home_page_url">
+		http://www.secondlife.com
+	</floater.string>
+	<floater.string name="support_page_url">
+		http://support.secondlife.com
+	</floater.string>
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button label="Atrás" name="back"/>
+			<button label="Adelante" name="forward"/>
+			<button label="Recargar" name="reload"/>
+			<button label="Ir" name="go"/>
+		</layout_panel>
+		<layout_panel name="time_controls">
+			<button label="rebobinar" name="rewind"/>
+			<button label="parar" name="stop"/>
+			<button label="avanzar" name="seek"/>
+		</layout_panel>
+		<layout_panel name="parcel_owner_controls">
+			<button label="Enviar a la parcela la página actual" name="assign"/>
+		</layout_panel>
+		<layout_panel name="external_controls">
+			<button label="Abrir en mi propio navegador" name="open_browser"/>
+			<check_box label="Abrir siempre en mi propio navegador" name="open_always"/>
+			<button label="Cerrar" name="close"/>
+		</layout_panel>
+	</layout_stack>
+</floater>

indra/newview/skins/minimal/xui/es/floater_web_content.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_web_content" title="">
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button name="back" tool_tip="Navegar hacia atrás"/>
+			<button name="forward" tool_tip="Navegar hacia adelante"/>
+			<button name="stop" tool_tip="Parar navegación"/>
+			<button name="reload" tool_tip="Recargar página"/>
+			<combo_box name="address" tool_tip="Escribe la URL aquí"/>
+			<icon name="media_secure_lock_flag" tool_tip="Navegación segura"/>
+			<button name="popexternal" tool_tip="Abrir la URL actual en tu explorador de escritorio"/>
+		</layout_panel>
+	</layout_stack>
+</floater>

indra/newview/skins/minimal/xui/es/menu_inspect_self_gear.xml

-<?xml version="1.0" encoding="utf-8"?>
-<menu name="Gear Menu">
-	<menu_item_call label="Sentarte" name="sit_down_here"/>
-	<menu_item_call label="Levantarme" name="stand_up"/>
-	<menu_item_call label="Cambiar vestuario" name="change_outfit"/>
-	<menu_item_call label="Mi perfil" name="my_profile"/>
-	<menu_item_call label="Mis amigos" name="my_friends"/>
-	<menu_item_call label="Mis grupos" name="my_groups"/>
-	<menu_item_call label="Depurar las texturas" name="Debug..."/>
-</menu>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Gear Menu">
+	<menu_item_call label="Sentarme" name="Sit Down Here"/>
+	<menu_item_call label="Levantarme" name="Stand Up"/>
+	<menu_item_call label="Mis amigos" name="Friends..."/>
+	<menu_item_call label="Mi perfil" name="Profile..."/>
+	<menu_item_call label="Depurar texturas" name="Debug..."/>
+</toggleable_menu>

indra/newview/skins/minimal/xui/es/notifications.xml

+<?xml version="1.0" encoding="utf-8"?>
+<notifications>
+	<notification name="UserGiveItem">
+		[NAME_SLURL] te ofrece un/a [ITEM_SLURL]. Para utilizar este ítem, cambia al modo Avanzado y búscalo en el inventario. Para cambiar al modo Avanzado, sal de la aplicación, reiníciala y cambia el ajuste de modo en la pantalla de inicio de sesión.
+		<form name="form">
+			<button name="Show" text="Conservar ítem"/>
+			<button name="Discard" text="Rechazar ítem"/>
+			<button name="Mute" text="Bloquear usuario"/>
+		</form>
+	</notification>
+	<notification name="ObjectGiveItem">
+		Un objeto de nombre &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt;, propiedad de [NAME_SLURL], te ofrece un/a [ITEM_SLURL]. Para utilizar este ítem, cambia al modo Avanzado y búscalo en el inventario. Para cambiar al modo Avanzado, sal de la aplicación, reiníciala y cambia el ajuste de modo en la pantalla de inicio de sesión.
+		<form name="form">
+			<button name="Keep" text="Conservar ítem"/>
+			<button name="Discard" text="Rechazar ítem"/>
+			<button name="Mute" text="Bloquear objeto"/>
+		</form>
+	</notification>
+</notifications>

indra/newview/skins/minimal/xui/es/panel_bottomtray.xml

 			<bottomtray_button label="Visión" name="camera_btn" tool_tip="Muestra/Oculta los controles de la cámara"/>
 		</layout_panel>
 		<layout_panel name="avatar_and_destinations_panel">
-			<radio_group name="avatar_and_destination_btns">
-				<radio_item name="destination_btn" value="0"/>
-				<radio_item name="avatar_btn" value="1"/>
-			</radio_group>
+			<bottomtray_button label="Destinos" name="destination_btn" tool_tip="Muestra la ventana de gente"/>
+		</layout_panel>
+		<layout_panel name="avatar_and_destinations_panel">
+			<bottomtray_button label="Mi avatar" name="avatar_btn"/>
 		</layout_panel>
 		<layout_panel name="people_panel">
 			<bottomtray_button label="Gente" name="show_people_button" tool_tip="Muestra la ventana de gente"/>

indra/newview/skins/minimal/xui/es/panel_group_control_panel.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_im_control_panel">
+	<layout_stack name="vertical_stack">
+		<layout_panel name="end_call_btn_panel">
+			<button label="Colgar" name="end_call_btn"/>
+		</layout_panel>
+		<layout_panel name="voice_ctrls_btn_panel">
+			<button label="Abrir los controles de la voz" name="voice_ctrls_btn"/>
+		</layout_panel>
+	</layout_stack>
+</panel>

indra/newview/skins/minimal/xui/es/panel_login.xml

 			<text name="mode_selection_text">
 				Modo:
 			</text>
-			<combo_box name="mode_combo">
-				<combo_box.item label="Básico (Predeterminado)" name="Basic"/>
+			<combo_box name="mode_combo" tool_tip="Selecciona el modo. Elige Básico para una exploración rápida y fácil y para chatear. Elige Avanzado para tener acceso a más funciones.">
+				<combo_box.item label="Básico" name="Basic"/>
 				<combo_box.item label="Avanzado" name="Advanced"/>
 			</combo_box>
 		</layout_panel>

indra/newview/skins/minimal/xui/fr/floater_media_browser.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_about" title="NAVIGATEUR DE MÉDIAS">
+	<floater.string name="home_page_url">
+		http://www.secondlife.com
+	</floater.string>
+	<floater.string name="support_page_url">
+		http://support.secondlife.com
+	</floater.string>
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button label="Préc." name="back"/>
+			<button label="Suiv." name="forward"/>
+			<button label="Recharger" name="reload"/>
+			<button label="OK" name="go"/>
+		</layout_panel>
+		<layout_panel name="time_controls">
+			<button label="retour" name="rewind"/>
+			<button label="stop" name="stop"/>
+			<button label="avance" name="seek"/>
+		</layout_panel>
+		<layout_panel name="parcel_owner_controls">
+			<button label="Envoyer la page actuelle à la parcelle" name="assign"/>
+		</layout_panel>
+		<layout_panel name="external_controls">
+			<button label="Ouvrir dans mon navigateur Web" name="open_browser"/>
+			<check_box label="Toujours ouvrir dans mon navigateur Web" name="open_always"/>
+			<button label="Fermer" name="close"/>
+		</layout_panel>
+	</layout_stack>
+</floater>

indra/newview/skins/minimal/xui/fr/floater_web_content.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_web_content" title="">
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button name="back" tool_tip="Précédente"/>
+			<button name="forward" tool_tip="Suivante"/>
+			<button name="stop" tool_tip="Arrêter"/>
+			<button name="reload" tool_tip="Recharger la page"/>
+			<combo_box name="address" tool_tip="Saisir une URL ici"/>
+			<icon name="media_secure_lock_flag" tool_tip="Navigation sécurisée"/>
+			<button name="popexternal" tool_tip="Ouvrir l&apos;URL actuelle dans votre navigateur de bureau"/>
+		</layout_panel>
+	</layout_stack>
+</floater>

indra/newview/skins/minimal/xui/fr/menu_inspect_self_gear.xml

-<?xml version="1.0" encoding="utf-8"?>
-<menu name="Gear Menu">
-	<menu_item_call label="M&apos;asseoir" name="sit_down_here"/>
-	<menu_item_call label="Me lever" name="stand_up"/>
-	<menu_item_call label="Changer de tenue" name="change_outfit"/>
-	<menu_item_call label="Mon profil" name="my_profile"/>
-	<menu_item_call label="Mes amis" name="my_friends"/>
-	<menu_item_call label="Mes groupes" name="my_groups"/>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Gear Menu">
+	<menu_item_call label="M&apos;asseoir" name="Sit Down Here"/>
+	<menu_item_call label="Me lever" name="Stand Up"/>
+	<menu_item_call label="Mes amis" name="Friends..."/>
+	<menu_item_call label="Mon profil" name="Profile..."/>
 	<menu_item_call label="Déboguer les textures" name="Debug..."/>
-</menu>
+</toggleable_menu>

indra/newview/skins/minimal/xui/fr/menu_people_nearby.xml

 	<menu_item_call label="Partager" name="Share"/>
 	<menu_item_call label="Payer" name="Pay"/>
 	<menu_item_check label="Ignorer/Ne plus ignorer" name="Block/Unblock"/>
-	<menu_item_call label="Proposer une téléportation" name="teleport"/>
+	<menu_item_call label="Téléporter" name="teleport"/>
 </context_menu>

indra/newview/skins/minimal/xui/fr/notifications.xml

+<?xml version="1.0" encoding="utf-8"?>
+<notifications>
+	<notification name="UserGiveItem">
+		[NAME_SLURL] vous offre [ITEM_SLURL]. Pour utiliser cet article, vous devez passer en mode Avancé. L&apos;article se trouve dans votre inventaire. Pour changer de mode, quittez l&apos;application, redémarrez-la, puis sélectionnez un autre mode sur l&apos;écran de connexion.
+		<form name="form">
+			<button name="Show" text="Garder l&apos;article"/>
+			<button name="Discard" text="Refuser l&apos;article"/>
+			<button name="Mute" text="Ignorer l&apos;utilisateur"/>
+		</form>
+	</notification>
+	<notification name="ObjectGiveItem">
+		Un objet nommé &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; appartenant à [NAME_SLURL] vous offre [ITEM_SLURL]. Pour utiliser cet article, vous devez passer en mode Avancé. L&apos;article se trouve dans votre inventaire. Pour changer de mode, quittez l&apos;application, redémarrez-la, puis sélectionnez un autre mode sur l&apos;écran de connexion.
+		<form name="form">
+			<button name="Keep" text="Garder l&apos;article"/>
+			<button name="Discard" text="Refuser l&apos;article"/>
+			<button name="Mute" text="Ignorer l&apos;objet"/>
+		</form>
+	</notification>
+</notifications>

indra/newview/skins/minimal/xui/fr/panel_bottomtray.xml

 			<bottomtray_button label="Affichage" name="camera_btn" tool_tip="Affiche/Masque le contrôle de la caméra"/>
 		</layout_panel>
 		<layout_panel name="avatar_and_destinations_panel">
-			<radio_group name="avatar_and_destination_btns">
-				<radio_item name="destination_btn" value="0"/>
-				<radio_item name="avatar_btn" value="1"/>
-			</radio_group>
+			<bottomtray_button label="Destinations" name="destination_btn" tool_tip="Afficher la fenêtre des personnes."/>
+		</layout_panel>
+		<layout_panel name="avatar_and_destinations_panel">
+			<bottomtray_button label="Mon avatar" name="avatar_btn"/>
 		</layout_panel>
 		<layout_panel name="people_panel">
 			<bottomtray_button label="Personnes" name="show_people_button" tool_tip="Afficher la fenêtre des personnes."/>

indra/newview/skins/minimal/xui/fr/panel_group_control_panel.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_im_control_panel">
+	<layout_stack name="vertical_stack">
+		<layout_panel name="end_call_btn_panel">
+			<button label="Quitter l&apos;appel" name="end_call_btn"/>
+		</layout_panel>
+		<layout_panel name="voice_ctrls_btn_panel">
+			<button label="Ouvrir contrôles vocaux" name="voice_ctrls_btn"/>
+		</layout_panel>
+	</layout_stack>
+</panel>

indra/newview/skins/minimal/xui/fr/panel_login.xml

 			<text name="mode_selection_text">
 				Mode :
 			</text>
-			<combo_box name="mode_combo">
-				<combo_box.item label="Basique (par défaut)" name="Basic"/>
+			<combo_box name="mode_combo" tool_tip="Sélectionnez un mode. Pour une exploration facile et rapide avec chat, choisissez Basique. Pour accéder à plus de fonctionnalités, choisissez Avancé.">
+				<combo_box.item label="Basique" name="Basic"/>
 				<combo_box.item label="Avancé" name="Advanced"/>
 			</combo_box>
 		</layout_panel>

indra/newview/skins/minimal/xui/pt/floater_media_browser.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_about" title="NAVEGADOR DE MÍDIA">
+	<floater.string name="home_page_url">
+		http://www.secondlife.com
+	</floater.string>
+	<floater.string name="support_page_url">
+		http://support.secondlife.com
+	</floater.string>
+	<layout_stack name="stack1">
+		<layout_panel name="nav_controls">
+			<button label="Atrás" name="back"/>