Commits

Scott Lawrence  committed ee12851 Merge

merge changes for storm-1086

  • Participants
  • Parent commits d6928ba, 2e8df76

Comments (0)

Files changed (114)

 f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
 f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
 4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start
+9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1
+9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1
+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
+c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
+c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
 # 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
 
 # ========================================
 # enus

File doc/contributions.txt

 	STORM-990
 	STORM-1020
 	STORM-1064
+	STORM-1077
 Kage Pixel
 	VWR-11
 Ken March

File indra/integration_tests/CMakeLists.txt

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

File 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) 

File 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;
+}

File 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

File 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
 //----------------------------------------------------------------------------------------------

File 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.
 	 */

File 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, mWorkingDir.c_str(), &sinfo, &pinfo ) )
+	const char * working_directory = 0;
+	if(!mWorkingDir.empty()) working_directory = mWorkingDir.c_str();
+	if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, working_directory, &sinfo, &pinfo ) )
 	{
-		// TODO: do better than returning the OS-specific error code on failure...
 		result = GetLastError();
+
+		LPTSTR error_str = 0;
+		if(
+			FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+				NULL,
+				result,
+				0,
+				(LPTSTR)&error_str,
+				0,
+				NULL) 
+			!= 0) 
+		{
+			char message[256];
+			wcstombs(message, error_str, 256);
+			message[255] = 0;
+			llwarns << "CreateProcessA failed: " << message << llendl;
+			LocalFree(error_str);
+		}
+
 		if(result == 0)
 		{
 			// Make absolutely certain we return a non-zero value on failure.

File 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 = 3;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";

File 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);

File indra/llimage/llimagej2c.cpp

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

File indra/llui/llmenugl.cpp

 	{
 		item_list_t::reverse_iterator first_visible_item_iter = mItems.rend();
 
+		// Need to scroll through number of actual existing items in menu.
+		// Otherwise viewer will hang for a time needed to scroll U32_MAX
+		// times in std::advance(). STORM-659.
+		size_t nitems = mItems.size();
+		U32 scrollable_items = nitems < mMaxScrollableItems ? nitems : mMaxScrollableItems;
+
 		// Advance by mMaxScrollableItems back from the end of the list
 		// to make the last item visible.
-		std::advance(first_visible_item_iter, mMaxScrollableItems);
+		std::advance(first_visible_item_iter, scrollable_items);
 		mFirstVisibleItem = *first_visible_item_iter;
 		break;
 	}

File indra/newview/app_settings/ignorable_dialogs.xml

       <key>Value</key>
       <integer>1</integer>
     </map>
-
+    <key>FirstSpeak</key>
+    <map>
+      <key>Comment</key>
+      <string>Shows hint for Speak button</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>FirstSit</key>
     <map>
       <key>Comment</key>

File indra/newview/app_settings/settings.xml

     <key>FirstRunThisInstall</key>
     <map>
       <key>Comment</key>
-      <string>Specifies that you have not run the viewer since you installed the latest update</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
-    <key>FirstSelectedDisabledPopups</key>
+      <string>Specifies that you have not run the viewer since you performed a clean install</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+  <key>FirstLoginThisInstall</key>
+  <map>
+    <key>Comment</key>
+    <string>Specifies that you have not logged in with the viewer since you performed a clean install</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
+  <key>FirstSelectedDisabledPopups</key>
     <map>
       <key>Comment</key>
       <string>Return false if there is not disabled popup selected in the list of floater preferences popups</string>

File indra/newview/llappviewer.cpp

 	if (gSavedSettings.getBOOL("FirstRunThisInstall"))
 	{
 		gSavedSettings.setString("SessionSettingsFile", "settings_minimal.xml");
+		gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
 	}
 
 	if (clp.hasOption("sessionsettings"))

File indra/newview/llbottomtray.cpp

 
 #include "llviewerwindow.h"
 #include "llsdserialize.h"
+#include "llfirstuse.h"
 
 // Distance from mouse down on which drag'n'drop should be started.
 #define DRAG_START_DISTANCE 3
 	// skipped to avoid button blinking
 	if (status != STATUS_JOINING && status!= STATUS_LEFT_CHANNEL)
 	{
-		mSpeakBtn->setFlyoutBtnEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
+		bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
+		mSpeakBtn->setFlyoutBtnEnabled(voice_status);
+		if (voice_status)
+		{
+			LLFirstUse::speak(true);
+		}
 	}
 }
 
 
 	mSpeakPanel = getChild<LLPanel>("speak_panel");
 	mSpeakBtn = getChild<LLSpeakButton>("talk");
+	LLHints::registerHintTarget("speak_btn", mSpeakBtn->getHandle());
 
 	// Both parts of speak button should be initially disabled because
 	// it takes some time between logging in to world and connecting to voice channel.

File indra/newview/llcallfloater.cpp

 #include "llviewerwindow.h"
 #include "llvoicechannel.h"
 #include "llviewerparcelmgr.h"
+#include "llfirstuse.h"
 
 static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids);
 void reshape_floater(LLCallFloater* floater, S32 delta_height);
 	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
 	
 	updateSession();
-
 	return TRUE;
 }
 
 // virtual
 void LLCallFloater::onOpen(const LLSD& /*key*/)
 {
+	LLFirstUse::speak(false);
 }
 
 // virtual

File 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)

File 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);

File 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

File 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:
 

File 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 ;
 	}
 }

File 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:

File indra/newview/llfirstuse.cpp

 }
 
 // static
+void LLFirstUse::speak(bool enable)
+{
+	firstUseNotification("FirstSpeak", enable, "HintSpeak", LLSD(), LLSD().with("target", "speak_btn").with("direction", "top"));
+}
+
+// static
 void LLFirstUse::sit(bool enable)
 {
 	firstUseNotification("FirstSit", enable, "HintSit", LLSD(), LLSD().with("target", "stand_btn").with("direction", "top"));

File indra/newview/llfirstuse.h

 13. First time you open the debug menus (ctrl-alt-shift D)
 
 14. First time you create/edit a sculpted prim.
+
+15. Explanation of Speak&flyout buttons.
 */
 
 class LLNotification;
 	static void resetFirstUse();
 
 	static void otherAvatarChatFirst(bool enable = true);
+	static void speak(bool enable = true);
 	static void sit(bool enable = true);
 	static void notUsingDestinationGuide(bool enable = true);
 	static void notUsingSidePanel(bool enable = true);

File indra/newview/llfloatermap.cpp

 #include "llviewercamera.h"
 #include "lldraghandle.h"
 #include "lltextbox.h"
-#include "llviewermenu.h"
 #include "llfloaterworldmap.h"
 #include "llagent.h"
 
 
 LLFloaterMap::LLFloaterMap(const LLSD& key) 
 	: LLFloater(key),
-	  mPopupMenu(NULL),
 	  mTextBoxEast(NULL),
 	  mTextBoxNorth(NULL),
 	  mTextBoxWest(NULL),
 	mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
 	mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
 
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	
-	registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2));
-	registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if (mPopupMenu && !LLTracker::isTracking(0))
-	{
-		mPopupMenu->setItemEnabled ("Stop Tracking", false);
-	}
-
 	stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT
 		,getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM);
 
 	return TRUE;
 }
 
-BOOL LLFloaterMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	if (mPopupMenu)
-	{
-		mPopupMenu->buildDrawLabels();
-		mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
-		LLMenuGL::showPopup(this, mPopupMenu, x, y);
-	}
-	return TRUE;
-}
-
 void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
 {
 	// Rotation is in radians.
 		getDragHandle()->setMouseOpaque(TRUE);
 	}
 	
-	if (LLTracker::isTracking(0))
-	{
-		mPopupMenu->setItemEnabled ("Stop Tracking", true);
-	}
-	
 	LLFloater::draw();
 }
 
 	}
 }
 
-void LLFloaterMap::handleStopTracking (const LLSD& userdata)
-{
-	if (mPopupMenu)
-	{
-		mPopupMenu->setItemEnabled ("Stop Tracking", false);
-		LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL));
-	}
-}
 void	LLFloaterMap::setMinimized(BOOL b)
 {
 	LLFloater::setMinimized(b);

File indra/newview/llfloatermap.h

 
 #include "llfloater.h"
 
-class LLMenuGL;
 class LLNetMap;
 class LLTextBox;
 
 	
 	/*virtual*/ BOOL 	postBuild();
 	/*virtual*/ BOOL	handleDoubleClick( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL	handleRightMouseDown( S32 x, S32 y, MASK mask );
 	/*virtual*/ void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	/*virtual*/ void	draw();
 	/*virtual*/ void	onFocusLost();
 	
 private:
 	void handleZoom(const LLSD& userdata);
-	void handleStopTracking (const LLSD& userdata);
 	void setDirectionPos( LLTextBox* text_box, F32 rotation );
 	void updateMinorDirections();
 
 	void stretchMiniMap(S32 width,S32 height);
 	
-	LLMenuGL*		mPopupMenu;
-
 	LLTextBox*		mTextBoxEast;
 	LLTextBox*		mTextBoxNorth;
 	LLTextBox*		mTextBoxWest;

File 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;

File 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;
 	}
 }

File indra/newview/llhudeffectblob.cpp

 
 #include "llagent.h"
 #include "llviewercamera.h"
-#include "llrendersphere.h"
+#include "llui.h"
 
 LLHUDEffectBlob::LLHUDEffectBlob(const U8 type) 
 :	LLHUDEffect(type), 
 	mPixelSize(10)
 {
 	mTimer.start();
+	mImage = LLUI::getUIImage("Camera_Drag_Dot");
 }
 
 LLHUDEffectBlob::~LLHUDEffectBlob()
 	LLViewerCamera::instance().getPixelVectors(pos_agent, pixel_up, pixel_right);
 
 	LLGLSPipelineAlpha gls_pipeline_alpha;
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->bind(mImage->getImage());
 
 	LLColor4U color = mColor;
 	color.mV[VALPHA] = (U8)clamp_rescale(time, 0.f, mDuration, 255.f, 0.f);
-	glColor4ubv(color.mV);
+	gGL.color4ubv(color.mV);
 
-	glPushMatrix();
-	glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
-	F32 scale = pixel_up.magVec() * (F32)mPixelSize;
-	glScalef(scale, scale, scale);
-	gSphere.render(0);
-	glPopMatrix();
+	{ gGL.pushMatrix();
+		gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
+		LLVector3 u_scale = pixel_right * (F32)mPixelSize;
+		LLVector3 v_scale = pixel_up * (F32)mPixelSize;
+		
+		{ gGL.begin(LLRender::QUADS);
+			gGL.texCoord2f(0.f, 1.f);
+			gGL.vertex3fv((v_scale - u_scale).mV);
+			gGL.texCoord2f(0.f, 0.f);
+			gGL.vertex3fv((-v_scale - u_scale).mV);
+			gGL.texCoord2f(1.f, 0.f);
+			gGL.vertex3fv((-v_scale + u_scale).mV);
+			gGL.texCoord2f(1.f, 1.f);
+			gGL.vertex3fv((v_scale + u_scale).mV);
+		} gGL.end();
+
+	} gGL.popMatrix();
 }
 
 void LLHUDEffectBlob::renderForTimer()

File indra/newview/llhudeffectblob.h

 #define LL_LLHUDEFFECTBLOB_H
 
 #include "llhudeffect.h"
+#include "lluiimage.h"
 
 class LLHUDEffectBlob : public LLHUDEffect
 {
 private:
 	S32				mPixelSize;
 	LLFrameTimer	mTimer;
+	LLPointer<LLUIImage> mImage;
 };
 
 #endif // LL_LLHUDEFFECTBLOB_H

File 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);	
 	}
 

File indra/newview/llnetmap.cpp

 	registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
 
 	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if (mPopupMenu && !LLTracker::isTracking(0))
-	{
-		mPopupMenu->setItemEnabled ("Stop Tracking", false);
-	}
 	return TRUE;
 }
 
 	gGL.popUIMatrix();
 
 	LLUICtrl::draw();
-
-	if (LLTracker::isTracking(0))
-	{
-		mPopupMenu->setItemEnabled ("Stop Tracking", true);
-	}
-	
-
 }
 
 void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
 	{
 		mPopupMenu->buildDrawLabels();
 		mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+		mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
 		LLMenuGL::showPopup(this, mPopupMenu, x, y);
 	}
 	return TRUE;

File 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));
+		}
 	}
 }
 

File 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());

File indra/newview/llspeakbutton.cpp

 #include "llspeakbutton.h"
 
 #include "llbottomtray.h"
+#include "llfirstuse.h"
 
 static LLDefaultChildRegistry::Register<LLSpeakButton> t1("talk_button");
 
 {
 	bool down = true;
 	LLVoiceClient::getInstance()->inputUserControlState(down); // this method knows/care about whether this translates into a toggle-to-talk or down-to-talk
+	LLFirstUse::speak(false);
 }
 void LLSpeakButton::onMouseUp_SpeakBtn()
 {

File indra/newview/llstartup.cpp

-/** 
- * @file llstartup.cpp
- * @brief startup routines.
- *
- * $LicenseInfo:firstyear=2004&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 "llviewerprecompiledheaders.h"
-
-#include "llstartup.h"
-
-#if LL_WINDOWS
-#	include <process.h>		// _spawnl()
-#else
-#	include <sys/stat.h>		// mkdir()
-#endif
-
-#include "llviewermedia_streamingaudio.h"
-#include "llaudioengine.h"
-
-#ifdef LL_FMOD
-# include "llaudioengine_fmod.h"
-#endif
-
-#ifdef LL_OPENAL
-#include "llaudioengine_openal.h"
-#endif
-
-#include "llares.h"
-#include "llavatarnamecache.h"
-#include "lllandmark.h"
-#include "llcachename.h"
-#include "lldir.h"
-#include "llerrorcontrol.h"
-#include "llfloaterreg.h"
-#include "llfocusmgr.h"