diff options
142 files changed, 4821 insertions, 3268 deletions
| diff --git a/BuildParams b/BuildParams index 0a4271f7a8..8e036ab56b 100644 --- a/BuildParams +++ b/BuildParams @@ -26,6 +26,7 @@ viewer-development.show_changes_since = last_sprint  # Build Settings  viewer-development_coverity.coverity_product = viewer +viewer-development_coverity.run_tests = false  viewer-development.build_debug_release_separately = true  # Notifications - to configure email notices, add a setting like this: @@ -66,7 +66,8 @@ pre_build()      -DRELEASE_CRASH_REPORTING:BOOL=ON \      -DLOCALIZESETUP:BOOL=ON \      -DPACKAGE:BOOL=ON \ -    -DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE +    -DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE \ +    -DLL_TESTS:BOOL="$run_tests"    end_section "Pre$variant"  } diff --git a/doc/contributions.txt b/doc/contributions.txt index 3b14ce5125..c61ae66b13 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -72,6 +72,7 @@ Aleric Inglewood  	VWR-10837  	VWR-12691  	VWR-12984 +	VWR-13040  	VWR-13996  	VWR-14426  	VWR-24247 @@ -79,6 +80,12 @@ Aleric Inglewood  	VWR-24252  	VWR-24254  	VWR-24261 +	VWR-24315 +	VWR-24317 +	VWR-24320 +    VWR-24321 + 	VWR-24354 +	VWR-24519  	SNOW-84  	SNOW-477  	SNOW-744 @@ -219,6 +226,8 @@ Catherine Pfeffer  Celierra Darling  	VWR-1274  	VWR-6975 +Coaldust Numbers +    VWR-1095  Cron Stardust  	VWR-10579  Cypren Christenson @@ -364,15 +373,22 @@ JB Kraft  Joghert LeSabre  	VWR-64  Jonathan Yap -	STORM-596  	STORM-523 +	STORM-596 +	STORM-615  	STORM-616  	STORM-679 -	STORM-737 +	STORM-723  	STORM-726 +	STORM-737 +	STORM-869 +	STORM-785  	STORM-812 +	STORM-829  	VWR-17801 -	STORM-785 +	VWR-24347 +	STORM-844 +	STORM-643  Kage Pixel  	VWR-11  Ken March @@ -389,6 +405,7 @@ Kitty Barnett  	STORM-288  	STORM-799  	STORM-800 +    VWR-24217  Kunnis Basiat  	VWR-82  	VWR-102 @@ -732,6 +749,7 @@ Thickbrick Sleaford  	VWR-9287  	VWR-13483  	VWR-13947 +	VWR-24420  Thraxis Epsilon  	SVC-371  	VWR-383 @@ -752,6 +770,8 @@ Twisted Laws  	SNOW-352  	STORM-466  	STORM-467 +	STORM-844 +	STORM-643  Vadim Bigbear  	VWR-2681  Vector Hastings diff --git a/etc/message.xml b/etc/message.xml index 7c4a927cc5..764aea3879 100644 --- a/etc/message.xml +++ b/etc/message.xml @@ -678,20 +678,17 @@  			<key>EstateChangeInfo</key>  			<boolean>true</boolean> -			<key>FetchInventoryDescendents</key> +			<key>FetchInventoryDescendents2</key>  			<boolean>false</boolean> -			<key>WebFetchInventoryDescendents</key> -			<boolean>true</boolean> -		 -			<key>FetchInventory</key> -			<boolean>true</boolean> +			<key>FetchInventory2</key> +			<boolean>false</boolean> -			<key>FetchLibDescendents</key> -			<boolean>true</boolean> +			<key>FetchLibDescendents2</key> +			<boolean>false</boolean> -			<key>FetchLib</key> -			<boolean>true</boolean> +			<key>FetchLib2</key> +			<boolean>false</boolean>  			<key>UploadBakedTexture</key>  			<boolean>true</boolean> diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 176ae9787e..1b08c3fd2e 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -66,6 +66,7 @@ if(WINDOWS)  if (MSVC80)      FIND_PATH(debug_msvc8_redist_path msvcr80d.dll          PATHS +		${MSVC_DEBUG_REDIST_PATH}           [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/redist/Debug_NonRedist/x86/Microsoft.VC80.DebugCRT          NO_DEFAULT_PATH          NO_DEFAULT_PATH @@ -90,6 +91,7 @@ if (MSVC80)      FIND_PATH(release_msvc8_redist_path msvcr80.dll          PATHS +		${MSVC_REDIST_PATH}           [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/redist/x86/Microsoft.VC80.CRT          NO_DEFAULT_PATH          NO_DEFAULT_PATH diff --git a/indra/cmake/GetPrerequisites_2_8.cmake b/indra/cmake/GetPrerequisites_2_8.cmake index 5a24842c89..05ec1539ba 100644 --- a/indra/cmake/GetPrerequisites_2_8.cmake +++ b/indra/cmake/GetPrerequisites_2_8.cmake @@ -1,786 +1,786 @@ -# GetPrerequisites.cmake
 -#
 -# This script provides functions to list the .dll, .dylib or .so files that an
 -# executable or shared library file depends on. (Its prerequisites.)
 -#
 -# It uses various tools to obtain the list of required shared library files:
 -#   dumpbin (Windows)
 -#   ldd (Linux/Unix)
 -#   otool (Mac OSX)
 -#
 -# The following functions are provided by this script:
 -#   gp_append_unique
 -#   is_file_executable
 -#   gp_item_default_embedded_path
 -#     (projects can override with gp_item_default_embedded_path_override)
 -#   gp_resolve_item
 -#     (projects can override with gp_resolve_item_override)
 -#   gp_resolved_file_type
 -#   gp_file_type
 -#   get_prerequisites
 -#   list_prerequisites
 -#   list_prerequisites_by_glob
 -#
 -# Requires CMake 2.6 or greater because it uses function, break, return and
 -# PARENT_SCOPE.
 -
 -#=============================================================================
 -# Copyright 2008-2009 Kitware, Inc.
 -#
 -# Distributed under the OSI-approved BSD License (the "License");
 -# see accompanying file Copyright.txt for details.
 -#
 -# This software is distributed WITHOUT ANY WARRANTY; without even the
 -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 -# See the License for more information.
 -#=============================================================================
 -# (To distributed this file outside of CMake, substitute the full
 -#  License text for the above reference.)
 -
 -# gp_append_unique list_var value
 -#
 -# Append value to the list variable ${list_var} only if the value is not
 -# already in the list.
 -#
 -function(gp_append_unique list_var value)
 -  set(contains 0)
 -
 -  foreach(item ${${list_var}})
 -    if("${item}" STREQUAL "${value}")
 -      set(contains 1)
 -      break()
 -    endif("${item}" STREQUAL "${value}")
 -  endforeach(item)
 -
 -  if(NOT contains)
 -    set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
 -  endif(NOT contains)
 -endfunction(gp_append_unique)
 -
 -
 -# is_file_executable file result_var
 -#
 -# Return 1 in ${result_var} if ${file} is a binary executable.
 -#
 -# Return 0 in ${result_var} otherwise.
 -#
 -function(is_file_executable file result_var)
 -  #
 -  # A file is not executable until proven otherwise:
 -  #
 -  set(${result_var} 0 PARENT_SCOPE)
 -
 -  get_filename_component(file_full "${file}" ABSOLUTE)
 -  string(TOLOWER "${file_full}" file_full_lower)
 -
 -  # If file name ends in .exe on Windows, *assume* executable:
 -  #
 -  if(WIN32)
 -    if("${file_full_lower}" MATCHES "\\.exe$")
 -      set(${result_var} 1 PARENT_SCOPE)
 -      return()
 -    endif("${file_full_lower}" MATCHES "\\.exe$")
 -
 -    # A clause could be added here that uses output or return value of dumpbin
 -    # to determine ${result_var}. In 99%+? practical cases, the exe name
 -    # match will be sufficient...
 -    #
 -  endif(WIN32)
 -
 -  # Use the information returned from the Unix shell command "file" to
 -  # determine if ${file_full} should be considered an executable file...
 -  #
 -  # If the file command's output contains "executable" and does *not* contain
 -  # "text" then it is likely an executable suitable for prerequisite analysis
 -  # via the get_prerequisites macro.
 -  #
 -  if(UNIX)
 -    if(NOT file_cmd)
 -      find_program(file_cmd "file")
 -    endif(NOT file_cmd)
 -
 -    if(file_cmd)
 -      execute_process(COMMAND "${file_cmd}" "${file_full}"
 -        OUTPUT_VARIABLE file_ov
 -        OUTPUT_STRIP_TRAILING_WHITESPACE
 -        )
 -
 -      # Replace the name of the file in the output with a placeholder token
 -      # (the string " _file_full_ ") so that just in case the path name of
 -      # the file contains the word "text" or "executable" we are not fooled
 -      # into thinking "the wrong thing" because the file name matches the
 -      # other 'file' command output we are looking for...
 -      #
 -      string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
 -      string(TOLOWER "${file_ov}" file_ov)
 -
 -      #message(STATUS "file_ov='${file_ov}'")
 -      if("${file_ov}" MATCHES "executable")
 -        #message(STATUS "executable!")
 -        if("${file_ov}" MATCHES "text")
 -          #message(STATUS "but text, so *not* a binary executable!")
 -        else("${file_ov}" MATCHES "text")
 -          set(${result_var} 1 PARENT_SCOPE)
 -          return()
 -        endif("${file_ov}" MATCHES "text")
 -      endif("${file_ov}" MATCHES "executable")
 -    else(file_cmd)
 -      message(STATUS "warning: No 'file' command, skipping execute_process...")
 -    endif(file_cmd)
 -  endif(UNIX)
 -endfunction(is_file_executable)
 -
 -
 -# gp_item_default_embedded_path item default_embedded_path_var
 -#
 -# Return the path that others should refer to the item by when the item
 -# is embedded inside a bundle.
 -#
 -# Override on a per-project basis by providing a project-specific
 -# gp_item_default_embedded_path_override function.
 -#
 -function(gp_item_default_embedded_path item default_embedded_path_var)
 -
 -  # On Windows and Linux, "embed" prerequisites in the same directory
 -  # as the executable by default:
 -  #
 -  set(path "@executable_path")
 -  set(overridden 0)
 -
 -  # On the Mac, relative to the executable depending on the type
 -  # of the thing we are embedding:
 -  #
 -  if(APPLE)
 -    #
 -    # The assumption here is that all executables in the bundle will be
 -    # in same-level-directories inside the bundle. The parent directory
 -    # of an executable inside the bundle should be MacOS or a sibling of
 -    # MacOS and all embedded paths returned from here will begin with
 -    # "@executable_path/../" and will work from all executables in all
 -    # such same-level-directories inside the bundle.
 -    #
 -
 -    # By default, embed things right next to the main bundle executable:
 -    #
 -    set(path "@executable_path/../../Contents/MacOS")
 -
 -    # Embed .dylibs right next to the main bundle executable:
 -    #
 -    if(item MATCHES "\\.dylib$")
 -      set(path "@executable_path/../MacOS")
 -      set(overridden 1)
 -    endif(item MATCHES "\\.dylib$")
 -
 -    # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
 -    #
 -    if(NOT overridden)
 -      if(item MATCHES "[^/]+\\.framework/")
 -        set(path "@executable_path/../Frameworks")
 -        set(overridden 1)
 -      endif(item MATCHES "[^/]+\\.framework/")
 -    endif(NOT overridden)
 -  endif()
 -
 -  # Provide a hook so that projects can override the default embedded location
 -  # of any given library by whatever logic they choose:
 -  #
 -  if(COMMAND gp_item_default_embedded_path_override)
 -    gp_item_default_embedded_path_override("${item}" path)
 -  endif(COMMAND gp_item_default_embedded_path_override)
 -
 -  set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
 -endfunction(gp_item_default_embedded_path)
 -
 -
 -# gp_resolve_item context item exepath dirs resolved_item_var
 -#
 -# Resolve an item into an existing full path file.
 -#
 -# Override on a per-project basis by providing a project-specific
 -# gp_resolve_item_override function.
 -#
 -function(gp_resolve_item context item exepath dirs resolved_item_var)
 -  set(resolved 0)
 -  set(resolved_item "${item}")
 -
 -  # Is it already resolved?
 -  #
 -  if(EXISTS "${resolved_item}")
 -    set(resolved 1)
 -  endif(EXISTS "${resolved_item}")
 -
 -  if(NOT resolved)
 -    if(item MATCHES "@executable_path")
 -      #
 -      # @executable_path references are assumed relative to exepath
 -      #
 -      string(REPLACE "@executable_path" "${exepath}" ri "${item}")
 -      get_filename_component(ri "${ri}" ABSOLUTE)
 -
 -      if(EXISTS "${ri}")
 -        #message(STATUS "info: embedded item exists (${ri})")
 -        set(resolved 1)
 -        set(resolved_item "${ri}")
 -      else(EXISTS "${ri}")
 -        message(STATUS "warning: embedded item does not exist '${ri}'")
 -      endif(EXISTS "${ri}")
 -    endif(item MATCHES "@executable_path")
 -  endif(NOT resolved)
 -
 -  if(NOT resolved)
 -    if(item MATCHES "@loader_path")
 -      #
 -      # @loader_path references are assumed relative to the
 -      # PATH of the given "context" (presumably another library)
 -      #
 -      get_filename_component(contextpath "${context}" PATH)
 -      string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
 -      get_filename_component(ri "${ri}" ABSOLUTE)
 -
 -      if(EXISTS "${ri}")
 -        #message(STATUS "info: embedded item exists (${ri})")
 -        set(resolved 1)
 -        set(resolved_item "${ri}")
 -      else(EXISTS "${ri}")
 -        message(STATUS "warning: embedded item does not exist '${ri}'")
 -      endif(EXISTS "${ri}")
 -    endif(item MATCHES "@loader_path")
 -  endif(NOT resolved)
 -
 -  if(NOT resolved)
 -    set(ri "ri-NOTFOUND")
 -    find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
 -    find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
 -    if(ri)
 -      #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
 -      set(resolved 1)
 -      set(resolved_item "${ri}")
 -      set(ri "ri-NOTFOUND")
 -    endif(ri)
 -  endif(NOT resolved)
 -
 -  if(NOT resolved)
 -    if(item MATCHES "[^/]+\\.framework/")
 -      set(fw "fw-NOTFOUND")
 -      find_file(fw "${item}"
 -        "~/Library/Frameworks"
 -        "/Library/Frameworks"
 -        "/System/Library/Frameworks"
 -      )
 -      if(fw)
 -        #message(STATUS "info: 'find_file' found framework (${fw})")
 -        set(resolved 1)
 -        set(resolved_item "${fw}")
 -        set(fw "fw-NOTFOUND")
 -      endif(fw)
 -    endif(item MATCHES "[^/]+\\.framework/")
 -  endif(NOT resolved)
 -
 -  # Using find_program on Windows will find dll files that are in the PATH.
 -  # (Converting simple file names into full path names if found.)
 -  #
 -  if(WIN32)
 -  if(NOT resolved)
 -    set(ri "ri-NOTFOUND")
 -    find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
 -    find_program(ri "${item}" PATHS "${exepath};${dirs}")
 -    if(ri)
 -      #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
 -      set(resolved 1)
 -      set(resolved_item "${ri}")
 -      set(ri "ri-NOTFOUND")
 -    endif(ri)
 -  endif(NOT resolved)
 -  endif(WIN32)
 -
 -  # Provide a hook so that projects can override item resolution
 -  # by whatever logic they choose:
 -  #
 -  if(COMMAND gp_resolve_item_override)
 -    gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
 -  endif(COMMAND gp_resolve_item_override)
 -
 -  if(NOT resolved)
 -    message(STATUS "
 -warning: cannot resolve item '${item}'
 -
 -  possible problems:
 -    need more directories?
 -    need to use InstallRequiredSystemLibraries?
 -    run in install tree instead of build tree?
 -")
 -#    message(STATUS "
 -#******************************************************************************
 -#warning: cannot resolve item '${item}'
 -#
 -#  possible problems:
 -#    need more directories?
 -#    need to use InstallRequiredSystemLibraries?
 -#    run in install tree instead of build tree?
 -#
 -#    context='${context}'
 -#    item='${item}'
 -#    exepath='${exepath}'
 -#    dirs='${dirs}'
 -#    resolved_item_var='${resolved_item_var}'
 -#******************************************************************************
 -#")
 -  endif(NOT resolved)
 -
 -  set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
 -endfunction(gp_resolve_item)
 -
 -
 -# gp_resolved_file_type original_file file exepath dirs type_var
 -#
 -# Return the type of ${file} with respect to ${original_file}. String
 -# describing type of prerequisite is returned in variable named ${type_var}.
 -#
 -# Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file}
 -# values -- but only for non-embedded items.
 -#
 -# Possible types are:
 -#   system
 -#   local
 -#   embedded
 -#   other
 -#
 -function(gp_resolved_file_type original_file file exepath dirs type_var)
 -  #message(STATUS "**")
 -
 -  if(NOT IS_ABSOLUTE "${original_file}")
 -    message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
 -  endif()
 -
 -  set(is_embedded 0)
 -  set(is_local 0)
 -  set(is_system 0)
 -
 -  set(resolved_file "${file}")
 -
 -  if("${file}" MATCHES "^@(executable|loader)_path")
 -    set(is_embedded 1)
 -  endif()
 -
 -  if(NOT is_embedded)
 -    if(NOT IS_ABSOLUTE "${file}")
 -      gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
 -    endif()
 -
 -    string(TOLOWER "${original_file}" original_lower)
 -    string(TOLOWER "${resolved_file}" lower)
 -
 -    if(UNIX)
 -      if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)")
 -        set(is_system 1)
 -      endif()
 -    endif()
 -
 -    if(APPLE)
 -      if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
 -        set(is_system 1)
 -      endif()
 -    endif()
 -
 -    if(WIN32)
 -      string(TOLOWER "$ENV{SystemRoot}" sysroot)
 -      string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
 -
 -      string(TOLOWER "$ENV{windir}" windir)
 -      string(REGEX REPLACE "\\\\" "/" windir "${windir}")
 -
 -      if(lower MATCHES "^(${sysroot}/system|${windir}/system|${sysroot}/syswow|${windir}/syswow|(.*/)*msvc[^/]+dll)")
 -        set(is_system 1)
 -      endif()
 -    endif()
 -
 -    if(NOT is_system)
 -      get_filename_component(original_path "${original_lower}" PATH)
 -      get_filename_component(path "${lower}" PATH)
 -      if("${original_path}" STREQUAL "${path}")
 -        set(is_local 1)
 -      endif()
 -    endif()
 -  endif()
 -
 -  # Return type string based on computed booleans:
 -  #
 -  set(type "other")
 -
 -  if(is_system)
 -    set(type "system")
 -  elseif(is_embedded)
 -    set(type "embedded")
 -  elseif(is_local)
 -    set(type "local")
 -  endif()
 -
 -  #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
 -  #message(STATUS "                type: '${type}'")
 -
 -  if(NOT is_embedded)
 -    if(NOT IS_ABSOLUTE "${resolved_file}")
 -      if(lower MATCHES "^msvc[^/]+dll" AND is_system)
 -        message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
 -      else()
 -        message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
 -      endif()
 -    endif()
 -  endif()
 -
 -  set(${type_var} "${type}" PARENT_SCOPE)
 -
 -  #message(STATUS "**")
 -endfunction()
 -
 -
 -# gp_file_type original_file file type_var
 -#
 -# Return the type of ${file} with respect to ${original_file}. String
 -# describing type of prerequisite is returned in variable named ${type_var}.
 -#
 -# Possible types are:
 -#   system
 -#   local
 -#   embedded
 -#   other
 -#
 -function(gp_file_type original_file file type_var)
 -  if(NOT IS_ABSOLUTE "${original_file}")
 -    message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
 -  endif()
 -
 -  get_filename_component(exepath "${original_file}" PATH)
 -
 -  set(type "")
 -  gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
 -
 -  set(${type_var} "${type}" PARENT_SCOPE)
 -endfunction(gp_file_type)
 -
 -
 -# get_prerequisites target prerequisites_var exclude_system recurse dirs
 -#
 -# Get the list of shared library files required by ${target}. The list in
 -# the variable named ${prerequisites_var} should be empty on first entry to
 -# this function. On exit, ${prerequisites_var} will contain the list of
 -# required shared library files.
 -#
 -#  target is the full path to an executable file
 -#
 -#  prerequisites_var is the name of a CMake variable to contain the results
 -#
 -#  exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to
 -#   exclude them
 -#
 -#  recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites
 -#   recursively
 -#
 -#  exepath is the path to the top level executable used for @executable_path
 -#   replacment on the Mac
 -#
 -#  dirs is a list of paths where libraries might be found: these paths are
 -#   searched first when a target without any path info is given. Then standard
 -#   system locations are also searched: PATH, Framework locations, /usr/lib...
 -#
 -function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
 -  set(verbose 0)
 -  set(eol_char "E")
 -
 -  if(NOT IS_ABSOLUTE "${target}")
 -    message("warning: target '${target}' is not absolute...")
 -  endif(NOT IS_ABSOLUTE "${target}")
 -
 -  if(NOT EXISTS "${target}")
 -    message("warning: target '${target}' does not exist...")
 -  endif(NOT EXISTS "${target}")
 -
 -  # <setup-gp_tool-vars>
 -  #
 -  # Try to choose the right tool by default. Caller can set gp_tool prior to
 -  # calling this function to force using a different tool.
 -  #
 -  if("${gp_tool}" STREQUAL "")
 -    set(gp_tool "ldd")
 -    if(APPLE)
 -      set(gp_tool "otool")
 -    endif(APPLE)
 -    if(WIN32)
 -      set(gp_tool "dumpbin")
 -    endif(WIN32)
 -  endif("${gp_tool}" STREQUAL "")
 -
 -  set(gp_tool_known 0)
 -
 -  if("${gp_tool}" STREQUAL "ldd")
 -    set(gp_cmd_args "")
 -    set(gp_regex "^[\t ]*[^\t ]+ => ([^\t ]+).*${eol_char}$")
 -    set(gp_regex_cmp_count 1)
 -    set(gp_tool_known 1)
 -  endif("${gp_tool}" STREQUAL "ldd")
 -
 -  if("${gp_tool}" STREQUAL "otool")
 -    set(gp_cmd_args "-L")
 -    set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
 -    set(gp_regex_cmp_count 3)
 -    set(gp_tool_known 1)
 -  endif("${gp_tool}" STREQUAL "otool")
 -
 -  if("${gp_tool}" STREQUAL "dumpbin")
 -    set(gp_cmd_args "/dependents")
 -    set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$")
 -    set(gp_regex_cmp_count 1)
 -    set(gp_tool_known 1)
 -    set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
 -  endif("${gp_tool}" STREQUAL "dumpbin")
 -
 -  if(NOT gp_tool_known)
 -    message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
 -    message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
 -    message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
 -    return()
 -  endif(NOT gp_tool_known)
 -
 -  set(gp_cmd_paths ${gp_cmd_paths}
 -    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
 -    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
 -    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
 -    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
 -    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
 -    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
 -    "/usr/local/bin"
 -    "/usr/bin"
 -    )
 -
 -  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
 -
 -  if(NOT gp_cmd)
 -    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
 -    return()
 -  endif(NOT gp_cmd)
 -
 -  if("${gp_tool}" STREQUAL "dumpbin")
 -    # When running dumpbin, it also needs the "Common7/IDE" directory in the
 -    # PATH. It will already be in the PATH if being run from a Visual Studio
 -    # command prompt. Add it to the PATH here in case we are running from a
 -    # different command prompt.
 -    #
 -    get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
 -    get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
 -    if(EXISTS "${gp_cmd_dlls_dir}")
 -      # only add to the path if it is not already in the path
 -      if(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
 -        set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
 -      endif(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
 -    endif(EXISTS "${gp_cmd_dlls_dir}")
 -  endif("${gp_tool}" STREQUAL "dumpbin")
 -  #
 -  # </setup-gp_tool-vars>
 -
 -  if("${gp_tool}" STREQUAL "ldd")
 -    set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
 -    foreach(dir ${exepath} ${dirs})
 -      set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
 -    endforeach(dir)
 -  endif("${gp_tool}" STREQUAL "ldd")
 -
 -
 -  # Track new prerequisites at each new level of recursion. Start with an
 -  # empty list at each level:
 -  #
 -  set(unseen_prereqs)
 -
 -  # Run gp_cmd on the target:
 -  #
 -  execute_process(
 -    COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
 -    OUTPUT_VARIABLE gp_cmd_ov
 -    )
 -
 -  if("${gp_tool}" STREQUAL "ldd")
 -    set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
 -  endif("${gp_tool}" STREQUAL "ldd")
 -
 -  if(verbose)
 -    message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
 -    message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
 -    message(STATUS "</RawOutput>")
 -  endif(verbose)
 -
 -  get_filename_component(target_dir "${target}" PATH)
 -
 -  # Convert to a list of lines:
 -  #
 -  string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
 -  string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
 -
 -  # Analyze each line for file names that match the regular expression:
 -  #
 -  foreach(candidate ${candidates})
 -  if("${candidate}" MATCHES "${gp_regex}")
 -    # Extract information from each candidate:
 -    string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
 -
 -    if(gp_regex_cmp_count GREATER 1)
 -      string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
 -      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
 -      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
 -      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
 -    endif(gp_regex_cmp_count GREATER 1)
 -
 -    if(gp_regex_cmp_count GREATER 2)
 -      string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
 -      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
 -      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
 -      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
 -    endif(gp_regex_cmp_count GREATER 2)
 -
 -    # Use the raw_item as the list entries returned by this function. Use the
 -    # gp_resolve_item function to resolve it to an actual full path file if
 -    # necessary.
 -    #
 -    set(item "${raw_item}")
 -
 -    # Add each item unless it is excluded:
 -    #
 -    set(add_item 1)
 -
 -    if(${exclude_system})
 -      set(type "")
 -      gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
 -      if("${type}" STREQUAL "system")
 -        set(add_item 0)
 -      endif("${type}" STREQUAL "system")
 -    endif(${exclude_system})
 -
 -    if(add_item)
 -      list(LENGTH ${prerequisites_var} list_length_before_append)
 -      gp_append_unique(${prerequisites_var} "${item}")
 -      list(LENGTH ${prerequisites_var} list_length_after_append)
 -
 -      if(${recurse})
 -        # If item was really added, this is the first time we have seen it.
 -        # Add it to unseen_prereqs so that we can recursively add *its*
 -        # prerequisites...
 -        #
 -        # But first: resolve its name to an absolute full path name such
 -        # that the analysis tools can simply accept it as input.
 -        #
 -        if(NOT list_length_before_append EQUAL list_length_after_append)
 -          gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
 -          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
 -        endif(NOT list_length_before_append EQUAL list_length_after_append)
 -      endif(${recurse})
 -    endif(add_item)
 -  else("${candidate}" MATCHES "${gp_regex}")
 -    if(verbose)
 -      message(STATUS "ignoring non-matching line: '${candidate}'")
 -    endif(verbose)
 -  endif("${candidate}" MATCHES "${gp_regex}")
 -  endforeach(candidate)
 -
 -  list(LENGTH ${prerequisites_var} prerequisites_var_length)
 -  if(prerequisites_var_length GREATER 0)
 -    list(SORT ${prerequisites_var})
 -  endif(prerequisites_var_length GREATER 0)
 -  if(${recurse})
 -    set(more_inputs ${unseen_prereqs})
 -    foreach(input ${more_inputs})
 -      get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
 -    endforeach(input)
 -  endif(${recurse})
 -
 -  set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
 -endfunction(get_prerequisites)
 -
 -
 -# list_prerequisites target all exclude_system verbose
 -#
 -#  ARGV0 (target) is the full path to an executable file
 -#
 -#  optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only,
 -#   1 for all prerequisites recursively
 -#
 -#  optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system"
 -#   prerequisites , 1 to exclude them
 -#
 -#  optional ARGV3 (verbose) is 0 or 1: 0 to print only full path
 -#   names of prerequisites, 1 to print extra information
 -#
 -function(list_prerequisites target)
 -  if("${ARGV1}" STREQUAL "")
 -    set(all 1)
 -  else("${ARGV1}" STREQUAL "")
 -    set(all "${ARGV1}")
 -  endif("${ARGV1}" STREQUAL "")
 -
 -  if("${ARGV2}" STREQUAL "")
 -    set(exclude_system 0)
 -  else("${ARGV2}" STREQUAL "")
 -    set(exclude_system "${ARGV2}")
 -  endif("${ARGV2}" STREQUAL "")
 -
 -  if("${ARGV3}" STREQUAL "")
 -    set(verbose 0)
 -  else("${ARGV3}" STREQUAL "")
 -    set(verbose "${ARGV3}")
 -  endif("${ARGV3}" STREQUAL "")
 -
 -  set(count 0)
 -  set(count_str "")
 -  set(print_count "${verbose}")
 -  set(print_prerequisite_type "${verbose}")
 -  set(print_target "${verbose}")
 -  set(type_str "")
 -
 -  get_filename_component(exepath "${target}" PATH)
 -
 -  set(prereqs "")
 -  get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
 -
 -  if(print_target)
 -    message(STATUS "File '${target}' depends on:")
 -  endif(print_target)
 -
 -  foreach(d ${prereqs})
 -    math(EXPR count "${count} + 1")
 -
 -    if(print_count)
 -      set(count_str "${count}. ")
 -    endif(print_count)
 -
 -    if(print_prerequisite_type)
 -      gp_file_type("${target}" "${d}" type)
 -      set(type_str " (${type})")
 -    endif(print_prerequisite_type)
 -
 -    message(STATUS "${count_str}${d}${type_str}")
 -  endforeach(d)
 -endfunction(list_prerequisites)
 -
 -
 -# list_prerequisites_by_glob glob_arg glob_exp
 -#
 -#  glob_arg is GLOB or GLOB_RECURSE
 -#
 -#  glob_exp is a globbing expression used with "file(GLOB" to retrieve a list
 -#   of matching files. If a matching file is executable, its prerequisites are
 -#   listed.
 -#
 -# Any additional (optional) arguments provided are passed along as the
 -# optional arguments to the list_prerequisites calls.
 -#
 -function(list_prerequisites_by_glob glob_arg glob_exp)
 -  message(STATUS "=============================================================================")
 -  message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
 -  message(STATUS "")
 -  file(${glob_arg} file_list ${glob_exp})
 -  foreach(f ${file_list})
 -    is_file_executable("${f}" is_f_executable)
 -    if(is_f_executable)
 -      message(STATUS "=============================================================================")
 -      list_prerequisites("${f}" ${ARGN})
 -      message(STATUS "")
 -    endif(is_f_executable)
 -  endforeach(f)
 -endfunction(list_prerequisites_by_glob)
 +# GetPrerequisites.cmake +# +# This script provides functions to list the .dll, .dylib or .so files that an +# executable or shared library file depends on. (Its prerequisites.) +# +# It uses various tools to obtain the list of required shared library files: +#   dumpbin (Windows) +#   ldd (Linux/Unix) +#   otool (Mac OSX) +# +# The following functions are provided by this script: +#   gp_append_unique +#   is_file_executable +#   gp_item_default_embedded_path +#     (projects can override with gp_item_default_embedded_path_override) +#   gp_resolve_item +#     (projects can override with gp_resolve_item_override) +#   gp_resolved_file_type +#   gp_file_type +#   get_prerequisites +#   list_prerequisites +#   list_prerequisites_by_glob +# +# Requires CMake 2.6 or greater because it uses function, break, return and +# PARENT_SCOPE. + +#============================================================================= +# Copyright 2008-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +#  License text for the above reference.) + +# gp_append_unique list_var value +# +# Append value to the list variable ${list_var} only if the value is not +# already in the list. +# +function(gp_append_unique list_var value) +  set(contains 0) + +  foreach(item ${${list_var}}) +    if("${item}" STREQUAL "${value}") +      set(contains 1) +      break() +    endif("${item}" STREQUAL "${value}") +  endforeach(item) + +  if(NOT contains) +    set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE) +  endif(NOT contains) +endfunction(gp_append_unique) + + +# is_file_executable file result_var +# +# Return 1 in ${result_var} if ${file} is a binary executable. +# +# Return 0 in ${result_var} otherwise. +# +function(is_file_executable file result_var) +  # +  # A file is not executable until proven otherwise: +  # +  set(${result_var} 0 PARENT_SCOPE) + +  get_filename_component(file_full "${file}" ABSOLUTE) +  string(TOLOWER "${file_full}" file_full_lower) + +  # If file name ends in .exe on Windows, *assume* executable: +  # +  if(WIN32) +    if("${file_full_lower}" MATCHES "\\.exe$") +      set(${result_var} 1 PARENT_SCOPE) +      return() +    endif("${file_full_lower}" MATCHES "\\.exe$") + +    # A clause could be added here that uses output or return value of dumpbin +    # to determine ${result_var}. In 99%+? practical cases, the exe name +    # match will be sufficient... +    # +  endif(WIN32) + +  # Use the information returned from the Unix shell command "file" to +  # determine if ${file_full} should be considered an executable file... +  # +  # If the file command's output contains "executable" and does *not* contain +  # "text" then it is likely an executable suitable for prerequisite analysis +  # via the get_prerequisites macro. +  # +  if(UNIX) +    if(NOT file_cmd) +      find_program(file_cmd "file") +    endif(NOT file_cmd) + +    if(file_cmd) +      execute_process(COMMAND "${file_cmd}" "${file_full}" +        OUTPUT_VARIABLE file_ov +        OUTPUT_STRIP_TRAILING_WHITESPACE +        ) + +      # Replace the name of the file in the output with a placeholder token +      # (the string " _file_full_ ") so that just in case the path name of +      # the file contains the word "text" or "executable" we are not fooled +      # into thinking "the wrong thing" because the file name matches the +      # other 'file' command output we are looking for... +      # +      string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}") +      string(TOLOWER "${file_ov}" file_ov) + +      #message(STATUS "file_ov='${file_ov}'") +      if("${file_ov}" MATCHES "executable") +        #message(STATUS "executable!") +        if("${file_ov}" MATCHES "text") +          #message(STATUS "but text, so *not* a binary executable!") +        else("${file_ov}" MATCHES "text") +          set(${result_var} 1 PARENT_SCOPE) +          return() +        endif("${file_ov}" MATCHES "text") +      endif("${file_ov}" MATCHES "executable") +    else(file_cmd) +      message(STATUS "warning: No 'file' command, skipping execute_process...") +    endif(file_cmd) +  endif(UNIX) +endfunction(is_file_executable) + + +# gp_item_default_embedded_path item default_embedded_path_var +# +# Return the path that others should refer to the item by when the item +# is embedded inside a bundle. +# +# Override on a per-project basis by providing a project-specific +# gp_item_default_embedded_path_override function. +# +function(gp_item_default_embedded_path item default_embedded_path_var) + +  # On Windows and Linux, "embed" prerequisites in the same directory +  # as the executable by default: +  # +  set(path "@executable_path") +  set(overridden 0) + +  # On the Mac, relative to the executable depending on the type +  # of the thing we are embedding: +  # +  if(APPLE) +    # +    # The assumption here is that all executables in the bundle will be +    # in same-level-directories inside the bundle. The parent directory +    # of an executable inside the bundle should be MacOS or a sibling of +    # MacOS and all embedded paths returned from here will begin with +    # "@executable_path/../" and will work from all executables in all +    # such same-level-directories inside the bundle. +    # + +    # By default, embed things right next to the main bundle executable: +    # +    set(path "@executable_path/../../Contents/MacOS") + +    # Embed .dylibs right next to the main bundle executable: +    # +    if(item MATCHES "\\.dylib$") +      set(path "@executable_path/../MacOS") +      set(overridden 1) +    endif(item MATCHES "\\.dylib$") + +    # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS): +    # +    if(NOT overridden) +      if(item MATCHES "[^/]+\\.framework/") +        set(path "@executable_path/../Frameworks") +        set(overridden 1) +      endif(item MATCHES "[^/]+\\.framework/") +    endif(NOT overridden) +  endif() + +  # Provide a hook so that projects can override the default embedded location +  # of any given library by whatever logic they choose: +  # +  if(COMMAND gp_item_default_embedded_path_override) +    gp_item_default_embedded_path_override("${item}" path) +  endif(COMMAND gp_item_default_embedded_path_override) + +  set(${default_embedded_path_var} "${path}" PARENT_SCOPE) +endfunction(gp_item_default_embedded_path) + + +# gp_resolve_item context item exepath dirs resolved_item_var +# +# Resolve an item into an existing full path file. +# +# Override on a per-project basis by providing a project-specific +# gp_resolve_item_override function. +# +function(gp_resolve_item context item exepath dirs resolved_item_var) +  set(resolved 0) +  set(resolved_item "${item}") + +  # Is it already resolved? +  # +  if(EXISTS "${resolved_item}") +    set(resolved 1) +  endif(EXISTS "${resolved_item}") + +  if(NOT resolved) +    if(item MATCHES "@executable_path") +      # +      # @executable_path references are assumed relative to exepath +      # +      string(REPLACE "@executable_path" "${exepath}" ri "${item}") +      get_filename_component(ri "${ri}" ABSOLUTE) + +      if(EXISTS "${ri}") +        #message(STATUS "info: embedded item exists (${ri})") +        set(resolved 1) +        set(resolved_item "${ri}") +      else(EXISTS "${ri}") +        message(STATUS "warning: embedded item does not exist '${ri}'") +      endif(EXISTS "${ri}") +    endif(item MATCHES "@executable_path") +  endif(NOT resolved) + +  if(NOT resolved) +    if(item MATCHES "@loader_path") +      # +      # @loader_path references are assumed relative to the +      # PATH of the given "context" (presumably another library) +      # +      get_filename_component(contextpath "${context}" PATH) +      string(REPLACE "@loader_path" "${contextpath}" ri "${item}") +      get_filename_component(ri "${ri}" ABSOLUTE) + +      if(EXISTS "${ri}") +        #message(STATUS "info: embedded item exists (${ri})") +        set(resolved 1) +        set(resolved_item "${ri}") +      else(EXISTS "${ri}") +        message(STATUS "warning: embedded item does not exist '${ri}'") +      endif(EXISTS "${ri}") +    endif(item MATCHES "@loader_path") +  endif(NOT resolved) + +  if(NOT resolved) +    set(ri "ri-NOTFOUND") +    find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH) +    find_file(ri "${item}" ${exepath} ${dirs} /usr/lib) +    if(ri) +      #message(STATUS "info: 'find_file' in exepath/dirs (${ri})") +      set(resolved 1) +      set(resolved_item "${ri}") +      set(ri "ri-NOTFOUND") +    endif(ri) +  endif(NOT resolved) + +  if(NOT resolved) +    if(item MATCHES "[^/]+\\.framework/") +      set(fw "fw-NOTFOUND") +      find_file(fw "${item}" +        "~/Library/Frameworks" +        "/Library/Frameworks" +        "/System/Library/Frameworks" +      ) +      if(fw) +        #message(STATUS "info: 'find_file' found framework (${fw})") +        set(resolved 1) +        set(resolved_item "${fw}") +        set(fw "fw-NOTFOUND") +      endif(fw) +    endif(item MATCHES "[^/]+\\.framework/") +  endif(NOT resolved) + +  # Using find_program on Windows will find dll files that are in the PATH. +  # (Converting simple file names into full path names if found.) +  # +  if(WIN32) +  if(NOT resolved) +    set(ri "ri-NOTFOUND") +    find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH) +    find_program(ri "${item}" PATHS "${exepath};${dirs}") +    if(ri) +      #message(STATUS "info: 'find_program' in exepath/dirs (${ri})") +      set(resolved 1) +      set(resolved_item "${ri}") +      set(ri "ri-NOTFOUND") +    endif(ri) +  endif(NOT resolved) +  endif(WIN32) + +  # Provide a hook so that projects can override item resolution +  # by whatever logic they choose: +  # +  if(COMMAND gp_resolve_item_override) +    gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved) +  endif(COMMAND gp_resolve_item_override) + +  if(NOT resolved) +    message(STATUS " +warning: cannot resolve item '${item}' + +  possible problems: +    need more directories? +    need to use InstallRequiredSystemLibraries? +    run in install tree instead of build tree? +") +#    message(STATUS " +#****************************************************************************** +#warning: cannot resolve item '${item}' +# +#  possible problems: +#    need more directories? +#    need to use InstallRequiredSystemLibraries? +#    run in install tree instead of build tree? +# +#    context='${context}' +#    item='${item}' +#    exepath='${exepath}' +#    dirs='${dirs}' +#    resolved_item_var='${resolved_item_var}' +#****************************************************************************** +#") +  endif(NOT resolved) + +  set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE) +endfunction(gp_resolve_item) + + +# gp_resolved_file_type original_file file exepath dirs type_var +# +# Return the type of ${file} with respect to ${original_file}. String +# describing type of prerequisite is returned in variable named ${type_var}. +# +# Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file} +# values -- but only for non-embedded items. +# +# Possible types are: +#   system +#   local +#   embedded +#   other +# +function(gp_resolved_file_type original_file file exepath dirs type_var) +  #message(STATUS "**") + +  if(NOT IS_ABSOLUTE "${original_file}") +    message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file") +  endif() + +  set(is_embedded 0) +  set(is_local 0) +  set(is_system 0) + +  set(resolved_file "${file}") + +  if("${file}" MATCHES "^@(executable|loader)_path") +    set(is_embedded 1) +  endif() + +  if(NOT is_embedded) +    if(NOT IS_ABSOLUTE "${file}") +      gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file) +    endif() + +    string(TOLOWER "${original_file}" original_lower) +    string(TOLOWER "${resolved_file}" lower) + +    if(UNIX) +      if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)") +        set(is_system 1) +      endif() +    endif() + +    if(APPLE) +      if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)") +        set(is_system 1) +      endif() +    endif() + +    if(WIN32) +      string(TOLOWER "$ENV{SystemRoot}" sysroot) +      string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}") + +      string(TOLOWER "$ENV{windir}" windir) +      string(REGEX REPLACE "\\\\" "/" windir "${windir}") + +      if(lower MATCHES "^(${sysroot}/system|${windir}/system|${sysroot}/syswow|${windir}/syswow|(.*/)*msvc[^/]+dll)") +        set(is_system 1) +      endif() +    endif() + +    if(NOT is_system) +      get_filename_component(original_path "${original_lower}" PATH) +      get_filename_component(path "${lower}" PATH) +      if("${original_path}" STREQUAL "${path}") +        set(is_local 1) +      endif() +    endif() +  endif() + +  # Return type string based on computed booleans: +  # +  set(type "other") + +  if(is_system) +    set(type "system") +  elseif(is_embedded) +    set(type "embedded") +  elseif(is_local) +    set(type "local") +  endif() + +  #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'") +  #message(STATUS "                type: '${type}'") + +  if(NOT is_embedded) +    if(NOT IS_ABSOLUTE "${resolved_file}") +      if(lower MATCHES "^msvc[^/]+dll" AND is_system) +        message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'") +      else() +        message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect") +      endif() +    endif() +  endif() + +  set(${type_var} "${type}" PARENT_SCOPE) + +  #message(STATUS "**") +endfunction() + + +# gp_file_type original_file file type_var +# +# Return the type of ${file} with respect to ${original_file}. String +# describing type of prerequisite is returned in variable named ${type_var}. +# +# Possible types are: +#   system +#   local +#   embedded +#   other +# +function(gp_file_type original_file file type_var) +  if(NOT IS_ABSOLUTE "${original_file}") +    message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file") +  endif() + +  get_filename_component(exepath "${original_file}" PATH) + +  set(type "") +  gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type) + +  set(${type_var} "${type}" PARENT_SCOPE) +endfunction(gp_file_type) + + +# get_prerequisites target prerequisites_var exclude_system recurse dirs +# +# Get the list of shared library files required by ${target}. The list in +# the variable named ${prerequisites_var} should be empty on first entry to +# this function. On exit, ${prerequisites_var} will contain the list of +# required shared library files. +# +#  target is the full path to an executable file +# +#  prerequisites_var is the name of a CMake variable to contain the results +# +#  exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to +#   exclude them +# +#  recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites +#   recursively +# +#  exepath is the path to the top level executable used for @executable_path +#   replacment on the Mac +# +#  dirs is a list of paths where libraries might be found: these paths are +#   searched first when a target without any path info is given. Then standard +#   system locations are also searched: PATH, Framework locations, /usr/lib... +# +function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs) +  set(verbose 0) +  set(eol_char "E") + +  if(NOT IS_ABSOLUTE "${target}") +    message("warning: target '${target}' is not absolute...") +  endif(NOT IS_ABSOLUTE "${target}") + +  if(NOT EXISTS "${target}") +    message("warning: target '${target}' does not exist...") +  endif(NOT EXISTS "${target}") + +  # <setup-gp_tool-vars> +  # +  # Try to choose the right tool by default. Caller can set gp_tool prior to +  # calling this function to force using a different tool. +  # +  if("${gp_tool}" STREQUAL "") +    set(gp_tool "ldd") +    if(APPLE) +      set(gp_tool "otool") +    endif(APPLE) +    if(WIN32) +      set(gp_tool "dumpbin") +    endif(WIN32) +  endif("${gp_tool}" STREQUAL "") + +  set(gp_tool_known 0) + +  if("${gp_tool}" STREQUAL "ldd") +    set(gp_cmd_args "") +    set(gp_regex "^[\t ]*[^\t ]+ => ([^\t ]+).*${eol_char}$") +    set(gp_regex_cmp_count 1) +    set(gp_tool_known 1) +  endif("${gp_tool}" STREQUAL "ldd") + +  if("${gp_tool}" STREQUAL "otool") +    set(gp_cmd_args "-L") +    set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$") +    set(gp_regex_cmp_count 3) +    set(gp_tool_known 1) +  endif("${gp_tool}" STREQUAL "otool") + +  if("${gp_tool}" STREQUAL "dumpbin") +    set(gp_cmd_args "/dependents") +    set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$") +    set(gp_regex_cmp_count 1) +    set(gp_tool_known 1) +    set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE. +  endif("${gp_tool}" STREQUAL "dumpbin") + +  if(NOT gp_tool_known) +    message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...") +    message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'") +    message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.") +    return() +  endif(NOT gp_tool_known) + +  set(gp_cmd_paths ${gp_cmd_paths} +    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin" +    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin" +    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN" +    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN" +    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN" +    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN" +    "/usr/local/bin" +    "/usr/bin" +    ) + +  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths}) + +  if(NOT gp_cmd) +    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...") +    return() +  endif(NOT gp_cmd) + +  if("${gp_tool}" STREQUAL "dumpbin") +    # When running dumpbin, it also needs the "Common7/IDE" directory in the +    # PATH. It will already be in the PATH if being run from a Visual Studio +    # command prompt. Add it to the PATH here in case we are running from a +    # different command prompt. +    # +    get_filename_component(gp_cmd_dir "${gp_cmd}" PATH) +    get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE) +    if(EXISTS "${gp_cmd_dlls_dir}") +      # only add to the path if it is not already in the path +      if(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}") +        set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}") +      endif(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}") +    endif(EXISTS "${gp_cmd_dlls_dir}") +  endif("${gp_tool}" STREQUAL "dumpbin") +  # +  # </setup-gp_tool-vars> + +  if("${gp_tool}" STREQUAL "ldd") +    set(old_ld_env "$ENV{LD_LIBRARY_PATH}") +    foreach(dir ${exepath} ${dirs}) +      set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}") +    endforeach(dir) +  endif("${gp_tool}" STREQUAL "ldd") + + +  # Track new prerequisites at each new level of recursion. Start with an +  # empty list at each level: +  # +  set(unseen_prereqs) + +  # Run gp_cmd on the target: +  # +  execute_process( +    COMMAND ${gp_cmd} ${gp_cmd_args} ${target} +    OUTPUT_VARIABLE gp_cmd_ov +    ) + +  if("${gp_tool}" STREQUAL "ldd") +    set(ENV{LD_LIBRARY_PATH} "${old_ld_env}") +  endif("${gp_tool}" STREQUAL "ldd") + +  if(verbose) +    message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>") +    message(STATUS "gp_cmd_ov='${gp_cmd_ov}'") +    message(STATUS "</RawOutput>") +  endif(verbose) + +  get_filename_component(target_dir "${target}" PATH) + +  # Convert to a list of lines: +  # +  string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}") +  string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}") + +  # Analyze each line for file names that match the regular expression: +  # +  foreach(candidate ${candidates}) +  if("${candidate}" MATCHES "${gp_regex}") +    # Extract information from each candidate: +    string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}") + +    if(gp_regex_cmp_count GREATER 1) +      string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}") +      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}") +      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}") +      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}") +    endif(gp_regex_cmp_count GREATER 1) + +    if(gp_regex_cmp_count GREATER 2) +      string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}") +      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}") +      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}") +      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}") +    endif(gp_regex_cmp_count GREATER 2) + +    # Use the raw_item as the list entries returned by this function. Use the +    # gp_resolve_item function to resolve it to an actual full path file if +    # necessary. +    # +    set(item "${raw_item}") + +    # Add each item unless it is excluded: +    # +    set(add_item 1) + +    if(${exclude_system}) +      set(type "") +      gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type) +      if("${type}" STREQUAL "system") +        set(add_item 0) +      endif("${type}" STREQUAL "system") +    endif(${exclude_system}) + +    if(add_item) +      list(LENGTH ${prerequisites_var} list_length_before_append) +      gp_append_unique(${prerequisites_var} "${item}") +      list(LENGTH ${prerequisites_var} list_length_after_append) + +      if(${recurse}) +        # If item was really added, this is the first time we have seen it. +        # Add it to unseen_prereqs so that we can recursively add *its* +        # prerequisites... +        # +        # But first: resolve its name to an absolute full path name such +        # that the analysis tools can simply accept it as input. +        # +        if(NOT list_length_before_append EQUAL list_length_after_append) +          gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item) +          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}") +        endif(NOT list_length_before_append EQUAL list_length_after_append) +      endif(${recurse}) +    endif(add_item) +  else("${candidate}" MATCHES "${gp_regex}") +    if(verbose) +      message(STATUS "ignoring non-matching line: '${candidate}'") +    endif(verbose) +  endif("${candidate}" MATCHES "${gp_regex}") +  endforeach(candidate) + +  list(LENGTH ${prerequisites_var} prerequisites_var_length) +  if(prerequisites_var_length GREATER 0) +    list(SORT ${prerequisites_var}) +  endif(prerequisites_var_length GREATER 0) +  if(${recurse}) +    set(more_inputs ${unseen_prereqs}) +    foreach(input ${more_inputs}) +      get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}") +    endforeach(input) +  endif(${recurse}) + +  set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE) +endfunction(get_prerequisites) + + +# list_prerequisites target all exclude_system verbose +# +#  ARGV0 (target) is the full path to an executable file +# +#  optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only, +#   1 for all prerequisites recursively +# +#  optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system" +#   prerequisites , 1 to exclude them +# +#  optional ARGV3 (verbose) is 0 or 1: 0 to print only full path +#   names of prerequisites, 1 to print extra information +# +function(list_prerequisites target) +  if("${ARGV1}" STREQUAL "") +    set(all 1) +  else("${ARGV1}" STREQUAL "") +    set(all "${ARGV1}") +  endif("${ARGV1}" STREQUAL "") + +  if("${ARGV2}" STREQUAL "") +    set(exclude_system 0) +  else("${ARGV2}" STREQUAL "") +    set(exclude_system "${ARGV2}") +  endif("${ARGV2}" STREQUAL "") + +  if("${ARGV3}" STREQUAL "") +    set(verbose 0) +  else("${ARGV3}" STREQUAL "") +    set(verbose "${ARGV3}") +  endif("${ARGV3}" STREQUAL "") + +  set(count 0) +  set(count_str "") +  set(print_count "${verbose}") +  set(print_prerequisite_type "${verbose}") +  set(print_target "${verbose}") +  set(type_str "") + +  get_filename_component(exepath "${target}" PATH) + +  set(prereqs "") +  get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "") + +  if(print_target) +    message(STATUS "File '${target}' depends on:") +  endif(print_target) + +  foreach(d ${prereqs}) +    math(EXPR count "${count} + 1") + +    if(print_count) +      set(count_str "${count}. ") +    endif(print_count) + +    if(print_prerequisite_type) +      gp_file_type("${target}" "${d}" type) +      set(type_str " (${type})") +    endif(print_prerequisite_type) + +    message(STATUS "${count_str}${d}${type_str}") +  endforeach(d) +endfunction(list_prerequisites) + + +# list_prerequisites_by_glob glob_arg glob_exp +# +#  glob_arg is GLOB or GLOB_RECURSE +# +#  glob_exp is a globbing expression used with "file(GLOB" to retrieve a list +#   of matching files. If a matching file is executable, its prerequisites are +#   listed. +# +# Any additional (optional) arguments provided are passed along as the +# optional arguments to the list_prerequisites calls. +# +function(list_prerequisites_by_glob glob_arg glob_exp) +  message(STATUS "=============================================================================") +  message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'") +  message(STATUS "") +  file(${glob_arg} file_list ${glob_exp}) +  foreach(f ${file_list}) +    is_file_executable("${f}" is_f_executable) +    if(is_f_executable) +      message(STATUS "=============================================================================") +      list_prerequisites("${f}" ${ARGN}) +      message(STATUS "") +    endif(is_f_executable) +  endforeach(f) +endfunction(list_prerequisites_by_glob) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 62b764bb30..05f0492234 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -1,276 +1,276 @@ -# -*- cmake -*-
 -include(LLTestCommand)
 -include(GoogleMock)
 -
 -MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
 -  # Given a project name and a list of sourcefiles (with optional properties on each),
 -  # add targets to build and run the tests specified.
 -  # ASSUMPTIONS:
 -  # * this macro is being executed in the project file that is passed in
 -  # * current working SOURCE dir is that project dir
 -  # * there is a subfolder tests/ with test code corresponding to the filenames passed in
 -  # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
 -  #
 -  # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
 -  #
 -  # WARNING: do NOT modify this code without working with poppy -
 -  # there is another branch that will conflict heavily with any changes here.
 -INCLUDE(GoogleMock)
 -
 -
 -  IF(LL_TEST_VERBOSE)
 -    MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
 -  ENDIF(LL_TEST_VERBOSE)
 -
 -  # Start with the header and project-wide setup before making targets
 -  #project(UNITTEST_PROJECT_${project})
 -  # Setup includes, paths, etc
 -  SET(alltest_SOURCE_FILES
 -    ${CMAKE_SOURCE_DIR}/test/test.cpp
 -    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
 -    )
 -  SET(alltest_DEP_TARGETS
 -    # needed by the test harness itself
 -    ${APRUTIL_LIBRARIES}
 -    ${APR_LIBRARIES}
 -    llcommon
 -    )
 -  IF(NOT "${project}" STREQUAL "llmath")
 -    # add llmath as a dep unless the tested module *is* llmath!
 -    LIST(APPEND alltest_DEP_TARGETS
 -      llmath
 -      )
 -  ENDIF(NOT "${project}" STREQUAL "llmath")
 -  SET(alltest_INCLUDE_DIRS
 -    ${LLMATH_INCLUDE_DIRS}
 -    ${LLCOMMON_INCLUDE_DIRS}
 -    ${LIBS_OPEN_DIR}/test
 -    ${GOOGLEMOCK_INCLUDE_DIRS}
 -    )
 -  SET(alltest_LIBRARIES
 -    ${GOOGLEMOCK_LIBRARIES}
 -    ${PTHREAD_LIBRARY}
 -    ${WINDOWS_LIBRARIES}
 -    )
 -  # Headers, for convenience in targets.
 -  SET(alltest_HEADER_FILES
 -    ${CMAKE_SOURCE_DIR}/test/test.h
 -    )
 -
 -  # Use the default flags
 -  if (LINUX)
 -    SET(CMAKE_EXE_LINKER_FLAGS "")
 -  endif (LINUX)
 -
 -  # start the source test executable definitions
 -  SET(${project}_TEST_OUTPUT "")
 -  FOREACH (source ${sources})
 -    STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
 -    STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
 -    ENDIF(LL_TEST_VERBOSE)
 -
 -    #
 -    # Per-codefile additional / external source, header, and include dir property extraction
 -    #
 -    # Source
 -    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
 -    IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
 -      SET(${name}_test_additional_SOURCE_FILES "")
 -    ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
 -    SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
 -    ENDIF(LL_TEST_VERBOSE)
 -    # Headers
 -    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
 -    IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
 -      SET(${name}_test_additional_HEADER_FILES "")
 -    ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
 -    SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
 -    set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
 -    LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
 -    ENDIF(LL_TEST_VERBOSE)
 -    # Include dirs
 -    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
 -    IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
 -      SET(${name}_test_additional_INCLUDE_DIRS "")
 -    ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
 -    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS )
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
 -    ENDIF(LL_TEST_VERBOSE)
 -
 -
 -    # Setup target
 -    ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
 -    SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
 -
 -    #
 -    # Per-codefile additional / external project dep and lib dep property extraction
 -    #
 -    # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
 -    # Projects
 -    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
 -    IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
 -      SET(${name}_test_additional_PROJECTS "")
 -    ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
 -    # Libraries
 -    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
 -    IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
 -      SET(${name}_test_additional_LIBRARIES "")
 -    ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
 -      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
 -    ENDIF(LL_TEST_VERBOSE)
 -    # Add to project
 -    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
 -    # Compile-time Definitions
 -    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
 -     IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
 -       SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} )
 -       IF(LL_TEST_VERBOSE)
 -         MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
 -       ENDIF(LL_TEST_VERBOSE)
 -     ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
 -     
 -    #
 -    # Setup test targets
 -    #
 -    GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
 -    SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
 -    SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
 -
 -    # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd  = ${TEST_CMD}")
 -    ENDIF(LL_TEST_VERBOSE)
 -
 -    SET_TEST_PATH(LD_LIBRARY_PATH)
 -    LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
 -    IF(LL_TEST_VERBOSE)
 -      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script  = ${TEST_SCRIPT_CMD}")
 -    ENDIF(LL_TEST_VERBOSE)
 -    # Add test 
 -    ADD_CUSTOM_COMMAND(
 -        OUTPUT ${TEST_OUTPUT}
 -        COMMAND ${TEST_SCRIPT_CMD}
 -        DEPENDS PROJECT_${project}_TEST_${name}
 -        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
 -        )
 -    # Why not add custom target and add POST_BUILD command?
 -    # Slightly less uncertain behavior
 -    # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
 -    # > I did not use a post build step as I could not make it notify of a 
 -    # > failure after the first time you build and fail a test. - daveh 2009-04-20
 -    LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
 -  ENDFOREACH (source)
 -
 -  # Add the test runner target per-project
 -  # (replaces old _test_ok targets all over the place)
 -  ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
 -  ADD_DEPENDENCIES(${project} ${project}_tests)
 -ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
 -
 -FUNCTION(LL_ADD_INTEGRATION_TEST 
 -    testname
 -    additional_source_files
 -    library_dependencies
 -# variable args
 -    )
 -  if(TEST_DEBUG)
 -    message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
 -  endif(TEST_DEBUG)
 -  
 -  SET(source_files
 -    tests/${testname}_test.cpp
 -    ${CMAKE_SOURCE_DIR}/test/test.cpp
 -    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
 -    ${additional_source_files}
 -    )
 -
 -  SET(libraries
 -    ${library_dependencies}
 -    ${GOOGLEMOCK_LIBRARIES}
 -    ${PTHREAD_LIBRARY}
 -    )
 -
 -  # Add test executable build target
 -  if(TEST_DEBUG)
 -    message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
 -  endif(TEST_DEBUG)
 -  ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
 -  SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
 -  if(STANDALONE)
 -    SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
 -  endif(STANDALONE)
 -
 -  # Add link deps to the executable
 -  if(TEST_DEBUG)
 -    message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
 -  endif(TEST_DEBUG)
 -  TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
 -
 -  # Create the test running command
 -  SET(test_command ${ARGN})
 -  GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
 -  LIST(FIND test_command "{}" test_exe_pos)
 -  IF(test_exe_pos LESS 0)
 -    # The {} marker means "the full pathname of the test executable."
 -    # test_exe_pos -1 means we didn't find it -- so append the test executable
 -    # name to $ARGN, the variable part of the arg list. This is convenient
 -    # shorthand for both straightforward execution of the test program (empty
 -    # $ARGN) and for running a "wrapper" program of some kind accepting the
 -    # pathname of the test program as the last of its args. You need specify
 -    # {} only if the test program's pathname isn't the last argument in the
 -    # desired command line.
 -    LIST(APPEND test_command "${TEST_EXE}")
 -  ELSE (test_exe_pos LESS 0)
 -    # Found {} marker at test_exe_pos. Remove the {}...
 -    LIST(REMOVE_AT test_command test_exe_pos)
 -    # ...and replace it with the actual name of the test executable.
 -    LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
 -  ENDIF (test_exe_pos LESS 0)
 -
 -  SET_TEST_PATH(LD_LIBRARY_PATH)
 -  LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
 -
 -  if(TEST_DEBUG)
 -    message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
 -  endif(TEST_DEBUG)
 -
 -  ADD_CUSTOM_COMMAND(
 -    TARGET INTEGRATION_TEST_${testname}
 -    POST_BUILD
 -    COMMAND ${TEST_SCRIPT_CMD}
 -    )
 -
 -  # Use CTEST? Not sure how to yet...
 -  # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
 -
 -ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
 -
 -MACRO(SET_TEST_PATH LISTVAR)
 -  IF(WINDOWS)
 -    # We typically build/package only Release variants of third-party
 -    # libraries, so append the Release staging dir in case the library being
 -    # sought doesn't have a debug variant.
 -    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
 -  ELSEIF(DARWIN)
 -    # We typically build/package only Release variants of third-party
 -    # libraries, so append the Release staging dir in case the library being
 -    # sought doesn't have a debug variant.
 -    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
 -  ELSE(WINDOWS)
 -    # Linux uses a single staging directory anyway.
 -    IF (STANDALONE)
 -      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
 -    ELSE (STANDALONE)
 -      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
 -    ENDIF (STANDALONE)
 -  ENDIF(WINDOWS)
 -ENDMACRO(SET_TEST_PATH)
 +# -*- cmake -*- +include(LLTestCommand) +include(GoogleMock) + +MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) +  # Given a project name and a list of sourcefiles (with optional properties on each), +  # add targets to build and run the tests specified. +  # ASSUMPTIONS: +  # * this macro is being executed in the project file that is passed in +  # * current working SOURCE dir is that project dir +  # * there is a subfolder tests/ with test code corresponding to the filenames passed in +  # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT) +  # +  # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code +  # +  # WARNING: do NOT modify this code without working with poppy - +  # there is another branch that will conflict heavily with any changes here. +INCLUDE(GoogleMock) + + +  IF(LL_TEST_VERBOSE) +    MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") +  ENDIF(LL_TEST_VERBOSE) + +  # Start with the header and project-wide setup before making targets +  #project(UNITTEST_PROJECT_${project}) +  # Setup includes, paths, etc +  SET(alltest_SOURCE_FILES +    ${CMAKE_SOURCE_DIR}/test/test.cpp +    ${CMAKE_SOURCE_DIR}/test/lltut.cpp +    ) +  SET(alltest_DEP_TARGETS +    # needed by the test harness itself +    ${APRUTIL_LIBRARIES} +    ${APR_LIBRARIES} +    llcommon +    ) +  IF(NOT "${project}" STREQUAL "llmath") +    # add llmath as a dep unless the tested module *is* llmath! +    LIST(APPEND alltest_DEP_TARGETS +      llmath +      ) +  ENDIF(NOT "${project}" STREQUAL "llmath") +  SET(alltest_INCLUDE_DIRS +    ${LLMATH_INCLUDE_DIRS} +    ${LLCOMMON_INCLUDE_DIRS} +    ${LIBS_OPEN_DIR}/test +    ${GOOGLEMOCK_INCLUDE_DIRS} +    ) +  SET(alltest_LIBRARIES +    ${GOOGLEMOCK_LIBRARIES} +    ${PTHREAD_LIBRARY} +    ${WINDOWS_LIBRARIES} +    ) +  # Headers, for convenience in targets. +  SET(alltest_HEADER_FILES +    ${CMAKE_SOURCE_DIR}/test/test.h +    ) + +  # Use the default flags +  if (LINUX) +    SET(CMAKE_EXE_LINKER_FLAGS "") +  endif (LINUX) + +  # start the source test executable definitions +  SET(${project}_TEST_OUTPUT "") +  FOREACH (source ${sources}) +    STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} ) +    STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} ) +    IF(LL_TEST_VERBOSE) +      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})") +    ENDIF(LL_TEST_VERBOSE) + +    # +    # Per-codefile additional / external source, header, and include dir property extraction +    # +    # Source +    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES) +    IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND) +      SET(${name}_test_additional_SOURCE_FILES "") +    ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND) +    SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} ) +    IF(LL_TEST_VERBOSE) +      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}") +    ENDIF(LL_TEST_VERBOSE) +    # Headers +    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES) +    IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND) +      SET(${name}_test_additional_HEADER_FILES "") +    ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND) +    SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) +    set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) +    LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES}) +    IF(LL_TEST_VERBOSE) +      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}") +    ENDIF(LL_TEST_VERBOSE) +    # Include dirs +    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS) +    IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) +      SET(${name}_test_additional_INCLUDE_DIRS "") +    ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) +    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS ) +    IF(LL_TEST_VERBOSE) +      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}") +    ENDIF(LL_TEST_VERBOSE) + + +    # Setup target +    ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) +    SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") + +    # +    # Per-codefile additional / external project dep and lib dep property extraction +    # +    # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19 +    # Projects +    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS) +    IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND) +      SET(${name}_test_additional_PROJECTS "") +    ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND) +    # Libraries +    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES) +    IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND) +      SET(${name}_test_additional_LIBRARIES "") +    ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND) +    IF(LL_TEST_VERBOSE) +      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}") +      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}") +    ENDIF(LL_TEST_VERBOSE) +    # Add to project +    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} ) +    # Compile-time Definitions +    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS) +     IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND) +       SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} ) +       IF(LL_TEST_VERBOSE) +         MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}") +       ENDIF(LL_TEST_VERBOSE) +     ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND) +      +    # +    # Setup test targets +    # +    GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION) +    SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt) +    SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) + +    # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19 +    IF(LL_TEST_VERBOSE) +      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd  = ${TEST_CMD}") +    ENDIF(LL_TEST_VERBOSE) + +    SET_TEST_PATH(LD_LIBRARY_PATH) +    LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD}) +    IF(LL_TEST_VERBOSE) +      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script  = ${TEST_SCRIPT_CMD}") +    ENDIF(LL_TEST_VERBOSE) +    # Add test  +    ADD_CUSTOM_COMMAND( +        OUTPUT ${TEST_OUTPUT} +        COMMAND ${TEST_SCRIPT_CMD} +        DEPENDS PROJECT_${project}_TEST_${name} +        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +        ) +    # Why not add custom target and add POST_BUILD command? +    # Slightly less uncertain behavior +    # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19 +    # > I did not use a post build step as I could not make it notify of a  +    # > failure after the first time you build and fail a test. - daveh 2009-04-20 +    LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT}) +  ENDFOREACH (source) + +  # Add the test runner target per-project +  # (replaces old _test_ok targets all over the place) +  ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) +  ADD_DEPENDENCIES(${project} ${project}_tests) +ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS) + +FUNCTION(LL_ADD_INTEGRATION_TEST  +    testname +    additional_source_files +    library_dependencies +# variable args +    ) +  if(TEST_DEBUG) +    message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on") +  endif(TEST_DEBUG) +   +  SET(source_files +    tests/${testname}_test.cpp +    ${CMAKE_SOURCE_DIR}/test/test.cpp +    ${CMAKE_SOURCE_DIR}/test/lltut.cpp +    ${additional_source_files} +    ) + +  SET(libraries +    ${library_dependencies} +    ${GOOGLEMOCK_LIBRARIES} +    ${PTHREAD_LIBRARY} +    ) + +  # Add test executable build target +  if(TEST_DEBUG) +    message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") +  endif(TEST_DEBUG) +  ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) +  SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") +  if(STANDALONE) +    SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}") +  endif(STANDALONE) + +  # Add link deps to the executable +  if(TEST_DEBUG) +    message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})") +  endif(TEST_DEBUG) +  TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries}) + +  # Create the test running command +  SET(test_command ${ARGN}) +  GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION) +  LIST(FIND test_command "{}" test_exe_pos) +  IF(test_exe_pos LESS 0) +    # The {} marker means "the full pathname of the test executable." +    # test_exe_pos -1 means we didn't find it -- so append the test executable +    # name to $ARGN, the variable part of the arg list. This is convenient +    # shorthand for both straightforward execution of the test program (empty +    # $ARGN) and for running a "wrapper" program of some kind accepting the +    # pathname of the test program as the last of its args. You need specify +    # {} only if the test program's pathname isn't the last argument in the +    # desired command line. +    LIST(APPEND test_command "${TEST_EXE}") +  ELSE (test_exe_pos LESS 0) +    # Found {} marker at test_exe_pos. Remove the {}... +    LIST(REMOVE_AT test_command test_exe_pos) +    # ...and replace it with the actual name of the test executable. +    LIST(INSERT test_command test_exe_pos "${TEST_EXE}") +  ENDIF (test_exe_pos LESS 0) + +  SET_TEST_PATH(LD_LIBRARY_PATH) +  LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command}) + +  if(TEST_DEBUG) +    message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}") +  endif(TEST_DEBUG) + +  ADD_CUSTOM_COMMAND( +    TARGET INTEGRATION_TEST_${testname} +    POST_BUILD +    COMMAND ${TEST_SCRIPT_CMD} +    ) + +  # Use CTEST? Not sure how to yet... +  # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD}) + +ENDFUNCTION(LL_ADD_INTEGRATION_TEST) + +MACRO(SET_TEST_PATH LISTVAR) +  IF(WINDOWS) +    # We typically build/package only Release variants of third-party +    # libraries, so append the Release staging dir in case the library being +    # sought doesn't have a debug variant. +    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release) +  ELSEIF(DARWIN) +    # We typically build/package only Release variants of third-party +    # libraries, so append the Release staging dir in case the library being +    # sought doesn't have a debug variant. +    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib) +  ELSE(WINDOWS) +    # Linux uses a single staging directory anyway. +    IF (STANDALONE) +      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib) +    ELSE (STANDALONE) +      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) +    ENDIF (STANDALONE) +  ENDIF(WINDOWS) +ENDMACRO(SET_TEST_PATH) diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index c9cb1cd6e7..5e540ad8c5 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -97,7 +97,11 @@ void LLAudioEngine::setDefaults()  	}  	mMasterGain = 1.f; -	mInternalGain = 0.f; +	// Setting mInternalGain to an out of range value fixes the issue reported in STORM-830. +	// There is an edge case in setMasterGain during startup which prevents setInternalGain from  +	// being called if the master volume setting and mInternalGain both equal 0, so using -1 forces +	// the if statement in setMasterGain to execute when the viewer starts up. +	mInternalGain = -1.f;  	mNextWindUpdate = 0.f;  	mStreamingAudioImpl = NULL; diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 8f02391e75..c32a776c3f 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -92,6 +92,17 @@ LLFILE*	LLFile::_fsopen(const std::string& filename, const char* mode, int shari  #endif  } +int	LLFile::close(LLFILE * file) +{ +	int ret_value = 0; +	if (file) +	{ +		ret_value = fclose(file); +	} +	return ret_value; +} + +  int	LLFile::remove(const std::string& filename)  {  #if	LL_WINDOWS diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 4913af7cb5..dd7d36513a 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -71,6 +71,8 @@ public:  	static	LLFILE*	fopen(const std::string& filename,const char* accessmode);	/* Flawfinder: ignore */  	static	LLFILE*	_fsopen(const std::string& filename,const char* accessmode,int	sharingFlag); +	static	int		close(LLFILE * file); +  	// perms is a permissions mask like 0777 or 0700.  In most cases it will  	// be overridden by the user's umask.  It is ignored on Windows.  	static	int		mkdir(const std::string& filename, int perms = 0700); diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index a502d1a7eb..51fcd5b717 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -26,6 +26,12 @@  #include "linden_common.h" +#include "llmemory.h" + +#if MEM_TRACK_MEM +#include "llthread.h" +#endif +  #if defined(LL_WINDOWS)  # include <windows.h>  # include <psapi.h> @@ -37,8 +43,6 @@  # include <unistd.h>  #endif -#include "llmemory.h" -  //----------------------------------------------------------------------------  //static @@ -105,6 +109,20 @@ U64 LLMemory::getCurrentRSS()  	return counters.WorkingSetSize;  } +//static  +U32 LLMemory::getWorkingSetSize() +{ +    PROCESS_MEMORY_COUNTERS pmc ; +	U32 ret = 0 ; + +    if (GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) ) +	{ +		ret = pmc.WorkingSetSize ; +	} + +	return ret ; +} +  #elif defined(LL_DARWIN)  /*  @@ -151,6 +169,11 @@ U64 LLMemory::getCurrentRSS()  	return residentSize;  } +U32 LLMemory::getWorkingSetSize() +{ +	return 0 ; +} +  #elif defined(LL_LINUX)  U64 LLMemory::getCurrentRSS() @@ -185,6 +208,11 @@ bail:  	return rss;  } +U32 LLMemory::getWorkingSetSize() +{ +	return 0 ; +} +  #elif LL_SOLARIS  #include <sys/types.h>  #include <sys/stat.h> @@ -213,6 +241,12 @@ U64 LLMemory::getCurrentRSS()  	return((U64)proc_psinfo.pr_rssize * 1024);  } + +U32 LLMemory::getWorkingSetSize() +{ +	return 0 ; +} +  #else  U64 LLMemory::getCurrentRSS() @@ -220,4 +254,144 @@ U64 LLMemory::getCurrentRSS()  	return 0;  } +U32 LLMemory::getWorkingSetSize() +{ +	return 0 ; +} +  #endif + +//-------------------------------------------------------------------------------------------------- +#if MEM_TRACK_MEM +#include "llframetimer.h" + +//static  +LLMemTracker* LLMemTracker::sInstance = NULL ; + +LLMemTracker::LLMemTracker() +{ +	mLastAllocatedMem = LLMemory::getWorkingSetSize() ; +	mCapacity = 128 ;	 +	mCurIndex = 0 ; +	mCounter = 0 ; +	mDrawnIndex = 0 ; +	mPaused = FALSE ; + +	mMutexp = new LLMutex(NULL) ; +	mStringBuffer = new char*[128] ; +	mStringBuffer[0] = new char[mCapacity * 128] ; +	for(S32 i = 1 ; i < mCapacity ; i++) +	{ +		mStringBuffer[i] = mStringBuffer[i-1] + 128 ; +	} +} + +LLMemTracker::~LLMemTracker() +{ +	delete[] mStringBuffer[0] ; +	delete[] mStringBuffer; +	delete mMutexp ; +} + +//static  +LLMemTracker* LLMemTracker::getInstance() +{ +	if(!sInstance) +	{ +		sInstance = new LLMemTracker() ; +	} +	return sInstance ; +} + +//static  +void LLMemTracker::release()  +{ +	if(sInstance) +	{ +		delete sInstance ; +		sInstance = NULL ; +	} +} + +//static +void LLMemTracker::track(const char* function, const int line) +{ +	static const S32 MIN_ALLOCATION = 0 ; //1KB + +	if(mPaused) +	{ +		return ; +	} + +	U32 allocated_mem = LLMemory::getWorkingSetSize() ; + +	LLMutexLock lock(mMutexp) ; + +	S32 delta_mem = allocated_mem - mLastAllocatedMem ; +	mLastAllocatedMem = allocated_mem ; + +	if(delta_mem <= 0) +	{ +		return ; //occupied memory does not grow +	} + +	if(delta_mem < MIN_ALLOCATION) +	{ +		return ; +	} +		 +	char* buffer = mStringBuffer[mCurIndex++] ; +	F32 time = (F32)LLFrameTimer::getElapsedSeconds() ; +	S32 hours = (S32)(time / (60*60)); +	S32 mins = (S32)((time - hours*(60*60)) / 60); +	S32 secs = (S32)((time - hours*(60*60) - mins*60)); +	strcpy(buffer, function) ; +	sprintf(buffer + strlen(function), " line: %d DeltaMem: %d (bytes) Time: %d:%02d:%02d", line, delta_mem, hours,mins,secs) ; + +	if(mCounter < mCapacity) +	{ +		mCounter++ ; +	} +	if(mCurIndex >= mCapacity) +	{ +		mCurIndex = 0 ;		 +	} +} + + +//static  +void LLMemTracker::preDraw(BOOL pause)  +{ +	mMutexp->lock() ; + +	mPaused = pause ; +	mDrawnIndex = mCurIndex - 1; +	mNumOfDrawn = 0 ; +} +	 +//static  +void LLMemTracker::postDraw()  +{ +	mMutexp->unlock() ; +} + +//static  +const char* LLMemTracker::getNextLine()  +{ +	if(mNumOfDrawn >= mCounter) +	{ +		return NULL ; +	} +	mNumOfDrawn++; + +	if(mDrawnIndex < 0) +	{ +		mDrawnIndex = mCapacity - 1 ; +	} + +	return mStringBuffer[mDrawnIndex--] ; +} + +#endif //MEM_TRACK_MEM +//-------------------------------------------------------------------------------------------------- + diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 9bf4248bb7..11406f59b0 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -26,7 +26,7 @@  #ifndef LLMEMORY_H  #define LLMEMORY_H - +#include "llmemtype.h"  extern S32 gTotalDAlloc;  extern S32 gTotalDAUse; @@ -44,10 +44,55 @@ public:  	// Return the resident set size of the current process, in bytes.  	// Return value is zero if not known.  	static U64 getCurrentRSS(); +	static U32 getWorkingSetSize();  private:  	static char* reserveMem;  }; +//---------------------------------------------------------------------------- +#if MEM_TRACK_MEM +class LLMutex ; +class LL_COMMON_API LLMemTracker +{ +private: +	LLMemTracker() ; +	~LLMemTracker() ; + +public: +	static void release() ; +	static LLMemTracker* getInstance() ; + +	void track(const char* function, const int line) ; +	void preDraw(BOOL pause) ; +	void postDraw() ; +	const char* getNextLine() ; + +private: +	static LLMemTracker* sInstance ; +	 +	char**     mStringBuffer ; +	S32        mCapacity ; +	U32        mLastAllocatedMem ; +	S32        mCurIndex ; +	S32        mCounter; +	S32        mDrawnIndex; +	S32        mNumOfDrawn; +	BOOL       mPaused; +	LLMutex*   mMutexp ; +}; + +#define MEM_TRACK_RELEASE LLMemTracker::release() ; +#define MEM_TRACK         LLMemTracker::getInstance()->track(__FUNCTION__, __LINE__) ; + +#else // MEM_TRACK_MEM + +#define MEM_TRACK_RELEASE +#define MEM_TRACK + +#endif // MEM_TRACK_MEM + +//---------------------------------------------------------------------------- +  // LLRefCount moved to llrefcount.h  // LLPointer moved to llpointer.h diff --git a/indra/llcommon/llmemtype.cpp b/indra/llcommon/llmemtype.cpp index fe83f87d4b..6290a7158f 100644 --- a/indra/llcommon/llmemtype.cpp +++ b/indra/llcommon/llmemtype.cpp @@ -229,3 +229,4 @@ char const * LLMemType::getNameFromID(S32 id)  	return DeclareMemType::mNameList[id];  } +//-------------------------------------------------------------------------------------------------- diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 356e0f4c0f..7d5afe92dc 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,7 +28,7 @@  #define LL_LLVERSIONVIEWER_H  const S32 LL_VERSION_MAJOR = 2; -const S32 LL_VERSION_MINOR = 5; +const S32 LL_VERSION_MINOR = 6;  const S32 LL_VERSION_PATCH = 0;  const S32 LL_VERSION_BUILD = 0; diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index b46a99e030..39211bf7fa 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -274,11 +274,11 @@ LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)  	++sRawImageCount;  } -LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only) -	: LLImageBase() -{ -	createFromFile(filename, j2c_lowest_mip_only); -} +//LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only) +//	: LLImageBase() +//{ +//	createFromFile(filename, j2c_lowest_mip_only); +//}  LLImageRaw::~LLImageRaw()  { @@ -1178,7 +1178,7 @@ file_extensions[] =  	{ "png", IMG_CODEC_PNG }  };  #define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions) - +#if 0  static std::string find_file(std::string &name, S8 *codec)  {  	std::string tname; @@ -1196,7 +1196,7 @@ static std::string find_file(std::string &name, S8 *codec)  	}  	return std::string("");  } - +#endif  EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)  {  	for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++) @@ -1206,7 +1206,7 @@ EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)  	}  	return IMG_CODEC_INVALID;  } - +#if 0  bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only)  {  	std::string name = filename; @@ -1313,7 +1313,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip  	return true;  } - +#endif  //---------------------------------------------------------------------------  // LLImageFormatted  //--------------------------------------------------------------------------- diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index bca7e915fa..825b9aab1a 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -164,7 +164,7 @@ public:  	LLImageRaw(U16 width, U16 height, S8 components);  	LLImageRaw(U8 *data, U16 width, U16 height, S8 components);  	// Construct using createFromFile (used by tools) -	LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false); +	//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);  	/*virtual*/ void deleteData();  	/*virtual*/ U8* allocateData(S32 size = -1); @@ -226,7 +226,7 @@ public:  protected:  	// Create an image from a local file (generally used in tools) -	bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false); +	//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);  	void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );  	void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index fe737e2072..2cc7d3c460 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -50,8 +50,6 @@ LLPngWrapper::LLPngWrapper()  	  mCompressionType( 0 ),  	  mFilterMethod( 0 ),  	  mFinalSize( 0 ), -	  mHasBKGD(false), -	  mBackgroundColor(),  	  mGamma(0.f)  {  } @@ -111,9 +109,9 @@ void LLPngWrapper::writeFlush(png_structp png_ptr)  }  // Read the PNG file using the libpng.  The low-level interface is used here -// because we want to do various transformations (including setting the -// matte background if any, and applying gama) which can't be done with -// the high-level interface. The scanline also begins at the bottom of +// because we want to do various transformations (including applying gama) +// which can't be done with the high-level interface. +// The scanline also begins at the bottom of  // the image (per SecondLife conventions) instead of at the top, so we  // must assign row-pointers in "reverse" order.  BOOL LLPngWrapper::readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop) @@ -201,8 +199,7 @@ void LLPngWrapper::normalizeImage()  	//		2. Convert grayscales to RGB  	//		3. Create alpha layer from transparency  	//		4. Ensure 8-bpp for all images -	//		5. Apply background matte if any -	//		6. Set (or guess) gamma +	//		5. Set (or guess) gamma  	if (mColorType == PNG_COLOR_TYPE_PALETTE)  	{ @@ -229,12 +226,6 @@ void LLPngWrapper::normalizeImage()  	{  		png_set_strip_16(mReadPngPtr);  	} -	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor); -	if (mHasBKGD) -	{ -		png_set_background(mReadPngPtr, mBackgroundColor, -			PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); -	}  #if LL_DARWIN  	const F64 SCREEN_GAMMA = 1.8; @@ -261,7 +252,6 @@ void LLPngWrapper::updateMetaData()      mBitDepth = png_get_bit_depth(mReadPngPtr, mReadInfoPtr);      mColorType = png_get_color_type(mReadPngPtr, mReadInfoPtr);  	mChannels = png_get_channels(mReadPngPtr, mReadInfoPtr); -	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor);  }  // Method to write raw image into PNG at dest. The raw scanline begins diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 47a4207d66..739f435996 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -88,9 +88,6 @@ private:  	U32 mFinalSize; -	bool mHasBKGD; -	png_color_16p mBackgroundColor; -  	F64 mGamma;  	std::string mErrorMessage; diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp index b46a6e03d2..3e2c05a6e6 100644 --- a/indra/llmath/llbbox.cpp +++ b/indra/llmath/llbbox.cpp @@ -89,6 +89,19 @@ void LLBBox::addBBoxAgent(const LLBBox& b)  	}  } +LLBBox LLBBox::getAxisAligned() const +{ +	// no rotation = axis aligned rotation +	LLBBox aligned(mPosAgent, LLQuaternion(), LLVector3(), LLVector3()); + +	// add the center point so that it's not empty +	aligned.addPointAgent(mPosAgent); + +	// add our BBox +	aligned.addBBoxAgent(*this); + +	return aligned; +}  void LLBBox::expand( F32 delta )  { @@ -147,6 +160,15 @@ BOOL LLBBox::containsPointAgent(const LLVector3& p) const  	return containsPointLocal(point_local);  } +LLVector3 LLBBox::getMinAgent() const +{ +	return localToAgent(mMinLocal); +} + +LLVector3 LLBBox::getMaxAgent() const +{ +	return localToAgent(mMaxLocal); +}  /*  LLBBox operator*(const LLBBox &a, const LLMatrix4 &b) diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h index 5b911793f0..28e69b75e1 100644 --- a/indra/llmath/llbbox.h +++ b/indra/llmath/llbbox.h @@ -51,9 +51,11 @@ public:  	const LLVector3&	getPositionAgent() const			{ return mPosAgent; }  	const LLQuaternion&	getRotation() const					{ return mRotation; } +	LLVector3           getMinAgent() const;  	const LLVector3&	getMinLocal() const					{ return mMinLocal; }  	void				setMinLocal( const LLVector3& min )	{ mMinLocal = min; } +	LLVector3           getMaxAgent() const;  	const LLVector3&	getMaxLocal() const					{ return mMaxLocal; }  	void				setMaxLocal( const LLVector3& max )	{ mMaxLocal = max; } @@ -80,6 +82,8 @@ public:  	LLVector3			localToAgentBasis(const LLVector3& v) const;  	LLVector3			agentToLocalBasis(const LLVector3& v) const; +	// Get the smallest possible axis aligned bbox that contains this bbox +	LLBBox              getAxisAligned() const;  //	friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 14e1ca8d43..71b92962fb 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4406,19 +4406,54 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)  BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  { +	BOOL ret = FALSE ;  	if (mTypeMask & CAP_MASK)  	{ -		return createCap(volume, partial_build); +		ret = createCap(volume, partial_build);  	}  	else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))  	{ -		return createSide(volume, partial_build); +		ret = createSide(volume, partial_build);  	}  	else  	{  		llerrs << "Unknown/uninitialized face type!" << llendl; -		return FALSE;  	} + +	//update the range of the texture coordinates +	if(ret) +	{ +		mTexCoordExtents[0].setVec(1.f, 1.f) ; +		mTexCoordExtents[1].setVec(0.f, 0.f) ; + +		U32 end = mVertices.size() ; +		for(U32 i = 0 ; i < end ; i++) +		{ +			if(mTexCoordExtents[0].mV[0] > mVertices[i].mTexCoord.mV[0]) +			{ +				mTexCoordExtents[0].mV[0] = mVertices[i].mTexCoord.mV[0] ; +			} +			if(mTexCoordExtents[1].mV[0] < mVertices[i].mTexCoord.mV[0]) +			{ +				mTexCoordExtents[1].mV[0] = mVertices[i].mTexCoord.mV[0] ; +			} + +			if(mTexCoordExtents[0].mV[1] > mVertices[i].mTexCoord.mV[1]) +			{ +				mTexCoordExtents[0].mV[1] = mVertices[i].mTexCoord.mV[1] ; +			} +			if(mTexCoordExtents[1].mV[1] < mVertices[i].mTexCoord.mV[1]) +			{ +				mTexCoordExtents[1].mV[1] = mVertices[i].mTexCoord.mV[1] ; +			}			 +		} +		mTexCoordExtents[0].mV[0] = llmax(0.f, mTexCoordExtents[0].mV[0]) ; +		mTexCoordExtents[0].mV[1] = llmax(0.f, mTexCoordExtents[0].mV[1]) ; +		mTexCoordExtents[1].mV[0] = llmin(1.f, mTexCoordExtents[1].mV[0]) ; +		mTexCoordExtents[1].mV[1] = llmin(1.f, mTexCoordExtents[1].mV[1]) ; +	} + +	return ret ;  }  void	LerpPlanarVertex(LLVolumeFace::VertexData& v0, diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index d48a79ee46..28b9895ff3 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -831,6 +831,7 @@ public:  	S32 mNumT;  	LLVector3 mExtents[2]; //minimum and maximum point of face +	LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.  	std::vector<VertexData> mVertices;  	std::vector<U16>	mIndices; diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp index 3ba2dfb104..e0410906fb 100644 --- a/indra/llmessage/llcircuit.cpp +++ b/indra/llmessage/llcircuit.cpp @@ -87,6 +87,7 @@ LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id,  	mPingDelayAveraged((F32)INITIAL_PING_VALUE_MSEC),   	mUnackedPacketCount(0),  	mUnackedPacketBytes(0), +	mLastPacketInTime(0.0),  	mLocalEndPointID(),  	mPacketsOut(0),  	mPacketsIn(0),  @@ -667,6 +668,8 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)  		mHighestPacketID = llmax(mHighestPacketID, id);  	} +	// Save packet arrival time +	mLastPacketInTime = LLMessageSystem::getMessageTimeSeconds();  	// Have we received anything on this circuit yet?  	if (0 == mPacketsIn) diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h index 874c0c0bee..d1c400c6a2 100644 --- a/indra/llmessage/llcircuit.h +++ b/indra/llmessage/llcircuit.h @@ -122,7 +122,7 @@ public:  	U32			getPacketsLost() const;  	TPACKETID	getPacketOutID() const;  	BOOL		getTrusted() const; -	F32 getAgeInSeconds() const; +	F32			getAgeInSeconds() const;  	S32			getUnackedPacketCount() const	{ return mUnackedPacketCount; }  	S32			getUnackedPacketBytes() const	{ return mUnackedPacketBytes; }  	F64         getNextPingSendTime() const { return mNextPingSendTime; } @@ -130,6 +130,7 @@ public:                      { return mOutOfOrderRate.meanValue(scale); }      U32         getLastPacketGap() const { return mLastPacketGap; }      LLHost      getHost() const { return mHost; } +	F64			getLastPacketInTime() const		{ return mLastPacketInTime;	}  	LLThrottleGroup &getThrottleGroup()		{	return mThrottles; } @@ -248,6 +249,7 @@ protected:  	S32										mUnackedPacketCount;  	S32										mUnackedPacketBytes; +	F64										mLastPacketInTime;		// Time of last packet arrival  	LLUUID									mLocalEndPointID; diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index b9b974ec4f..7b796a0fa8 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -42,9 +42,6 @@ const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);  // Does the sun move?  const U32 REGION_FLAGS_SUN_FIXED				= (1 << 4); -// Tax free zone (no taxes on objects, land, etc.) -const U32 REGION_FLAGS_TAX_FREE					= (1 << 5); -  // Can't change the terrain heightfield, even on owned parcels,  // but can plant trees and grass.  const U32 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6); @@ -54,17 +51,12 @@ const U32 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);  // All content wiped once per night  const U32 REGION_FLAGS_SANDBOX					= (1 << 8); -const U32 REGION_FLAGS_NULL_LAYER				= (1 << 9); -// const U32 REGION_FLAGS_SKIP_AGENT_ACTION		= (1 << 10); -const U32 REGION_FLAGS_HARD_ALLOW_LAND_TRANSFER	= (1 << 10);	// Region allows land reselling -// const U32 REGION_FLAGS_SKIP_UPDATE_INTEREST_LIST= (1 << 11); -const U32 REGION_FLAGS_HARD_ALLOW_POST_CLASSIFIED	= (1 << 11);	// Region allows posting of classified ads  const U32 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies  const U32 REGION_FLAGS_SKIP_SCRIPTS				= (1 << 13);  const U32 REGION_FLAGS_SKIP_PHYSICS				= (1 << 14); // Skip all physics  const U32 REGION_FLAGS_EXTERNALLY_VISIBLE		= (1 << 15); -//const U32 REGION_FLAGS_MAINLAND_VISIBLE			= (1 << 16); -const U32 REGION_FLAGS_PUBLIC_ALLOWED			= (1 << 17); +const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16); +const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);  const U32 REGION_FLAGS_BLOCK_DWELL				= (1 << 18);  // Is flight allowed? @@ -81,18 +73,13 @@ const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS		= (1 << 21);  const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT		= (1 << 22);  const U32 REGION_FLAGS_DENY_ANONYMOUS			= (1 << 23); -// const U32 REGION_FLAGS_DENY_IDENTIFIED			= (1 << 24); -// const U32 REGION_FLAGS_DENY_TRANSACTED			= (1 << 25);  const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26); -// const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27); // We no longer support ELAR -  const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);  const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);  const U32 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30); -const U32 REGION_FLAGS_SKIP_MONO_SCRIPTS	= (1 << 31);  const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |  								 REGION_FLAGS_ALLOW_SET_HOME | @@ -105,7 +92,6 @@ const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK  									   | REGION_FLAGS_ALLOW_SET_HOME;  const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE -									 | REGION_FLAGS_PUBLIC_ALLOWED	  									 | REGION_FLAGS_SUN_FIXED  									 | REGION_FLAGS_DENY_ANONYMOUS  									 | REGION_FLAGS_DENY_AGEUNVERIFIED; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 3c1d031ff5..861bde5c89 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -403,7 +403,7 @@ S32 LLTextureEntry::setOffsetT(F32 t)  S32 LLTextureEntry::setRotation(F32 theta)  { -	if (mRotation != theta) +	if (mRotation != theta && llfinite(theta))  	{  		mRotation = theta;  		return TEM_CHANGE_TEXTURE; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 65940cb067..e8e98211f1 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1063,16 +1063,6 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_  {  	if (gGL.getTexUnit(0)->bind(this, false, true))  	{ -		if(gGLManager.mDebugGPU) -		{ -			llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ; -			checkTexSize(true) ; -			llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << -				" : " << (S32)mComponents << llcallstacksendl ; - -			log_glerror() ; -		} -  		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);  		mGLTextureCreated = true;  		stop_glerror(); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index d30697e178..c425782715 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -272,9 +272,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  	initFromParams(p); -	// chrome floaters don't take focus at all -	setFocusRoot(!getIsChrome()); -  	initFloater(p);  } @@ -2910,8 +2907,6 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str  	params.from_xui = true;  	applyXUILayout(params, parent);   	initFromParams(params); -	// chrome floaters don't take focus at all -	setFocusRoot(!getIsChrome());  	initFloater(params); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 6c0d47ef63..32d7be377a 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1637,6 +1637,10 @@ LLMenuScrollItem::LLMenuScrollItem(const Params& p)  	}  	LLButton::Params bparams; + +	// Disabled the Return key handling by LLMenuScrollItem instead of +	// passing the key press to the currently selected menu item. See STORM-385. +	bparams.commit_on_return(false);  	bparams.mouse_opaque(true);  	bparams.scale_image(false);  	bparams.click_callback(p.scroll_callback); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index cd0f0e36b0..cc9edfcdea 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1367,7 +1367,6 @@ LLNotifications::TemplateNames LLNotifications::getTemplateNames() const  typedef std::map<std::string, std::string> StringMap;  void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)  { -	//llwarns << "replaceSubstitutionStrings" << llendl;  	// walk the list of attributes looking for replacements  	for (LLXMLAttribList::iterator it=node->mAttributes.begin();  		 it != node->mAttributes.end(); ++it) @@ -1381,13 +1380,12 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)  			if (found != replacements.end())  			{  				replacement = found->second; -				//llwarns << "replaceSubstituionStrings: value: " << value << " repl: " << replacement << llendl; - +				lldebugs << "replaceSubstitutionStrings: value: \"" << value << "\" repl: \"" << replacement << "\"." << llendl;  				it->second->setValue(replacement);  			}  			else  			{ -				llwarns << "replaceSubstituionStrings FAILURE: value: " << value << " repl: " << replacement << llendl; +				llwarns << "replaceSubstitutionStrings FAILURE: could not find replacement \"" << value << "\"." << llendl;  			}  		}  	} diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 4f7b4be526..9db1feafd1 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -36,6 +36,7 @@  #include "llcachename.h"  #include "lltrans.h"  #include "lluicolortable.h" +#include "message.h"  #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" @@ -684,8 +685,8 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa  LLStyle::Params LLUrlEntryGroup::getStyle() const  {  	LLStyle::Params style_params = LLUrlEntryBase::getStyle(); -	style_params.color = LLUIColorTable::instance().getColor("GroupLinkColor"); -	style_params.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor"); +	style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); +	style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");  	return style_params;  } @@ -740,6 +741,13 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const  	return LLUrlEntryBase::getLocation(url);  } +// LLUrlEntryParcel statics. +LLUUID	LLUrlEntryParcel::sAgentID(LLUUID::null); +LLUUID	LLUrlEntryParcel::sSessionID(LLUUID::null); +LLHost	LLUrlEntryParcel::sRegionHost(LLHost::invalid); +bool	LLUrlEntryParcel::sDisconnected(false); +std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers; +  ///  /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,  /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about @@ -751,13 +759,88 @@ LLUrlEntryParcel::LLUrlEntryParcel()  							boost::regex::perl|boost::regex::icase);  	mMenuName = "menu_url_parcel.xml";  	mTooltip = LLTrans::getString("TooltipParcelUrl"); + +	sParcelInfoObservers.insert(this); +} + +LLUrlEntryParcel::~LLUrlEntryParcel() +{ +	sParcelInfoObservers.erase(this);  }  std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)  { +	LLSD path_array = LLURI(url).pathArray(); +	S32 path_parts = path_array.size(); + +	if (path_parts < 3) // no parcel id +	{ +		llwarns << "Failed to parse url [" << url << "]" << llendl; +		return url; +	} + +	std::string parcel_id_string = unescapeUrl(path_array[2]); // parcel id + +	// Add an observer to call LLUrlLabelCallback when we have parcel name. +	addObserver(parcel_id_string, url, cb); + +	LLUUID parcel_id(parcel_id_string); + +	sendParcelInfoRequest(parcel_id); +  	return unescapeUrl(url);  } +void LLUrlEntryParcel::sendParcelInfoRequest(const LLUUID& parcel_id) +{ +	if (sRegionHost == LLHost::invalid || sDisconnected) return; + +	LLMessageSystem *msg = gMessageSystem; +	msg->newMessage("ParcelInfoRequest"); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, sAgentID ); +	msg->addUUID("SessionID", sSessionID); +	msg->nextBlock("Data"); +	msg->addUUID("ParcelID", parcel_id); +	msg->sendReliable(sRegionHost); +} + +void LLUrlEntryParcel::onParcelInfoReceived(const std::string &id, const std::string &label) +{ +	callObservers(id, label.empty() ? LLTrans::getString("RegionInfoError") : label, mIcon); +} + +// static +void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data) +{ +	std::string label(LLStringUtil::null); +	if (!parcel_data.name.empty()) +	{ +		label = parcel_data.name; +	} +	// If parcel name is empty use Sim_name (x, y, z) for parcel label. +	else if (!parcel_data.sim_name.empty()) +	{ +		S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS; +		S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS; +		S32 region_z = llround(parcel_data.global_z); + +		label = llformat("%s (%d, %d, %d)", +				parcel_data.sim_name.c_str(), region_x, region_y, region_z); +	} + +	for (std::set<LLUrlEntryParcel*>::iterator iter = sParcelInfoObservers.begin(); +			iter != sParcelInfoObservers.end(); +			++iter) +	{ +		LLUrlEntryParcel* url_entry = *iter; +		if (url_entry) +		{ +			url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label); +		} +	} +} +  //  // LLUrlEntryPlace Describes secondlife://<location> URLs  // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 1791739061..5f82721c0f 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -31,6 +31,9 @@  #include "lluuid.h"  #include "lluicolor.h"  #include "llstyle.h" + +#include "llhost.h" // for resolving parcel name by parcel id +  #include <boost/signals2.hpp>  #include <boost/regex.hpp>  #include <string> @@ -285,8 +288,44 @@ private:  class LLUrlEntryParcel : public LLUrlEntryBase  {  public: +	struct LLParcelData +	{ +		LLUUID		parcel_id; +		std::string	name; +		std::string	sim_name; +		F32			global_x; +		F32			global_y; +		F32			global_z; +	}; +  	LLUrlEntryParcel(); +	~LLUrlEntryParcel();  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + +	// Sends a parcel info request to sim. +	void sendParcelInfoRequest(const LLUUID& parcel_id); + +	// Calls observers of certain parcel id providing them with parcel label. +	void onParcelInfoReceived(const std::string &id, const std::string &label); + +	// Processes parcel label and triggers notifying observers. +	static void processParcelInfo(const LLParcelData& parcel_data); + +	// Next 4 setters are used to update agent and viewer connection information +	// upon events like user login, viewer disconnect and user changing region host. +	// These setters are made public to be accessible from newview and should not be +	// used in other cases. +	static void setAgentID(const LLUUID& id) { sAgentID = id; } +	static void setSessionID(const LLUUID& id) { sSessionID = id; } +	static void setRegionHost(const LLHost& host) { sRegionHost = host; } +	static void setDisconnected(bool disconnected) { sDisconnected = disconnected; } + +private: +	static LLUUID						sAgentID; +	static LLUUID						sSessionID; +	static LLHost						sRegionHost; +	static bool							sDisconnected; +	static std::set<LLUrlEntryParcel*>	sParcelInfoObservers;  };  /// diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index f30704cb22..96ebe83826 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -30,6 +30,7 @@  #include "llavatarnamecache.h"  #include "llcachename.h"  #include "lluuid.h" +#include "message.h"  #include <string> @@ -191,3 +192,20 @@ LLFontGL* LLFontGL::getFontDefault()  {  	return NULL;   } + +char* _PREHASH_AgentData = "AgentData"; +char* _PREHASH_AgentID = "AgentID"; + +LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS); + +LLMessageSystem* gMessageSystem = NULL; + +// +// Stub implementation for LLMessageSystem +// +void LLMessageSystem::newMessage(const char *name) { } +void LLMessageSystem::nextBlockFast(const char *blockname) { } +void LLMessageSystem::nextBlock(const char *blockname) { } +void LLMessageSystem::addUUIDFast( const char *varname, const LLUUID& uuid) { } +void LLMessageSystem::addUUID( const char *varname, const LLUUID& uuid) { } +S32 LLMessageSystem::sendReliable(const LLHost &host) { return 0; } diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 64556bcb4c..cb898e385f 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -101,10 +101,18 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)  		{  			if (0 != LLFile::remove(fullpath))  			{ +				retry_count++;  				result = errno;  				llwarns << "Problem removing " << fullpath << " - errorcode: "  						<< result << " attempt " << retry_count << llendl; -				ms_sleep(1000); + +				if(retry_count >= 5) +				{ +					llwarns << "Failed to remove " << fullpath << llendl ; +					return count ; +				} + +				ms_sleep(100);  			}  			else  			{ @@ -113,8 +121,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)  					llwarns << "Successfully removed " << fullpath << llendl;  				}  				break; -			} -			retry_count++; +			}			  		}  		count++;  	} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a61c35abd2..af6beacdfa 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -530,6 +530,7 @@ set(viewer_SOURCE_FILES      llviewerregion.cpp      llviewershadermgr.cpp      llviewerstats.cpp +    llviewerstatsrecorder.cpp      llviewertexteditor.cpp      llviewertexture.cpp      llviewertextureanim.cpp @@ -1063,6 +1064,7 @@ set(viewer_HEADER_FILES      llviewerregion.h      llviewershadermgr.h      llviewerstats.h +    llviewerstatsrecorder.h      llviewertexteditor.h      llviewertexture.h      llviewertextureanim.h @@ -1716,6 +1718,17 @@ set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH  if (LINUX)    set(product SecondLife-${ARCH}-${viewer_VERSION}) +  # These are the generated targets that are copied to package/ +  set(COPY_INPUT_DEPENDENCIES +	${VIEWER_BINARY_NAME} +	linux-crash-logger +	linux-updater +	SLPlugin +	media_plugin_webkit +	media_plugin_gstreamer010 +	llcommon +	) +    add_custom_command(        OUTPUT ${product}.tar.bz2        COMMAND ${PYTHON_EXECUTABLE} @@ -1733,18 +1746,11 @@ if (LINUX)          --login_channel=${VIEWER_LOGIN_CHANNEL}          --source=${CMAKE_CURRENT_SOURCE_DIR}          --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched -      DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +      DEPENDS +        ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +        ${COPY_INPUT_DEPENDENCIES}        ) -  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 media_plugin_webkit) - -  if (PACKAGE) -    add_custom_target(package ALL DEPENDS ${product}.tar.bz2) -    add_dependencies(package linux-crash-logger-target) -    add_dependencies(package linux-updater-target) -    check_message_template(package) -  endif (PACKAGE) -    add_custom_command(      OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched      COMMAND ${PYTHON_EXECUTABLE} @@ -1764,9 +1770,15 @@ if (LINUX)        ${COPY_INPUT_DEPENDENCIES}      COMMENT "Performing viewer_manifest copy"      ) -     +    add_custom_target(copy_l_viewer_manifest ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched)  -  add_dependencies(copy_l_viewer_manifest "${VIEWER_BINARY_NAME}" linux-crash-logger-target linux-updater-target) + +  if (PACKAGE) +    add_custom_target(package ALL DEPENDS ${product}.tar.bz2) +    # Make sure we don't run two instances of viewer_manifest.py at the same time. +    add_dependencies(package copy_l_viewer_manifest) +    check_message_template(package) +  endif (PACKAGE)  endif (LINUX)  if (DARWIN) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ca587302b2..6630d8f400 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -928,39 +928,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>BulkChangeIncludeAnimations</key> -    <map> -      <key>Comment</key> -      <string>Bulk permission changes affect animations</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map> -    <key>BulkChangeIncludeAnimations</key> -    <map> -      <key>Comment</key> -      <string>Bulk permission changes affect animations</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map> -    <key>BulkChangeIncludeAnimations</key> -    <map> -      <key>Comment</key> -      <string>Bulk permission changes affect animations</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>BulkChangeIncludeBodyParts</key>      <map>        <key>Comment</key> @@ -1173,18 +1140,7 @@      <key>CacheLocationTopFolder</key>      <map>        <key>Comment</key> -      <string>Controls the top folder location of the local disk cache</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string /> -    </map>	 -    <key>CacheLocationTopFolder</key> -    <map> -      <key>Comment</key> -      <string>Controls the location of the local disk cache</string> +      <string>Controls the top folder location of the the local disk cache</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -1201,7 +1157,7 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>20000</integer> +      <integer>128</integer>      </map>      <key>CacheSize</key>      <map> @@ -1874,6 +1830,17 @@        <key>Value</key>        <integer>0</integer>      </map> +   <key>DebugShowMemory</key> +    <map> +      <key>Comment</key> +      <string>Show Total Allocated Memory</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DebugShowRenderInfo</key>      <map>        <key>Comment</key> @@ -1896,10 +1863,21 @@      <key>Value</key>      <integer>0</integer>    </map> +  <key>DebugShowTextureInfo</key> +    <map> +      <key>Comment</key> +      <string>Show inertested texture info</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>    <key>DebugShowTime</key>      <map>        <key>Comment</key> -      <string>Show depth buffer contents</string> +      <string>Show time info</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -3097,17 +3075,6 @@          <string>http://viewer-settings.secondlife.com</string>      </map>      <key>FPSLogFrequency</key> -    <map> -      <key>Comment</key> -      <string>Seconds between display of FPS in log (0 for never)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>60.0</real> -    </map> -    <key>FPSLogFrequency</key>          <map>          <key>Comment</key>              <string>Seconds between display of FPS in log (0 for never)</string> @@ -6062,17 +6029,6 @@      <key>OutBandwidth</key>      <map>        <key>Comment</key> -      <string>Expand render stats display</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map> -    <key>OutBandwidth</key> -    <map> -      <key>Comment</key>        <string>Outgoing bandwidth throttle (bps)</string>        <key>Persist</key>        <integer>1</integer> @@ -11430,8 +11386,6 @@        <key>Type</key>        <string>LLSD</string>        <key>Value</key> -      <map> -      </map>      </map>      <key>VFSOldSize</key>      <map> @@ -11587,17 +11541,6 @@        <key>Value</key>        <string></string>      </map> -    <key>VivoxDebugSIPURIHostName</key> -    <map> -      <key>Comment</key> -      <string>Hostname portion of vivox SIP URIs (empty string for the default).</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string></string> -    </map>      <key>VivoxDebugVoiceAccountServerURI</key>      <map>        <key>Comment</key> @@ -12423,16 +12366,5 @@        <key>Value</key>        <string>name</string>      </map> -    <key>ReleaseNotesURL</key> -    <map> -      <key>Comment</key> -      <string>Release notes URL template</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string>http://secondlife.com/app/releasenotes/?channel=[CHANNEL]&version=[VERSION]</string> -    </map>  </map>  </llsd> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 77552663ab..7d908df5ce 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -64,6 +64,7 @@  #include "lltool.h"  #include "lltoolmgr.h"  #include "lltrans.h" +#include "llurlentry.h"  #include "llviewercontrol.h"  #include "llviewerdisplay.h"  #include "llviewerjoystick.h" @@ -649,6 +650,10 @@ void LLAgent::setRegion(LLViewerRegion *regionp)  	}  	mRegionp = regionp; +	// Pass the region host to LLUrlEntryParcel to resolve parcel name +	// with a server request. +	LLUrlEntryParcel::setRegionHost(getRegionHost()); +  	// Must shift hole-covering water object locations because local  	// coordinate frame changed.  	LLWorld::getInstance()->updateWaterObjects(); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 80734b0d41..f40fed5ad3 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1300,8 +1300,16 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)  		return false;  	} -	// Check whether the outfit contains the full set of body parts (shape+skin+hair+eyes). -	return getCanMakeFolderIntoOutfit(outfit_cat_id); +	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702). +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true); +	gInventory.collectDescendentsIf(outfit_cat_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		is_worn); +	return items.size() > 0;  }  void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9361ae20cf..a23f809b71 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -44,6 +44,7 @@  #include "llagentwearables.h"  #include "llwindow.h"  #include "llviewerstats.h" +#include "llviewerstatsrecorder.h"  #include "llmd5.h"  #include "llpumpio.h"  #include "llmimetypes.h" @@ -93,6 +94,7 @@  #include "llmemory.h"  #include "llprimitive.h"  #include "llurlaction.h" +#include "llurlentry.h"  #include "llvfile.h"  #include "llvfsthread.h"  #include "llvolumemgr.h" @@ -471,8 +473,6 @@ static void settings_to_globals()  	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");  	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");  	LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); - -	LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");  }  static void settings_modify() @@ -666,6 +666,10 @@ bool LLAppViewer::init()      mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::initClass(); +#endif +      // *NOTE:Mani - LLCurl::initClass is not thread safe.       // Called before threads are created.      LLCurl::initClass(); @@ -848,6 +852,9 @@ bool LLAppViewer::init()  	gGLActive = TRUE;  	initWindow(); +	// initWindow also initializes the Feature List, so now we can initialize this global. +	LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); +  	// call all self-registered classes  	LLInitClassList::instance().fireCallbacks(); @@ -989,6 +996,8 @@ bool LLAppViewer::init()  	LLAgentLanguage::init(); + +  	return true;  } @@ -1287,7 +1296,7 @@ bool LLAppViewer::mainLoop()  				resumeMainloopTimeout();  				pingMainloopTimeout("Main:End"); -			}			 +			}	  		}  		catch(std::bad_alloc)  		{			 @@ -1389,16 +1398,6 @@ bool LLAppViewer::cleanup()  	}  	mPlugins.clear(); -	//---------------------------------------------- -	//this test code will be removed after the test -	//test manual call stack tracer -	if(gSavedSettings.getBOOL("QAMode")) -	{ -		LLError::LLCallStacks::print() ; -	} -	//end of the test code -	//---------------------------------------------- -  	//flag all elements as needing to be destroyed immediately  	// to ensure shutdown order  	LLMortician::setZealous(TRUE); @@ -1709,6 +1708,10 @@ bool LLAppViewer::cleanup()  	}  	LLMetricPerformanceTesterBasic::cleanClass() ; +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::cleanupClass(); +#endif +  	llinfos << "Cleaning up Media and Textures" << llendflush;  	//Note: @@ -1776,6 +1779,8 @@ bool LLAppViewer::cleanup()  	ll_close_fail_log(); +	MEM_TRACK_RELEASE +      llinfos << "Goodbye!" << llendflush;  	// return 0; @@ -3072,35 +3077,32 @@ void LLAppViewer::initMarkerFile()  	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);  	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); -	  	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())  	{  		gLastExecEvent = LAST_EXEC_FROZE;  		LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;  	}     -      	if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))  	{ -		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << LAST_EXEC_LLERROR_CRASH << LL_ENDL;  		gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; +		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		LLAPRFile::remove(logout_marker_file);  	}  	if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))  	{ -		llinfos << "Last exec LLError crashed, setting LastExecEvent to " << LAST_EXEC_LLERROR_CRASH << llendl;  		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;  		else gLastExecEvent = LAST_EXEC_LLERROR_CRASH; +		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		LLAPRFile::remove(llerror_marker_file);  	}  	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))  	{ -		LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << LAST_EXEC_OTHER_CRASH << LL_ENDL;  		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;  		else gLastExecEvent = LAST_EXEC_OTHER_CRASH; +		LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		LLAPRFile::remove(error_marker_file);  	} -	 -	LLAPRFile::remove(logout_marker_file); -	LLAPRFile::remove(llerror_marker_file); -	LLAPRFile::remove(error_marker_file); -	 +  	// No new markers if another instance is running.  	if(anotherInstanceRunning())   	{ @@ -4576,6 +4578,10 @@ void LLAppViewer::disconnectViewer()  	cleanup_xfer_manager();  	gDisconnected = TRUE; + +	// Pass the connection state to LLUrlEntryParcel not to attempt +	// parcel info requests while disconnected. +	LLUrlEntryParcel::setDisconnected(gDisconnected);  }  void LLAppViewer::forceErrorLLError() diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index f12bc16d4b..dd5bc74b2a 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -126,6 +126,7 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)  			break;  	}  	LLUploadDialog::modalUploadFinished(); +	LLFilePicker::instance().reset();  // unlock file picker when bulk upload fails  }  //virtual  diff --git a/indra/newview/llcapabilityprovider.h b/indra/newview/llcapabilityprovider.h index a6e743f625..9d91245597 100644 --- a/indra/newview/llcapabilityprovider.h +++ b/indra/newview/llcapabilityprovider.h @@ -46,7 +46,7 @@ public:      /**       * Get host to which to send that capability request.       */ -    virtual LLHost getHost() const = 0; +    virtual const LLHost& getHost() const = 0;      /**       * Describe this LLCapabilityProvider for logging etc.       */ diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 4a1ba6f1b5..6f02192d0a 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -319,7 +319,7 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )  // This is called when the main floatercustomize panel is closed.  // Since this class has pointers up to its parents, we need to cleanup  // this class first in order to avoid a crash. -void LLColorSwatchCtrl::onParentFloaterClosed() +void LLColorSwatchCtrl::closeFloaterColorPicker()  {  	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();  	if (pickerp) diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index cd859ea128..5bdd1712d2 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -100,7 +100,7 @@ public:  	/*virtual*/ void	setEnabled( BOOL enabled );  	static void		onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE ); -	void			onParentFloaterClosed(); +	void			closeFloaterColorPicker();  protected:  	BOOL			mValid; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index a3d2941114..f781d5f3ff 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -177,10 +177,6 @@ void LLViewerDynamicTexture::postRender(BOOL success)  				generateGLTexture() ;  			} -			if(gGLManager.mDebugGPU) -			{ -				LLGLState::dumpStates() ; -			}  			success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);  		}  	} @@ -220,12 +216,6 @@ BOOL LLViewerDynamicTexture::updateAllInstances()  			LLViewerDynamicTexture *dynamicTexture = *iter;  			if (dynamicTexture->needsRender())  			{				 -				if(gGLManager.mDebugGPU) -				{				 -					llinfos << "class type: " << (S32)dynamicTexture->getType() << llendl; -					LLGLState::dumpStates() ; -				} -  				glClear(GL_DEPTH_BUFFER_BIT);  				gDepthDirty = TRUE; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 2471da9da5..fe201a6773 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1155,7 +1155,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_tcoord)  		{  			LLVector2 tc = vf.mVertices[i].mTexCoord; -		 +		     			if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)  			{  				LLVector3 vec = vf.mVertices[i].mPosition;  @@ -1331,7 +1331,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		mTexExtents[0].setVec(0,0);  		mTexExtents[1].setVec(1,1);  		xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt); -		xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);		 +		xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt); +		 +		F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ; +		F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ; +		mTexExtents[0][0] *= es ; +		mTexExtents[1][0] *= es ; +		mTexExtents[0][1] *= et ; +		mTexExtents[1][1] *= et ;  	}  	mLastVertexBuffer = mVertexBuffer; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ca2ef5f5b8..4e16cc4217 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -290,11 +290,9 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)  	mTableVersion = version;  	LLFeatureList *flp = NULL; -	while (!file.eof() && file.good()) +	while (file >> name)  	{  		char buffer[MAX_STRING];		 /*Flawfinder: ignore*/ - -		file >> name;  		if (name.substr(0,2) == "//")  		{ @@ -303,13 +301,6 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)  			continue;  		} -		if (name.empty()) -		{ -			// This is a blank line -			file.getline(buffer, MAX_STRING); -			continue; -		} -  		if (name == "list")  		{  			if (flp) diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 1b94d8cbcd..80920c80d6 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -83,7 +83,8 @@ LLFloaterMap::~LLFloaterMap()  BOOL LLFloaterMap::postBuild()  {  	mMap = getChild<LLNetMap>("Net Map"); -	mMap->setToolTipMsg(getString("ToolTipMsg"));	 +	mMap->setToolTipMsg(gSavedSettings.getBOOL("DoubleClickTeleport") ?  +		getString("AltToolTipMsg") : getString("ToolTipMsg"));  	sendChildToBack(mMap);  	mTextBoxNorth = getChild<LLTextBox> ("floater_map_north"); diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 71882fbb83..07f5220ab7 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -178,7 +178,7 @@ void LLFloaterSettingsDebug::onClickDefault()  	if (controlp)  	{ -		controlp->resetToDefault(); +		controlp->resetToDefault(true);  		updateControl(controlp);  	}  } diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 51726112a0..058567492b 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -1,402 +1,402 @@ -/**
 - * @file llfloaterwebcontent.cpp
 - * @brief floater for displaying web content - e.g. profiles and search (eventually)
 - *
 - * $LicenseInfo:firstyear=2006&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 "llcombobox.h"
 -#include "lliconctrl.h"
 -#include "llfloaterreg.h"
 -#include "lllayoutstack.h"
 -#include "llpluginclassmedia.h"
 -#include "llprogressbar.h"
 -#include "lltextbox.h"
 -#include "llurlhistory.h"
 -#include "llviewercontrol.h"
 -#include "llweb.h"
 -#include "llwindow.h"
 -
 -#include "llfloaterwebcontent.h"
 -
 -LLFloaterWebContent::LLFloaterWebContent( const LLSD& key )
 -	: LLFloater( key )
 -{
 -	mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));
 -	mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));
 -	mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this ));
 -	mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this ));
 -	mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this ));
 -	mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this ));
 -}
 -
 -BOOL LLFloaterWebContent::postBuild()
 -{
 -	// these are used in a bunch of places so cache them
 -	mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" );
 -	mAddressCombo = getChild< LLComboBox >( "address" );
 -	mStatusBarText = getChild< LLTextBox >( "statusbartext" );
 -	mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress" );
 -
 -	// observe browser events
 -	mWebBrowser->addObserver( this );
 -
 -	// these buttons are always enabled
 -	getChildView("reload")->setEnabled( true );
 -	getChildView("popexternal")->setEnabled( true );
 -
 -	// cache image for secure browsing
 -	mSecureLockIcon = getChild< LLIconCtrl >("media_secure_lock_flag");
 -
 -	// initialize the URL history using the system URL History manager
 -	initializeURLHistory();
 -
 -	return TRUE;
 -}
 -
 -void LLFloaterWebContent::initializeURLHistory()
 -{
 -	// start with an empty list
 -	LLCtrlListInterface* url_list = childGetListInterface("address");
 -	if (url_list)
 -	{
 -		url_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
 -	}
 -
 -	// Get all of the entries in the "browser" collection
 -	LLSD browser_history = LLURLHistory::getURLHistory("browser");
 -	LLSD::array_iterator iter_history =
 -		browser_history.beginArray();
 -	LLSD::array_iterator end_history =
 -		browser_history.endArray();
 -	for(; iter_history != end_history; ++iter_history)
 -	{
 -		std::string url = (*iter_history).asString();
 -		if(! url.empty())
 -			url_list->addSimpleElement(url);
 -	}
 -}
 -
 -//static
 -void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid )
 -{
 -	lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl;
 -
 -	std::string tag = target;
 -
 -	if(target.empty() || target == "_blank")
 -	{
 -		if(!uuid.empty())
 -		{
 -			tag = uuid;
 -		}
 -		else
 -		{
 -			// create a unique tag for this instance
 -			LLUUID id;
 -			id.generate();
 -			tag = id.asString();
 -		}
 -	}
 -
 -	S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit");
 -
 -	if(LLFloaterReg::findInstance("web_content", tag) != NULL)
 -	{
 -		// There's already a web browser for this tag, so we won't be opening a new window.
 -	}
 -	else if(browser_window_limit != 0)
 -	{
 -		// showInstance will open a new window.  Figure out how many web browsers are already open,
 -		// and close the least recently opened one if this will put us over the limit.
 -
 -		LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList("web_content");
 -		lldebugs << "total instance count is " << instances.size() << llendl;
 -
 -		for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++)
 -		{
 -			lldebugs << "    " << (*iter)->getKey() << llendl;
 -		}
 -
 -		if(instances.size() >= (size_t)browser_window_limit)
 -		{
 -			// Destroy the least recently opened instance
 -			(*instances.begin())->closeFloater();
 -		}
 -	}
 -
 -	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::showInstance("web_content", tag));
 -	llassert(browser);
 -	if(browser)
 -	{
 -		browser->mUUID = uuid;
 -
 -		// tell the browser instance to load the specified URL
 -		browser->open_media(url, target);
 -		LLViewerMedia::proxyWindowOpened(target, uuid);
 -	}
 -}
 -
 -//static
 -void LLFloaterWebContent::closeRequest(const std::string &uuid)
 -{
 -	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
 -	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
 -	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 -	{
 -		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
 -		lldebugs << "    " << i->mUUID << llendl;
 -		if (i && i->mUUID == uuid)
 -		{
 -			i->closeFloater(false);
 -			return;
 - 		}
 - 	}
 -}
 -
 -//static
 -void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height)
 -{
 -	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
 -	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
 -	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 -	{
 -		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
 -		lldebugs << "    " << i->mUUID << llendl;
 -		if (i && i->mUUID == uuid)
 -		{
 -			i->geometryChanged(x, y, width, height);
 -			return;
 -		}
 -	}
 -}
 -
 -void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
 -{
 -	// Make sure the layout of the browser control is updated, so this calculation is correct.
 -	LLLayoutStack::updateClass();
 -
 -	// TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc.
 -	LLCoordWindow window_size;
 -	getWindow()->getSize(&window_size);
 -
 -	// Adjust width and height for the size of the chrome on the web Browser window.
 -	width += getRect().getWidth() - mWebBrowser->getRect().getWidth();
 -	height += getRect().getHeight() - mWebBrowser->getRect().getHeight();
 -
 -	LLRect geom;
 -	geom.setOriginAndSize(x, window_size.mY - (y + height), width, height);
 -
 -	lldebugs << "geometry change: " << geom << llendl;
 -
 -	handleReshape(geom,false);
 -}
 -
 -void LLFloaterWebContent::open_media(const std::string& web_url, const std::string& target)
 -{
 -	// Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin.
 -	mWebBrowser->setHomePageUrl(web_url, "text/html");
 -	mWebBrowser->setTarget(target);
 -	mWebBrowser->navigateTo(web_url, "text/html");
 -	set_current_url(web_url);
 -}
 -
 -//virtual
 -void LLFloaterWebContent::onClose(bool app_quitting)
 -{
 -	LLViewerMedia::proxyWindowClosed(mUUID);
 -	destroy();
 -}
 -
 -// virtual
 -void LLFloaterWebContent::draw()
 -{
 -	// this is asychronous so we need to keep checking
 -	getChildView( "back" )->setEnabled( mWebBrowser->canNavigateBack() );
 -	getChildView( "forward" )->setEnabled( mWebBrowser->canNavigateForward() );
 -
 -	LLFloater::draw();
 -}
 -
 -// virtual
 -void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 -{
 -	if(event == MEDIA_EVENT_LOCATION_CHANGED)
 -	{
 -		const std::string url = self->getLocation();
 -
 -		if ( url.length() )
 -			mStatusBarText->setText( url );
 -
 -		set_current_url( url );
 -	}
 -	else if(event == MEDIA_EVENT_NAVIGATE_BEGIN)
 -	{
 -		// flags are sent with this event
 -		getChildView("back")->setEnabled( self->getHistoryBackAvailable() );
 -		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() );
 -
 -		// toggle visibility of these buttons based on browser state
 -		getChildView("reload")->setVisible( false );
 -		getChildView("stop")->setVisible( true );
 -
 -		// turn "on" progress bar now we're about to start loading
 -		mStatusBarProgress->setVisible( true );
 -	}
 -	else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
 -	{
 -		// flags are sent with this event
 -		getChildView("back")->setEnabled( self->getHistoryBackAvailable() );
 -		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() );
 -
 -		// toggle visibility of these buttons based on browser state
 -		getChildView("reload")->setVisible( true );
 -		getChildView("stop")->setVisible( false );
 -
 -		// turn "off" progress bar now we're loaded
 -		mStatusBarProgress->setVisible( false );
 -
 -		// we populate the status bar with URLs as they change so clear it now we're done
 -		const std::string end_str = "";
 -		mStatusBarText->setText( end_str );
 -
 -		// decide if secure browsing icon should be displayed
 -		std::string prefix =  std::string("https://");
 -		std::string test_prefix = mCurrentURL.substr(0, prefix.length());
 -		LLStringUtil::toLower(test_prefix);
 -		if(test_prefix == prefix)
 -		{
 -			mSecureLockIcon->setVisible(true);
 -		}
 -		else
 -		{
 -			mSecureLockIcon->setVisible(false);
 -		}
 -	}
 -	else if(event == MEDIA_EVENT_CLOSE_REQUEST)
 -	{
 -		// The browser instance wants its window closed.
 -		closeFloater();
 -	}
 -	else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
 -	{
 -		geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
 -	}
 -	else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
 -	{
 -		const std::string text = self->getStatusText();
 -		if ( text.length() )
 -			mStatusBarText->setText( text );
 -	}
 -	else if(event == MEDIA_EVENT_PROGRESS_UPDATED )
 -	{
 -		int percent = (int)self->getProgressPercent();
 -		mStatusBarProgress->setValue( percent );
 -	}
 -	else if(event == MEDIA_EVENT_NAME_CHANGED )
 -	{
 -		std::string page_title = self->getMediaName();
 -		// simulate browser behavior - title is empty, use the current URL
 -		if ( page_title.length() > 0 )
 -			setTitle( page_title );
 -		else
 -			setTitle( mCurrentURL );
 -	}
 -	else if(event == MEDIA_EVENT_LINK_HOVERED )
 -	{
 -		const std::string link = self->getHoverLink();
 -		mStatusBarText->setText( link );
 -	}
 -}
 -
 -void LLFloaterWebContent::set_current_url(const std::string& url)
 -{
 -	mCurrentURL = url;
 -
 -	// serialize url history into the system URL History manager
 -	LLURLHistory::removeURL("browser", mCurrentURL);
 -	LLURLHistory::addURL("browser", mCurrentURL);
 -
 -	mAddressCombo->remove( mCurrentURL );
 -	mAddressCombo->add( mCurrentURL );
 -	mAddressCombo->selectByValue( mCurrentURL );
 -}
 -
 -void LLFloaterWebContent::onClickForward()
 -{
 -	mWebBrowser->navigateForward();
 -}
 -
 -void LLFloaterWebContent::onClickBack()
 -{
 -	mWebBrowser->navigateBack();
 -}
 -
 -void LLFloaterWebContent::onClickReload()
 -{
 -
 -	if( mWebBrowser->getMediaPlugin() )
 -	{
 -		bool ignore_cache = true;
 -		mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache );
 -	}
 -	else
 -	{
 -		mWebBrowser->navigateTo(mCurrentURL);
 -	}
 -}
 -
 -void LLFloaterWebContent::onClickStop()
 -{
 -	if( mWebBrowser->getMediaPlugin() )
 -		mWebBrowser->getMediaPlugin()->browse_stop();
 -
 -	// still should happen when we catch the navigate complete event
 -	// but sometimes (don't know why) that event isn't sent from Qt
 -	// and we getto a point where the stop button stays active.
 -	getChildView("reload")->setVisible( true );
 -	getChildView("stop")->setVisible( false );
 -}
 -
 -void LLFloaterWebContent::onEnterAddress()
 -{
 -	// make sure there is at least something there.
 -	// (perhaps this test should be for minimum length of a URL)
 -	std::string url = mAddressCombo->getValue().asString();
 -	if ( url.length() > 0 )
 -	{
 -		mWebBrowser->navigateTo( url, "text/html");
 -	};
 -}
 -
 -void LLFloaterWebContent::onPopExternal()
 -{
 -	// make sure there is at least something there.
 -	// (perhaps this test should be for minimum length of a URL)
 -	std::string url = mAddressCombo->getValue().asString();
 -	if ( url.length() > 0 )
 -	{
 -		LLWeb::loadURLExternal( url );
 -	};
 -}
 +/** + * @file llfloaterwebcontent.cpp + * @brief floater for displaying web content - e.g. profiles and search (eventually) + * + * $LicenseInfo:firstyear=2006&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 "llcombobox.h" +#include "lliconctrl.h" +#include "llfloaterreg.h" +#include "lllayoutstack.h" +#include "llpluginclassmedia.h" +#include "llprogressbar.h" +#include "lltextbox.h" +#include "llurlhistory.h" +#include "llviewercontrol.h" +#include "llweb.h" +#include "llwindow.h" + +#include "llfloaterwebcontent.h" + +LLFloaterWebContent::LLFloaterWebContent( const LLSD& key ) +	: LLFloater( key ) +{ +	mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this )); +	mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this )); +	mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this )); +	mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this )); +	mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this )); +	mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this )); +} + +BOOL LLFloaterWebContent::postBuild() +{ +	// these are used in a bunch of places so cache them +	mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" ); +	mAddressCombo = getChild< LLComboBox >( "address" ); +	mStatusBarText = getChild< LLTextBox >( "statusbartext" ); +	mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress" ); + +	// observe browser events +	mWebBrowser->addObserver( this ); + +	// these buttons are always enabled +	getChildView("reload")->setEnabled( true ); +	getChildView("popexternal")->setEnabled( true ); + +	// cache image for secure browsing +	mSecureLockIcon = getChild< LLIconCtrl >("media_secure_lock_flag"); + +	// initialize the URL history using the system URL History manager +	initializeURLHistory(); + +	return TRUE; +} + +void LLFloaterWebContent::initializeURLHistory() +{ +	// start with an empty list +	LLCtrlListInterface* url_list = childGetListInterface("address"); +	if (url_list) +	{ +		url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); +	} + +	// Get all of the entries in the "browser" collection +	LLSD browser_history = LLURLHistory::getURLHistory("browser"); +	LLSD::array_iterator iter_history = +		browser_history.beginArray(); +	LLSD::array_iterator end_history = +		browser_history.endArray(); +	for(; iter_history != end_history; ++iter_history) +	{ +		std::string url = (*iter_history).asString(); +		if(! url.empty()) +			url_list->addSimpleElement(url); +	} +} + +//static +void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid ) +{ +	lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl; + +	std::string tag = target; + +	if(target.empty() || target == "_blank") +	{ +		if(!uuid.empty()) +		{ +			tag = uuid; +		} +		else +		{ +			// create a unique tag for this instance +			LLUUID id; +			id.generate(); +			tag = id.asString(); +		} +	} + +	S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit"); + +	if(LLFloaterReg::findInstance("web_content", tag) != NULL) +	{ +		// There's already a web browser for this tag, so we won't be opening a new window. +	} +	else if(browser_window_limit != 0) +	{ +		// showInstance will open a new window.  Figure out how many web browsers are already open, +		// and close the least recently opened one if this will put us over the limit. + +		LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList("web_content"); +		lldebugs << "total instance count is " << instances.size() << llendl; + +		for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++) +		{ +			lldebugs << "    " << (*iter)->getKey() << llendl; +		} + +		if(instances.size() >= (size_t)browser_window_limit) +		{ +			// Destroy the least recently opened instance +			(*instances.begin())->closeFloater(); +		} +	} + +	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::showInstance("web_content", tag)); +	llassert(browser); +	if(browser) +	{ +		browser->mUUID = uuid; + +		// tell the browser instance to load the specified URL +		browser->open_media(url, target); +		LLViewerMedia::proxyWindowOpened(target, uuid); +	} +} + +//static +void LLFloaterWebContent::closeRequest(const std::string &uuid) +{ +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content"); +	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl; +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) +	{ +		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter); +		lldebugs << "    " << i->mUUID << llendl; +		if (i && i->mUUID == uuid) +		{ +			i->closeFloater(false); +			return; + 		} + 	} +} + +//static +void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height) +{ +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content"); +	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl; +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) +	{ +		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter); +		lldebugs << "    " << i->mUUID << llendl; +		if (i && i->mUUID == uuid) +		{ +			i->geometryChanged(x, y, width, height); +			return; +		} +	} +} + +void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height) +{ +	// Make sure the layout of the browser control is updated, so this calculation is correct. +	LLLayoutStack::updateClass(); + +	// TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc. +	LLCoordWindow window_size; +	getWindow()->getSize(&window_size); + +	// Adjust width and height for the size of the chrome on the web Browser window. +	width += getRect().getWidth() - mWebBrowser->getRect().getWidth(); +	height += getRect().getHeight() - mWebBrowser->getRect().getHeight(); + +	LLRect geom; +	geom.setOriginAndSize(x, window_size.mY - (y + height), width, height); + +	lldebugs << "geometry change: " << geom << llendl; + +	handleReshape(geom,false); +} + +void LLFloaterWebContent::open_media(const std::string& web_url, const std::string& target) +{ +	// Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin. +	mWebBrowser->setHomePageUrl(web_url, "text/html"); +	mWebBrowser->setTarget(target); +	mWebBrowser->navigateTo(web_url, "text/html"); +	set_current_url(web_url); +} + +//virtual +void LLFloaterWebContent::onClose(bool app_quitting) +{ +	LLViewerMedia::proxyWindowClosed(mUUID); +	destroy(); +} + +// virtual +void LLFloaterWebContent::draw() +{ +	// this is asychronous so we need to keep checking +	getChildView( "back" )->setEnabled( mWebBrowser->canNavigateBack() ); +	getChildView( "forward" )->setEnabled( mWebBrowser->canNavigateForward() ); + +	LLFloater::draw(); +} + +// virtual +void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ +	if(event == MEDIA_EVENT_LOCATION_CHANGED) +	{ +		const std::string url = self->getLocation(); + +		if ( url.length() ) +			mStatusBarText->setText( url ); + +		set_current_url( url ); +	} +	else if(event == MEDIA_EVENT_NAVIGATE_BEGIN) +	{ +		// flags are sent with this event +		getChildView("back")->setEnabled( self->getHistoryBackAvailable() ); +		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() ); + +		// toggle visibility of these buttons based on browser state +		getChildView("reload")->setVisible( false ); +		getChildView("stop")->setVisible( true ); + +		// turn "on" progress bar now we're about to start loading +		mStatusBarProgress->setVisible( true ); +	} +	else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) +	{ +		// flags are sent with this event +		getChildView("back")->setEnabled( self->getHistoryBackAvailable() ); +		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() ); + +		// toggle visibility of these buttons based on browser state +		getChildView("reload")->setVisible( true ); +		getChildView("stop")->setVisible( false ); + +		// turn "off" progress bar now we're loaded +		mStatusBarProgress->setVisible( false ); + +		// we populate the status bar with URLs as they change so clear it now we're done +		const std::string end_str = ""; +		mStatusBarText->setText( end_str ); + +		// decide if secure browsing icon should be displayed +		std::string prefix =  std::string("https://"); +		std::string test_prefix = mCurrentURL.substr(0, prefix.length()); +		LLStringUtil::toLower(test_prefix); +		if(test_prefix == prefix) +		{ +			mSecureLockIcon->setVisible(true); +		} +		else +		{ +			mSecureLockIcon->setVisible(false); +		} +	} +	else if(event == MEDIA_EVENT_CLOSE_REQUEST) +	{ +		// The browser instance wants its window closed. +		closeFloater(); +	} +	else if(event == MEDIA_EVENT_GEOMETRY_CHANGE) +	{ +		geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight()); +	} +	else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED ) +	{ +		const std::string text = self->getStatusText(); +		if ( text.length() ) +			mStatusBarText->setText( text ); +	} +	else if(event == MEDIA_EVENT_PROGRESS_UPDATED ) +	{ +		int percent = (int)self->getProgressPercent(); +		mStatusBarProgress->setValue( percent ); +	} +	else if(event == MEDIA_EVENT_NAME_CHANGED ) +	{ +		std::string page_title = self->getMediaName(); +		// simulate browser behavior - title is empty, use the current URL +		if ( page_title.length() > 0 ) +			setTitle( page_title ); +		else +			setTitle( mCurrentURL ); +	} +	else if(event == MEDIA_EVENT_LINK_HOVERED ) +	{ +		const std::string link = self->getHoverLink(); +		mStatusBarText->setText( link ); +	} +} + +void LLFloaterWebContent::set_current_url(const std::string& url) +{ +	mCurrentURL = url; + +	// serialize url history into the system URL History manager +	LLURLHistory::removeURL("browser", mCurrentURL); +	LLURLHistory::addURL("browser", mCurrentURL); + +	mAddressCombo->remove( mCurrentURL ); +	mAddressCombo->add( mCurrentURL ); +	mAddressCombo->selectByValue( mCurrentURL ); +} + +void LLFloaterWebContent::onClickForward() +{ +	mWebBrowser->navigateForward(); +} + +void LLFloaterWebContent::onClickBack() +{ +	mWebBrowser->navigateBack(); +} + +void LLFloaterWebContent::onClickReload() +{ + +	if( mWebBrowser->getMediaPlugin() ) +	{ +		bool ignore_cache = true; +		mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache ); +	} +	else +	{ +		mWebBrowser->navigateTo(mCurrentURL); +	} +} + +void LLFloaterWebContent::onClickStop() +{ +	if( mWebBrowser->getMediaPlugin() ) +		mWebBrowser->getMediaPlugin()->browse_stop(); + +	// still should happen when we catch the navigate complete event +	// but sometimes (don't know why) that event isn't sent from Qt +	// and we getto a point where the stop button stays active. +	getChildView("reload")->setVisible( true ); +	getChildView("stop")->setVisible( false ); +} + +void LLFloaterWebContent::onEnterAddress() +{ +	// make sure there is at least something there. +	// (perhaps this test should be for minimum length of a URL) +	std::string url = mAddressCombo->getValue().asString(); +	if ( url.length() > 0 ) +	{ +		mWebBrowser->navigateTo( url, "text/html"); +	}; +} + +void LLFloaterWebContent::onPopExternal() +{ +	// make sure there is at least something there. +	// (perhaps this test should be for minimum length of a URL) +	std::string url = mAddressCombo->getValue().asString(); +	if ( url.length() > 0 ) +	{ +		LLWeb::loadURLExternal( url ); +	}; +} diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h index 001d822ada..ecc7e970d8 100644 --- a/indra/newview/llfloaterwebcontent.h +++ b/indra/newview/llfloaterwebcontent.h @@ -1,82 +1,82 @@ -/**
 - * @file llfloaterwebcontent.h
 - * @brief floater for displaying web content - e.g. profiles and search (eventually)
 - *
 - * $LicenseInfo:firstyear=2006&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - *
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - *
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - *
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - *
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLFLOATERWEBCONTENT_H
 -#define LL_LLFLOATERWEBCONTENT_H
 -
 -#include "llfloater.h"
 -#include "llmediactrl.h"
 -
 -class LLMediaCtrl;
 -class LLComboBox;
 -class LLTextBox;
 -class LLProgressBar;
 -class LLIconCtrl;
 -
 -class LLFloaterWebContent :
 -	public LLFloater,
 -	public LLViewerMediaObserver
 -{
 -public:
 -    LOG_CLASS(LLFloaterWebContent);
 -	LLFloaterWebContent(const LLSD& key);
 -
 +/** + * @file llfloaterwebcontent.h + * @brief floater for displaying web content - e.g. profiles and search (eventually) + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERWEBCONTENT_H +#define LL_LLFLOATERWEBCONTENT_H + +#include "llfloater.h" +#include "llmediactrl.h" + +class LLMediaCtrl; +class LLComboBox; +class LLTextBox; +class LLProgressBar; +class LLIconCtrl; + +class LLFloaterWebContent : +	public LLFloater, +	public LLViewerMediaObserver +{ +public: +    LOG_CLASS(LLFloaterWebContent); +	LLFloaterWebContent(const LLSD& key); +  	void initializeURLHistory(); -
 -	static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null);
 -
 -	static void closeRequest(const std::string &uuid);
 -	static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height);
 -	void geometryChanged(S32 x, S32 y, S32 width, S32 height);
 -
 -	/* virtual */ BOOL postBuild();
 -	/* virtual */ void onClose(bool app_quitting);
 -	/* virtual */ void draw();
 -
 -	// inherited from LLViewerMediaObserver
 -	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
 -
 -	void onClickBack();
 -	void onClickForward();
 -	void onClickReload();
 -	void onClickStop();
 -	void onEnterAddress();
 -	void onPopExternal();
 -
 -private:
 -	void open_media(const std::string& media_url, const std::string& target);
 -	void set_current_url(const std::string& url);
 -
 -	LLMediaCtrl* mWebBrowser;
 -	LLComboBox* mAddressCombo;
 -	LLIconCtrl *mSecureLockIcon;
 -	LLTextBox* mStatusBarText;
 -	LLProgressBar* mStatusBarProgress;
 -	std::string mCurrentURL;
 -	std::string mUUID;
 -};
 -
 -#endif  // LL_LLFLOATERWEBCONTENT_H
 + +	static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null); + +	static void closeRequest(const std::string &uuid); +	static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height); +	void geometryChanged(S32 x, S32 y, S32 width, S32 height); + +	/* virtual */ BOOL postBuild(); +	/* virtual */ void onClose(bool app_quitting); +	/* virtual */ void draw(); + +	// inherited from LLViewerMediaObserver +	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + +	void onClickBack(); +	void onClickForward(); +	void onClickReload(); +	void onClickStop(); +	void onEnterAddress(); +	void onPopExternal(); + +private: +	void open_media(const std::string& media_url, const std::string& target); +	void set_current_url(const std::string& url); + +	LLMediaCtrl* mWebBrowser; +	LLComboBox* mAddressCombo; +	LLIconCtrl *mSecureLockIcon; +	LLTextBox* mStatusBarText; +	LLProgressBar* mStatusBarProgress; +	std::string mCurrentURL; +	std::string mUUID; +}; + +#endif  // LL_LLFLOATERWEBCONTENT_H diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 62ba746a02..b3b1ce5743 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1854,31 +1854,9 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  	{  		if (mCallbackRegistrar)  			mCallbackRegistrar->pushScope(); -		//menu->empty(); -		const LLView::child_list_t *list = menu->getChildList(); -		LLView::child_list_t::const_iterator menu_itor; -		for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor) -		{ -			(*menu_itor)->setVisible(FALSE); -			(*menu_itor)->pushVisible(TRUE); -			(*menu_itor)->setEnabled(TRUE); -		} -		 -		// Successively filter out invalid options - -		U32 flags = FIRST_SELECTED_ITEM; -		for (selected_items_t::iterator item_itor = mSelectedItems.begin();  -			 item_itor != mSelectedItems.end();  -			 ++item_itor) -		{ -			LLFolderViewItem* selected_item = (*item_itor); -			selected_item->buildContextMenu(*menu, flags); -			flags = 0x0; -		} +		updateMenuOptions(menu); -		addNoOptions(menu); -  		menu->updateParent(LLMenuGL::sMenuContainer);  		LLMenuGL::showPopup(this, menu, x, y);  		if (mCallbackRegistrar) @@ -2365,6 +2343,45 @@ void LLFolderView::updateRenamerPosition()  	}  } +// Update visibility and availability (i.e. enabled/disabled) of context menu items. +void LLFolderView::updateMenuOptions(LLMenuGL* menu) +{ +	const LLView::child_list_t *list = menu->getChildList(); + +	LLView::child_list_t::const_iterator menu_itor; +	for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor) +	{ +		(*menu_itor)->setVisible(FALSE); +		(*menu_itor)->pushVisible(TRUE); +		(*menu_itor)->setEnabled(TRUE); +	} + +	// Successively filter out invalid options + +	U32 flags = FIRST_SELECTED_ITEM; +	for (selected_items_t::iterator item_itor = mSelectedItems.begin(); +			item_itor != mSelectedItems.end(); +			++item_itor) +	{ +		LLFolderViewItem* selected_item = (*item_itor); +		selected_item->buildContextMenu(*menu, flags); +		flags = 0x0; +	} + +	addNoOptions(menu); +} + +// Refresh the context menu (that is already shown). +void LLFolderView::updateMenu() +{ +	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); +	if (menu && menu->getVisible()) +	{ +		updateMenuOptions(menu); +		menu->needsArrange(); // update menu height if needed +	} +} +  bool LLFolderView::selectFirstItem()  {  	for (folders_t::iterator iter = mFolders.begin(); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index afaac86b04..210ba9eb3c 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -269,7 +269,10 @@ public:  	virtual S32	notify(const LLSD& info) ;  	bool useLabelSuffix() { return mUseLabelSuffix; } +	void updateMenu(); +  private: +	void updateMenuOptions(LLMenuGL* menu);  	void updateRenamerPosition();  protected: diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index e765a8da2f..a15776c207 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -100,7 +100,7 @@ public:  		void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name); -		void onAdHocNameCache(const LLAvatarName& av_name);
 +		void onAdHocNameCache(const LLAvatarName& av_name);  		//*TODO make private  		static std::string generateHash(const std::set<LLUUID>& sorted_uuids); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 4ad1934264..17d0b0ffbb 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -717,7 +717,7 @@ void LLInspectAvatar::onClickShare()  void LLInspectAvatar::onToggleMute()  { -	LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT); +	LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT);  	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))  	{ diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index ef4774a06d..e22363c2f6 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -393,18 +393,22 @@ void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)  void LLInventoryFilter::setFilterSubString(const std::string& string)  { -	if (mFilterSubString != string) +	std::string filter_sub_string_new = string; +	mFilterSubStringOrig = string; +	LLStringUtil::trimHead(filter_sub_string_new); +	LLStringUtil::toUpper(filter_sub_string_new); + +	if (mFilterSubString != filter_sub_string_new)  	{  		// hitting BACKSPACE, for example -		const BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string); +		const BOOL less_restrictive = mFilterSubString.size() >= filter_sub_string_new.size() +			&& !mFilterSubString.substr(0, filter_sub_string_new.size()).compare(filter_sub_string_new);  		// appending new characters -		const BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString); +		const BOOL more_restrictive = mFilterSubString.size() < filter_sub_string_new.size() +			&& !filter_sub_string_new.substr(0, mFilterSubString.size()).compare(mFilterSubString); -		mFilterSubStringOrig = string; -		LLStringUtil::trimHead(mFilterSubStringOrig); -		mFilterSubString = mFilterSubStringOrig; -		LLStringUtil::toUpper(mFilterSubString); +		mFilterSubString = filter_sub_string_new;  		if (less_restrictive)  		{  			setModified(FILTER_LESS_RESTRICTIVE); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ef20869114..61d0a150b7 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -686,6 +686,12 @@ bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* it  		return false;  	} +	// Skip broken links. +	if (vitem->getIsBrokenLink()) +	{ +		return false; +	} +  	return (bool) get_is_item_worn(item->getUUID()) == mIsWorn;  } diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index eab8f187a7..570e48d526 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -181,7 +181,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  	if (mBackgroundFetchActive && gAgent.getRegion())  	{  		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important. -		std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");    +		std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2");     		if (!url.empty())   		{  			bulkFetch(url); @@ -604,7 +604,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)  		}  		if (body_lib["folders"].size())  		{ -			std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents"); +			std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2");  			LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body_lib, recursive_cats);  			LLHTTPClient::post(url_lib, body_lib, fetcher, 300.0); diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 91ff8c7867..0fd4b2bee5 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -203,8 +203,8 @@ void fetch_items_from_llsd(const LLSD& items_llsd)  {  	if (!items_llsd.size() || gDisconnected) return;  	LLSD body; -	body[0]["cap_name"] = "FetchInventory"; -	body[1]["cap_name"] = "FetchLib"; +	body[0]["cap_name"] = "FetchInventory2"; +	body[1]["cap_name"] = "FetchLib2";  	for (S32 i=0; i<items_llsd.size();i++)  	{  		if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString()) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 5a9d1524f3..1dcb91ad4d 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -60,6 +60,7 @@ static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;  //  // Bridge to support knowing when the inventory has changed.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +  class LLInventoryPanelObserver : public LLInventoryObserver  {  public: @@ -73,9 +74,57 @@ protected:  	LLInventoryPanel* mIP;  }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLInvPanelComplObserver +// +// Calls specified callback when all specified items become complete. +// +// Usage: +// observer = new LLInvPanelComplObserver(boost::bind(onComplete)); +// inventory->addObserver(observer); +// observer->reset(); // (optional) +// observer->watchItem(incomplete_item1_id); +// observer->watchItem(incomplete_item2_id); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLInvPanelComplObserver : public LLInventoryCompletionObserver +{ +public: +	typedef boost::function<void()> callback_t; + +	LLInvPanelComplObserver(callback_t cb) +	:	mCallback(cb) +	{ +	} + +	void reset(); + +private: +	/*virtual*/ void done(); + +	/// Called when all the items are complete. +	callback_t	mCallback; +}; + +void LLInvPanelComplObserver::reset() +{ +	mIncomplete.clear(); +	mComplete.clear(); +} + +void LLInvPanelComplObserver::done() +{ +	mCallback(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLInventoryPanel +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +  LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :	  	LLPanel(p),  	mInventoryObserver(NULL), +	mCompletionObserver(NULL),  	mFolderRoot(NULL),  	mScroller(NULL),  	mSortOrderSetting(p.sort_order_setting), @@ -152,6 +201,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	mInventoryObserver = new LLInventoryPanelObserver(this);  	mInventory->addObserver(mInventoryObserver); +	mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this)); +	mInventory->addObserver(mCompletionObserver); +  	// Build view of inventory if we need default full hierarchy and inventory ready,  	// otherwise wait for idle callback.  	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized) @@ -189,7 +241,10 @@ LLInventoryPanel::~LLInventoryPanel()  	// LLView destructor will take care of the sub-views.  	mInventory->removeObserver(mInventoryObserver); +	mInventory->removeObserver(mCompletionObserver);  	delete mInventoryObserver; +	delete mCompletionObserver; +  	mScroller = NULL;  } @@ -654,6 +709,11 @@ void LLInventoryPanel::openStartFolderOrMyInventory()  	}  } +void LLInventoryPanel::onItemsCompletion() +{ +	if (mFolderRoot) mFolderRoot->updateMenu(); +} +  void LLInventoryPanel::openSelected()  {  	LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem(); @@ -757,6 +817,19 @@ void LLInventoryPanel::clearSelection()  void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)  { +	// Schedule updating the folder view context menu when all selected items become complete (STORM-373). +	mCompletionObserver->reset(); +	for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it) +	{ +		LLUUID id = (*it)->getListener()->getUUID(); +		LLViewerInventoryItem* inv_item = mInventory->getItem(id); + +		if (inv_item && !inv_item->isFinished()) +		{ +			mCompletionObserver->watchItem(id); +		} +	} +  	LLFolderView* fv = getRootFolder();  	if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename  	{ diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 6545fc0d5e..9da9f7d8ba 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -52,6 +52,7 @@ class LLIconCtrl;  class LLSaveFolderState;  class LLFilterEditor;  class LLTabContainer; +class LLInvPanelComplObserver;  class LLInventoryPanel : public LLPanel  { @@ -167,9 +168,11 @@ public:  protected:  	void openStartFolderOrMyInventory(); // open the first level of inventory +	void onItemsCompletion();			// called when selected items are complete  	LLInventoryModel*			mInventory;  	LLInventoryObserver*		mInventoryObserver; +	LLInvPanelComplObserver*	mCompletionObserver;  	BOOL 						mAllowMultiSelect;  	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 1527f8f4c9..55164f6094 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -547,6 +547,10 @@ void LLLocationInputCtrl::onFocusLost()  {  	LLUICtrl::onFocusLost();  	refreshLocation(); + +	// Setting cursor to 0  to show the left edge of the text. See STORM-370. +	mTextEntry->setCursor(0); +  	if(mTextEntry->hasSelection()){  		mTextEntry->deselect();  	} diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 0121bbb1ed..9adf374c71 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -89,15 +89,15 @@ const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+   */  const static boost::regex NAME_AND_TEXT("([^:]+[:]{1})?(\\s*)(.*)"); -/**
 - * These are recognizers for matching the names of ad-hoc conferences when generating the log file name
 - * On invited side, an ad-hoc is named like "<first name> <last name> Conference 2010/11/19 03:43 f0f4"
 - * On initiating side, an ad-hoc is named like Ad-hoc Conference hash<hash>"
 - * If the naming system for ad-hoc conferences are change in LLIMModel::LLIMSession::buildHistoryFileName()
 - * then these definition need to be adjusted as well.
 - */
 -const static boost::regex INBOUND_CONFERENCE("^[a-zA-Z]{1,31} [a-zA-Z]{1,31} Conference [0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2} [0-9a-f]{4}");
 -const static boost::regex OUTBOUND_CONFERENCE("^Ad-hoc Conference hash[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}");
 +/** + * These are recognizers for matching the names of ad-hoc conferences when generating the log file name + * On invited side, an ad-hoc is named like "<first name> <last name> Conference 2010/11/19 03:43 f0f4" + * On initiating side, an ad-hoc is named like Ad-hoc Conference hash<hash>" + * If the naming system for ad-hoc conferences are change in LLIMModel::LLIMSession::buildHistoryFileName() + * then these definition need to be adjusted as well. + */ +const static boost::regex INBOUND_CONFERENCE("^[a-zA-Z]{1,31} [a-zA-Z]{1,31} Conference [0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2} [0-9a-f]{4}"); +const static boost::regex OUTBOUND_CONFERENCE("^Ad-hoc Conference hash[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}");  //is used to parse complex object names like "Xstreet SL Terminal v2.2.5 st"  const static std::string NAME_TEXT_DIVIDER(": "); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index efb2e9c0fd..33e051bfab 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -472,7 +472,6 @@ LLLoginInstance::LLLoginInstance() :  	mLoginModule(new LLLogin()),  	mNotifications(NULL),  	mLoginState("offline"), -	mUserInteraction(true),  	mSkipOptionalUpdate(false),  	mAttemptComplete(false),  	mTransferRate(0.0f), @@ -641,64 +640,57 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	LLSD response = event["data"];  	std::string reason_response = response["reason"].asString();  	std::string message_response = response["message"].asString(); -	if(mUserInteraction) +	// For the cases of critical message or TOS agreement, +	// start the TOS dialog. The dialog response will be handled +	// by the LLLoginInstance::handleTOSResponse() callback. +	// The callback intiates the login attempt next step, either  +	// to reconnect or to end the attempt in failure. +	if(reason_response == "tos")  	{ -		// For the cases of critical message or TOS agreement, -		// start the TOS dialog. The dialog response will be handled -		// by the LLLoginInstance::handleTOSResponse() callback. -		// The callback intiates the login attempt next step, either  -		// to reconnect or to end the attempt in failure. -		if(reason_response == "tos") -		{ -			LLSD data(LLSD::emptyMap()); -			data["message"] = message_response; -			data["reply_pump"] = TOS_REPLY_PUMP; -			gViewerWindow->setShowProgress(FALSE); -			LLFloaterReg::showInstance("message_tos", data); -			LLEventPumps::instance().obtain(TOS_REPLY_PUMP) -				.listen(TOS_LISTENER_NAME, -						boost::bind(&LLLoginInstance::handleTOSResponse,  -									this, _1, "agree_to_tos")); -		} -		else if(reason_response == "critical") -		{ -			LLSD data(LLSD::emptyMap()); -			data["message"] = message_response; -			data["reply_pump"] = TOS_REPLY_PUMP; -			if(response.has("error_code")) -			{ -				data["error_code"] = response["error_code"]; -			} -			if(response.has("certificate")) -			{ -				data["certificate"] = response["certificate"]; -			} -			 -			gViewerWindow->setShowProgress(FALSE); -			LLFloaterReg::showInstance("message_critical", data); -			LLEventPumps::instance().obtain(TOS_REPLY_PUMP) -				.listen(TOS_LISTENER_NAME, -						boost::bind(&LLLoginInstance::handleTOSResponse,  -									this, _1, "read_critical")); -		} -		else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate")) +		LLSD data(LLSD::emptyMap()); +		data["message"] = message_response; +		data["reply_pump"] = TOS_REPLY_PUMP; +		gViewerWindow->setShowProgress(FALSE); +		LLFloaterReg::showInstance("message_tos", data); +		LLEventPumps::instance().obtain(TOS_REPLY_PUMP) +			.listen(TOS_LISTENER_NAME, +					boost::bind(&LLLoginInstance::handleTOSResponse,  +								this, _1, "agree_to_tos")); +	} +	else if(reason_response == "critical") +	{ +		LLSD data(LLSD::emptyMap()); +		data["message"] = message_response; +		data["reply_pump"] = TOS_REPLY_PUMP; +		if(response.has("error_code"))  		{ -			gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); -			updateApp(true, message_response); +			data["error_code"] = response["error_code"];  		} -		else if(reason_response == "optional") +		if(response.has("certificate"))  		{ -			updateApp(false, message_response); +			data["certificate"] = response["certificate"];  		} -		else -		{	 -			attemptComplete(); -		}	 +		 +		gViewerWindow->setShowProgress(FALSE); +		LLFloaterReg::showInstance("message_critical", data); +		LLEventPumps::instance().obtain(TOS_REPLY_PUMP) +			.listen(TOS_LISTENER_NAME, +					boost::bind(&LLLoginInstance::handleTOSResponse,  +								this, _1, "read_critical"));  	} -	else // no user interaction +	else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))  	{ -		attemptComplete(); +		gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); +		updateApp(true, message_response); +	} +	else if(reason_response == "optional") +	{ +		updateApp(false, message_response);  	} +	else +	{	 +		attemptComplete(); +	}	  }  void LLLoginInstance::handleLoginSuccess(const LLSD& event) diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index b872d7d1b1..8b53431219 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -61,12 +61,6 @@ public:  	// Only valid when authSuccess == true.  	const F64 getLastTransferRateBPS() { return mTransferRate; } -		// Set whether this class will drive user interaction. -	// If not, login failures like 'need tos agreement' will  -	// end the login attempt. -	void setUserInteraction(bool state) { mUserInteraction = state; }  -	bool getUserInteraction() { return mUserInteraction; } -  	// Whether to tell login to skip optional update request.  	// False by default.  	void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; } @@ -100,7 +94,6 @@ private:  	std::string mLoginState;  	LLSD mRequestData;  	LLSD mResponseData; -	bool mUserInteraction;   	bool mSkipOptionalUpdate;  	bool mAttemptComplete;  	F64 mTransferRate; diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp index 9a244e2562..7e9c3c84a7 100644 --- a/indra/newview/llmemoryview.cpp +++ b/indra/newview/llmemoryview.cpp @@ -37,9 +37,11 @@  #include <sstream>  #include <boost/algorithm/string/split.hpp> +#include "llmemory.h"  LLMemoryView::LLMemoryView(const LLMemoryView::Params& p)  :	LLView(p), +	mPaused(FALSE),  	//mDelay(120),      mAlloc(NULL)  { @@ -59,6 +61,7 @@ BOOL LLMemoryView::handleMouseDown(S32 x, S32 y, MASK mask)  	}  	else  	{ +		mPaused = !mPaused;  	}  	return TRUE;  } @@ -148,13 +151,14 @@ void LLMemoryView::draw()  	// cut off lines on bottom  	U32 max_lines = U32((height - 2 * line_height) / line_height); -    std::vector<LLWString>::const_iterator end = mLines.end(); +	y_pos = height - MARGIN_AMT - line_height; +    y_off = 0.f; + +#if !MEM_TRACK_MEM +	std::vector<LLWString>::const_iterator end = mLines.end();      if(mLines.size() > max_lines) {          end = mLines.begin() + max_lines;      } - -	y_pos = height - MARGIN_AMT - line_height; -    y_off = 0.f;      for (std::vector<LLWString>::const_iterator i = mLines.begin(); i != end; ++i)  	{  		font->render(*i, 0, MARGIN_AMT, y_pos -  y_off, @@ -169,6 +173,47 @@ void LLMemoryView::draw()  		y_off += line_height;  	} +#else +	LLMemTracker::getInstance()->preDraw(mPaused) ; + +	{ +		F32 x_pos = MARGIN_AMT ; +		U32 lines = 0 ; +		const char* str = LLMemTracker::getInstance()->getNextLine() ; +		while(str != NULL) +		{ +			lines++ ; +			font->renderUTF8(str, 0, x_pos, y_pos -  y_off, +				LLColor4::white, +				LLFontGL::LEFT,  +				LLFontGL::BASELINE, +				LLFontGL::NORMAL, +				LLFontGL::DROP_SHADOW, +				S32_MAX, +				target_width, +				NULL, FALSE); +		 +			str = LLMemTracker::getInstance()->getNextLine() ; +			y_off += line_height; + +			if(lines >= max_lines) +			{ +				lines = 0 ; +				x_pos += 512.f ; +				if(x_pos + 512.f > target_width) +				{ +					break ; +				} + +				y_pos = height - MARGIN_AMT - line_height; +				y_off = 0.f; +			} +		} +	} + +	LLMemTracker::getInstance()->postDraw() ; +#endif +  #if MEM_TRACK_TYPE  	S32 left, top, right, bottom; diff --git a/indra/newview/llmemoryview.h b/indra/newview/llmemoryview.h index 24ea058279..9bdc59ab10 100644 --- a/indra/newview/llmemoryview.h +++ b/indra/newview/llmemoryview.h @@ -55,6 +55,7 @@ public:  private:      std::vector<LLWString> mLines;  	LLAllocator* mAlloc; +	BOOL mPaused ;  }; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1a8ec4991d..93039d935d 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -47,6 +47,7 @@  #include "llagentcamera.h"  #include "llappviewer.h" // for gDisconnected  #include "llcallingcard.h" // LLAvatarTracker +#include "llfloaterworldmap.h"  #include "lltracker.h"  #include "llsurface.h"  #include "llviewercamera.h" @@ -91,7 +92,8 @@ LLNetMap::LLNetMap (const Params & p)  	mObjectImagep(),  	mClosestAgentToCursor(),  	mClosestAgentAtLastRightClick(), -	mToolTipMsg() +	mToolTipMsg(), +	mPopupMenu(NULL)  {  	mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);  	setScale(gSavedSettings.getF32("MiniMapScale")); @@ -102,6 +104,21 @@ LLNetMap::~LLNetMap()  	gSavedSettings.setF32("MiniMapScale", mScale);  } +BOOL LLNetMap::postBuild() +{ +	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +	 +	registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); +	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; +} +  void LLNetMap::setScale( F32 scale )  {  	scale = llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX); @@ -354,16 +371,49 @@ void LLNetMap::draw()  				pos_map = globalPosToView(pos_global); +				LLUUID uuid(NULL);  				BOOL show_as_friend = FALSE;  				if( i < regionp->mMapAvatarIDs.count())  				{ -					show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(regionp->mMapAvatarIDs.get(i)) != NULL); +					uuid = regionp->mMapAvatarIDs.get(i); +					show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL);  				} + +				LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color;  				LLWorldMapView::drawAvatar(  					pos_map.mV[VX], pos_map.mV[VY],  -					show_as_friend ? map_avatar_friend_color : map_avatar_color,  +					color,   					pos_map.mV[VZ], mDotRadius); +				if(uuid.notNull()) +				{ +					bool selected = false; +					uuid_vec_t::iterator sel_iter = gmSelected.begin(); +					for (; sel_iter != gmSelected.end(); sel_iter++) +					{ +						if(*sel_iter == uuid) +						{ +							selected = true; +							break; +						} +					} +					if(selected) +					{ +						if( (pos_map.mV[VX] < 0) || +							(pos_map.mV[VY] < 0) || +							(pos_map.mV[VX] >= getRect().getWidth()) || +							(pos_map.mV[VY] >= getRect().getHeight()) ) +						{ +							S32 x = llround( pos_map.mV[VX] ); +							S32 y = llround( pos_map.mV[VY] ); +							LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); +						} else +						{ +							LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); +						} +					} +				} +  				F32	dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),  											  LLVector2(local_mouse_x,local_mouse_y));  				if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) @@ -460,6 +510,13 @@ void LLNetMap::draw()  	gGL.popUIMatrix();  	LLUICtrl::draw(); + +	if (LLTracker::isTracking(0)) +	{ +		mPopupMenu->setItemEnabled ("Stop Tracking", true); +	} +	 +  }  void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -600,7 +657,6 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )  	args["[REGION]"] = region_name;  	std::string msg = mToolTipMsg;  	LLStringUtil::format(msg, args); -  	LLToolTipMgr::instance().show(LLToolTip::Params()  		.message(msg)  		.sticky_rect(sticky_rect)); @@ -793,6 +849,9 @@ BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )  BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )  { +	if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3) +		handleClick(x,y,mask); +  	if (hasMouseCapture())  	{  		if (mPanning) @@ -821,6 +880,53 @@ BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )  	return FALSE;  } +BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ +	if (mPopupMenu) +	{ +		mPopupMenu->buildDrawLabels(); +		mPopupMenu->updateParent(LLMenuGL::sMenuContainer); +		LLMenuGL::showPopup(this, mPopupMenu, x, y); +	} +	return TRUE; +} + +BOOL LLNetMap::handleClick(S32 x, S32 y, MASK mask) +{ +	// TODO: allow clicking an avatar on minimap to select avatar in the nearby avatar list +	// if(mClosestAgentToCursor.notNull()) +	//     mNearbyList->selectUser(mClosestAgentToCursor); +	// Needs a registered observer i guess to accomplish this without using +	// globals to tell the mNearbyList in llpeoplepanel to select the user +	return TRUE; +} + +BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask) +{ +	LLVector3d pos_global = viewPosToGlobal(x, y); +	 +	// If we're not tracking a beacon already, double-click will set one  +	if (!LLTracker::isTracking(NULL)) +	{ +		LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance(); +		if (world_map) +		{ +			world_map->trackLocation(pos_global); +		} +	} +	 +	if (gSavedSettings.getBOOL("DoubleClickTeleport")) +	{ +		// If DoubleClickTeleport is on, double clicking the minimap will teleport there +		gAgent.teleportViaLocationLookAt(pos_global); +	} +	else  +	{ +		LLFloaterReg::showInstance("world_map"); +	} +	return TRUE; +} +  // static  bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )  { @@ -871,3 +977,38 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )  	return TRUE;  } + +void LLNetMap::handleZoom(const LLSD& userdata) +{ +	std::string level = userdata.asString(); +	 +	F32 scale = 0.0f; +	if (level == std::string("default")) +	{ +		LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); +		if(pvar) +		{ +			pvar->resetToDefault(); +			scale = gSavedSettings.getF32("MiniMapScale"); +		} +	} +	else if (level == std::string("close")) +		scale = LLNetMap::MAP_SCALE_MAX; +	else if (level == std::string("medium")) +		scale = LLNetMap::MAP_SCALE_MID; +	else if (level == std::string("far")) +		scale = LLNetMap::MAP_SCALE_MIN; +	if (scale != 0.0f) +	{ +		setScale(scale); +	} +} + +void LLNetMap::handleStopTracking (const LLSD& userdata) +{ +	if (mPopupMenu) +	{ +		mPopupMenu->setItemEnabled ("Stop Tracking", false); +		LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL)); +	} +} diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index e053b1c177..20fcee0814 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -39,6 +39,7 @@ class LLCoordGL;  class LLImageRaw;  class LLViewerTexture;  class LLFloaterMap; +class LLMenuGL;  class LLNetMap : public LLUICtrl  { @@ -72,7 +73,12 @@ public:  	/*virtual*/ BOOL	handleHover( S32 x, S32 y, MASK mask );  	/*virtual*/ BOOL	handleToolTip( S32 x, S32 y, MASK mask);  	/*virtual*/ void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); -	 + +	/*virtual*/ BOOL 	postBuild(); +	/*virtual*/ BOOL	handleRightMouseDown( S32 x, S32 y, MASK mask ); +	/*virtual*/ BOOL	handleClick(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL	handleDoubleClick( S32 x, S32 y, MASK mask ); +  	void			setScale( F32 scale );  	void			setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }  	void			renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); @@ -120,6 +126,16 @@ private:  	LLUUID			mClosestAgentAtLastRightClick;  	std::string		mToolTipMsg; + +public: +	void			setSelected(uuid_vec_t uuids) { gmSelected=uuids; }; + +private: +	void handleZoom(const LLSD& userdata); +	void handleStopTracking (const LLSD& userdata); + +	LLMenuGL*		mPopupMenu; +	uuid_vec_t		gmSelected;  }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 8a917a082c..73c4722b82 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -629,11 +629,11 @@ static void got_full_name_callback( LLHandle<LLPanel> profile_panel_handle, cons  {  	if (profile_panel_handle.isDead() ) return; -	LLPanelAvatarProfile* profile_panel = dynamic_cast<LLPanelAvatarProfile*>(profile_panel_handle.get());
 -	if ( ! profile_panel ) return;
 +	LLPanelAvatarProfile* profile_panel = dynamic_cast<LLPanelAvatarProfile*>(profile_panel_handle.get()); +	if ( ! profile_panel ) return; + +	LLStringUtil::format_map_t args; -	LLStringUtil::format_map_t args;
 -
  	std::string name;  	if (LLAvatarNameCache::useDisplayNames())  	{ @@ -642,21 +642,21 @@ static void got_full_name_callback( LLHandle<LLPanel> profile_panel_handle, cons  	else  	{  		name = full_name; -	}
 -
 -	args["[NAME]"] = name;
 -
 -	std::string linden_name = profile_panel->getString("name_text_args", args);
 +	} + +	args["[NAME]"] = name; + +	std::string linden_name = profile_panel->getString("name_text_args", args);  	profile_panel->getChild<LLUICtrl>("name_descr_text")->setValue(linden_name);  }  void LLPanelAvatarProfile::onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)  { -	LLStringUtil::format_map_t args;
 -	args["[DISPLAY_NAME]"] = av_name.mDisplayName;
 -
 -	std::string display_name = getString("display_name_text_args", args);
 -	getChild<LLUICtrl>("display_name_descr_text")->setValue(display_name);
 +	LLStringUtil::format_map_t args; +	args["[DISPLAY_NAME]"] = av_name.mDisplayName; + +	std::string display_name = getString("display_name_text_args", args); +	getChild<LLUICtrl>("display_name_descr_text")->setValue(display_name);  }  void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) @@ -672,23 +672,23 @@ void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data)  	}  	// ask (asynchronously) for the avatar name -	LLHandle<LLPanel> profile_panel_handle = getHandle();
 -	std::string full_name;
 -	if (gCacheName->getFullName(avatar_data->agent_id, full_name))
 -	{
 -		// name in cache, call callback directly
 -		got_full_name_callback( profile_panel_handle, full_name );
 -	}
 -	else
 -	{
 -		// not in cache, lookup name 
 -		gCacheName->get(avatar_data->agent_id, false, boost::bind( got_full_name_callback, profile_panel_handle, _2 ));
 -	}
 -
 -	// get display name
 +	LLHandle<LLPanel> profile_panel_handle = getHandle(); +	std::string full_name; +	if (gCacheName->getFullName(avatar_data->agent_id, full_name)) +	{ +		// name in cache, call callback directly +		got_full_name_callback( profile_panel_handle, full_name ); +	} +	else +	{ +		// not in cache, lookup name  +		gCacheName->get(avatar_data->agent_id, false, boost::bind( got_full_name_callback, profile_panel_handle, _2 )); +	} + +	// get display name  	LLAvatarNameCache::get(avatar_data->avatar_id, -		boost::bind(&LLPanelAvatarProfile::onNameCache, this, _1, _2));
 -
 +		boost::bind(&LLPanelAvatarProfile::onNameCache, this, _1, _2)); +  	args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now());  	std::string register_date = getString("RegisterDateFormat", args);  	getChild<LLUICtrl>("register_date")->setValue(register_date ); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index b8cb62db43..e95441cd58 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -1,297 +1,297 @@ -/** 
 - * @file llpanelavatar.h
 - * @brief LLPanelAvatar and related class definitions
 - *
 - * $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$
 - */
 -
 -#ifndef LL_LLPANELAVATAR_H
 -#define LL_LLPANELAVATAR_H
 -
 -#include "llpanel.h"
 -#include "llavatarpropertiesprocessor.h"
 -#include "llcallingcard.h"
 -#include "llvoiceclient.h"
 -#include "llavatarnamecache.h"
 -
 -class LLComboBox;
 -class LLLineEditor;
 -
 -enum EOnlineStatus
 -{
 -	ONLINE_STATUS_NO      = 0,
 -	ONLINE_STATUS_YES     = 1
 -};
 -
 -/**
 -* Base class for any Profile View or My Profile Panel.
 -*/
 -class LLPanelProfileTab
 -	: public LLPanel
 -	, public LLAvatarPropertiesObserver
 -{
 -public:
 -
 -	/**
 -	 * Sets avatar ID, sets panel as observer of avatar related info replies from server.
 -	 */
 -	virtual void setAvatarId(const LLUUID& id);
 -
 -	/**
 -	 * Returns avatar ID.
 -	 */
 -	virtual const LLUUID& getAvatarId() { return mAvatarId; }
 -
 -	/**
 -	 * Sends update data request to server.
 -	 */
 -	virtual void updateData() = 0;
 -
 -	/**
 -	 * Clears panel data if viewing avatar info for first time and sends update data request.
 -	 */
 -	virtual void onOpen(const LLSD& key);
 -
 -	/**
 -	 * Profile tabs should close any opened panels here.
 -	 *
 -	 * Called from LLPanelProfile::onOpen() before opening new profile.
 -	 * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
 -	 * before new profile is displayed, otherwise new profile will 
 -	 * be hidden behind picture info panel.
 -	 */
 -	virtual void onClosePanel() {}
 -
 -	/**
 -	 * Resets controls visibility, state, etc.
 -	 */
 -	virtual void resetControls(){};
 -
 -	/**
 -	 * Clears all data received from server.
 -	 */
 -	virtual void resetData(){};
 -
 -	/*virtual*/ ~LLPanelProfileTab();
 -
 -protected:
 -
 -	LLPanelProfileTab();
 -
 -	/**
 -	 * Scrolls panel to top when viewing avatar info for first time.
 -	 */
 -	void scrollToTop();
 -
 -	virtual void onMapButtonClick();
 -
 -	virtual void updateButtons();
 -
 -private:
 -
 -	LLUUID mAvatarId;
 -};
 -
 -/**
 -* Panel for displaying Avatar's first and second life related info.
 -*/
 -class LLPanelAvatarProfile
 -	: public LLPanelProfileTab
 -	, public LLFriendObserver
 -	, public LLVoiceClientStatusObserver
 -{
 -public:
 -	LLPanelAvatarProfile();
 -	/*virtual*/ ~LLPanelAvatarProfile();
 -
 -	/*virtual*/ void onOpen(const LLSD& key);
 -
 -	/**
 -	 * LLFriendObserver trigger
 -	 */
 -	virtual void changed(U32 mask);
 -
 -	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
 -	// button when voice is available
 -	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
 -
 -	/*virtual*/ void setAvatarId(const LLUUID& id);
 -
 -	/**
 -	 * Processes data received from server.
 -	 */
 -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
 -
 -	/*virtual*/ BOOL postBuild();
 -
 -	/*virtual*/ void updateData();
 -
 -	/*virtual*/ void resetControls();
 -
 -	/*virtual*/ void resetData();
 -
 -protected:
 -
 -	/**
 -	 * Process profile related data received from server.
 -	 */
 -	virtual void processProfileProperties(const LLAvatarData* avatar_data);
 -
 -	/**
 -	 * Processes group related data received from server.
 -	 */
 -	virtual void processGroupProperties(const LLAvatarGroups* avatar_groups);
 -
 -	/**
 -	 * Fills common for Avatar profile and My Profile fields.
 -	 */
 -	virtual void fillCommonData(const LLAvatarData* avatar_data);
 -
 -	/**
 -	 * Fills partner data.
 -	 */
 -	virtual void fillPartnerData(const LLAvatarData* avatar_data);
 -
 -	/**
 -	 * Fills account status.
 -	 */
 -	virtual void fillAccountStatus(const LLAvatarData* avatar_data);
 -
 -	/**
 -	 * Opens "Pay Resident" dialog.
 -	 */
 -	void pay();
 -
 -	/**
 -	 * opens inventory and IM for sharing items
 -	 */
 -	void share();
 -
 -	/**
 -	 * Add/remove resident to/from your block list.
 -	 */
 -	void toggleBlock();
 -
 -	void kick();
 -	void freeze();
 -	void unfreeze();
 -	void csr();
 -	
 -	bool enableShowOnMap();
 -	bool enableBlock();
 -	bool enableUnblock();
 -	bool enableGod();
 -
 -	void onSeeProfileBtnClick();
 -	void onAddFriendButtonClick();
 -	void onIMButtonClick();
 -	void onCallButtonClick();
 -	void onTeleportButtonClick();
 -	void onShareButtonClick();
 -
 -private:
 -	void onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
 -
 -	typedef std::map< std::string,LLUUID>	group_map_t;
 -	group_map_t 			mGroups;
 -};
 -
 -/**
 - * Panel for displaying own first and second life related info.
 - */
 -class LLPanelMyProfile
 -	: public LLPanelAvatarProfile
 -{
 -public:
 -	LLPanelMyProfile();
 -
 -	/*virtual*/ BOOL postBuild();
 -
 -protected:
 -
 -	/*virtual*/ void onOpen(const LLSD& key);
 -
 -	/*virtual*/ void processProfileProperties(const LLAvatarData* avatar_data);
 -
 -	/*virtual*/ void resetControls();
 -
 -protected:
 -	void onStatusMessageChanged();
 -};
 -
 -/**
 - * Panel for displaying Avatar's notes and modifying friend's rights.
 - */
 -class LLPanelAvatarNotes 
 -	: public LLPanelProfileTab
 -	, public LLFriendObserver
 -	, public LLVoiceClientStatusObserver
 -{
 -public:
 -	LLPanelAvatarNotes();
 -	/*virtual*/ ~LLPanelAvatarNotes();
 -
 -	virtual void setAvatarId(const LLUUID& id);
 -
 -	/** 
 -	 * LLFriendObserver trigger
 -	 */
 -	virtual void changed(U32 mask);
 -
 -	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
 -	// button when voice is available
 -	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
 -
 -	/*virtual*/ void onOpen(const LLSD& key);
 -
 -	/*virtual*/ BOOL postBuild();
 -
 -	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
 -
 -	/*virtual*/ void updateData();
 -
 -protected:
 -
 -	/*virtual*/ void resetControls();
 -
 -	/*virtual*/ void resetData();
 -
 -	/**
 -	 * Fills rights data for friends.
 -	 */
 -	void fillRightsData();
 -
 -	void rightsConfirmationCallback(const LLSD& notification,
 -			const LLSD& response, S32 rights);
 -	void confirmModifyRights(bool grant, S32 rights);
 -	void onCommitRights();
 -	void onCommitNotes();
 -
 -	void onAddFriendButtonClick();
 -	void onIMButtonClick();
 -	void onCallButtonClick();
 -	void onTeleportButtonClick();
 -	void onShareButtonClick();
 -	void enableCheckboxes(bool enable);
 -};
 -
 -#endif // LL_LLPANELAVATAR_H
 +/**  + * @file llpanelavatar.h + * @brief LLPanelAvatar and related class definitions + * + * $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$ + */ + +#ifndef LL_LLPANELAVATAR_H +#define LL_LLPANELAVATAR_H + +#include "llpanel.h" +#include "llavatarpropertiesprocessor.h" +#include "llcallingcard.h" +#include "llvoiceclient.h" +#include "llavatarnamecache.h" + +class LLComboBox; +class LLLineEditor; + +enum EOnlineStatus +{ +	ONLINE_STATUS_NO      = 0, +	ONLINE_STATUS_YES     = 1 +}; + +/** +* Base class for any Profile View or My Profile Panel. +*/ +class LLPanelProfileTab +	: public LLPanel +	, public LLAvatarPropertiesObserver +{ +public: + +	/** +	 * Sets avatar ID, sets panel as observer of avatar related info replies from server. +	 */ +	virtual void setAvatarId(const LLUUID& id); + +	/** +	 * Returns avatar ID. +	 */ +	virtual const LLUUID& getAvatarId() { return mAvatarId; } + +	/** +	 * Sends update data request to server. +	 */ +	virtual void updateData() = 0; + +	/** +	 * Clears panel data if viewing avatar info for first time and sends update data request. +	 */ +	virtual void onOpen(const LLSD& key); + +	/** +	 * Profile tabs should close any opened panels here. +	 * +	 * Called from LLPanelProfile::onOpen() before opening new profile. +	 * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel +	 * before new profile is displayed, otherwise new profile will  +	 * be hidden behind picture info panel. +	 */ +	virtual void onClosePanel() {} + +	/** +	 * Resets controls visibility, state, etc. +	 */ +	virtual void resetControls(){}; + +	/** +	 * Clears all data received from server. +	 */ +	virtual void resetData(){}; + +	/*virtual*/ ~LLPanelProfileTab(); + +protected: + +	LLPanelProfileTab(); + +	/** +	 * Scrolls panel to top when viewing avatar info for first time. +	 */ +	void scrollToTop(); + +	virtual void onMapButtonClick(); + +	virtual void updateButtons(); + +private: + +	LLUUID mAvatarId; +}; + +/** +* Panel for displaying Avatar's first and second life related info. +*/ +class LLPanelAvatarProfile +	: public LLPanelProfileTab +	, public LLFriendObserver +	, public LLVoiceClientStatusObserver +{ +public: +	LLPanelAvatarProfile(); +	/*virtual*/ ~LLPanelAvatarProfile(); + +	/*virtual*/ void onOpen(const LLSD& key); + +	/** +	 * LLFriendObserver trigger +	 */ +	virtual void changed(U32 mask); + +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + +	/*virtual*/ void setAvatarId(const LLUUID& id); + +	/** +	 * Processes data received from server. +	 */ +	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + +	/*virtual*/ BOOL postBuild(); + +	/*virtual*/ void updateData(); + +	/*virtual*/ void resetControls(); + +	/*virtual*/ void resetData(); + +protected: + +	/** +	 * Process profile related data received from server. +	 */ +	virtual void processProfileProperties(const LLAvatarData* avatar_data); + +	/** +	 * Processes group related data received from server. +	 */ +	virtual void processGroupProperties(const LLAvatarGroups* avatar_groups); + +	/** +	 * Fills common for Avatar profile and My Profile fields. +	 */ +	virtual void fillCommonData(const LLAvatarData* avatar_data); + +	/** +	 * Fills partner data. +	 */ +	virtual void fillPartnerData(const LLAvatarData* avatar_data); + +	/** +	 * Fills account status. +	 */ +	virtual void fillAccountStatus(const LLAvatarData* avatar_data); + +	/** +	 * Opens "Pay Resident" dialog. +	 */ +	void pay(); + +	/** +	 * opens inventory and IM for sharing items +	 */ +	void share(); + +	/** +	 * Add/remove resident to/from your block list. +	 */ +	void toggleBlock(); + +	void kick(); +	void freeze(); +	void unfreeze(); +	void csr(); +	 +	bool enableShowOnMap(); +	bool enableBlock(); +	bool enableUnblock(); +	bool enableGod(); + +	void onSeeProfileBtnClick(); +	void onAddFriendButtonClick(); +	void onIMButtonClick(); +	void onCallButtonClick(); +	void onTeleportButtonClick(); +	void onShareButtonClick(); + +private: +	void onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + +	typedef std::map< std::string,LLUUID>	group_map_t; +	group_map_t 			mGroups; +}; + +/** + * Panel for displaying own first and second life related info. + */ +class LLPanelMyProfile +	: public LLPanelAvatarProfile +{ +public: +	LLPanelMyProfile(); + +	/*virtual*/ BOOL postBuild(); + +protected: + +	/*virtual*/ void onOpen(const LLSD& key); + +	/*virtual*/ void processProfileProperties(const LLAvatarData* avatar_data); + +	/*virtual*/ void resetControls(); + +protected: +	void onStatusMessageChanged(); +}; + +/** + * Panel for displaying Avatar's notes and modifying friend's rights. + */ +class LLPanelAvatarNotes  +	: public LLPanelProfileTab +	, public LLFriendObserver +	, public LLVoiceClientStatusObserver +{ +public: +	LLPanelAvatarNotes(); +	/*virtual*/ ~LLPanelAvatarNotes(); + +	virtual void setAvatarId(const LLUUID& id); + +	/**  +	 * LLFriendObserver trigger +	 */ +	virtual void changed(U32 mask); + +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + +	/*virtual*/ void onOpen(const LLSD& key); + +	/*virtual*/ BOOL postBuild(); + +	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + +	/*virtual*/ void updateData(); + +protected: + +	/*virtual*/ void resetControls(); + +	/*virtual*/ void resetData(); + +	/** +	 * Fills rights data for friends. +	 */ +	void fillRightsData(); + +	void rightsConfirmationCallback(const LLSD& notification, +			const LLSD& response, S32 rights); +	void confirmModifyRights(bool grant, S32 rights); +	void onCommitRights(); +	void onCommitNotes(); + +	void onAddFriendButtonClick(); +	void onIMButtonClick(); +	void onCallButtonClick(); +	void onTeleportButtonClick(); +	void onShareButtonClick(); +	void enableCheckboxes(bool enable); +}; + +#endif // LL_LLPANELAVATAR_H diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 90ed8b9e58..4a74b7925c 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -569,6 +569,7 @@ static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel,  	if (color_swatch_ctrl)  	{  		color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex)); +		color_swatch_ctrl->closeFloaterColorPicker();  	}  } diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index d1362d7922..3dbc637318 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1843,7 +1843,8 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg)  {  	lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl; -	saveRoleChanges(); +	saveRoleChanges(true); +  	LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID);  	notifyObservers(); @@ -2022,7 +2023,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()  		return;  	} -	saveRoleChanges(); +	saveRoleChanges(false);  	// Check if there is anything selected.  	LLScrollListItem* item = mRolesList->getFirstSelected(); @@ -2385,7 +2386,7 @@ void LLPanelGroupRolesSubTab::handleDeleteRole()  	notifyObservers();  } -void LLPanelGroupRolesSubTab::saveRoleChanges() +void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role)  {  	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); @@ -2400,13 +2401,23 @@ void LLPanelGroupRolesSubTab::saveRoleChanges()  		rd.mRoleDescription = mRoleDescription->getText();  		rd.mRoleTitle = mRoleTitle->getText(); +		S32 role_members_count = 0; +		if (mSelectedRole.isNull()) +		{ +			role_members_count = gdatap->mMemberCount; +		} +		else if(LLGroupRoleData* grd = get_ptr_in_map(gdatap->mRoles, mSelectedRole)) +		{ +			role_members_count = grd->getTotalMembersInRole(); +		} +  		gdatap->setRoleData(mSelectedRole,rd);  		mRolesList->deleteSingleItem(mRolesList->getItemIndex(mSelectedRole)); -		LLSD row = createRoleItem(mSelectedRole,rd.mRoleName,rd.mRoleTitle,0); +		LLSD row = createRoleItem(mSelectedRole,rd.mRoleName,rd.mRoleTitle,role_members_count);  		LLScrollListItem* item = mRolesList->addElement(row, ADD_BOTTOM, this); -		item->setSelected(TRUE); +		item->setSelected(select_saved_role);  		mHasRoleChange = FALSE;  	} diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 270259c16f..a55e264150 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -257,7 +257,7 @@ public:  	static void onDeleteRole(void*);  	void handleDeleteRole(); -	void saveRoleChanges(); +	void saveRoleChanges(bool select_saved_role);  	virtual void setGroupID(const LLUUID& id);  protected: diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index e8c8273a9d..80f6862169 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -71,6 +71,7 @@ static void collapse_all_folders(LLFolderView* root_folder);  static void expand_all_folders(LLFolderView* root_folder);  static bool has_expanded_folders(LLFolderView* root_folder);  static bool has_collapsed_folders(LLFolderView* root_folder); +static void toggle_restore_menu(LLMenuGL* menu, BOOL visible, BOOL enabled);  /**   * Functor counting expanded and collapsed folders in folder view tree to know @@ -708,6 +709,9 @@ void LLLandmarksPanel::initListCommandsHandlers()  	mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());  	mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mGearLandmarkMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); +	mGearFolderMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); +  	mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME));  } @@ -1079,6 +1083,60 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)  	{  		doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1));  	} +	else if ("restore" == command_name && mCurrentSelectedList) +	{ +		mCurrentSelectedList->doToSelected(userdata); +	} +} + +void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param) +{ +	bool new_visibility = param["visibility"].asBoolean(); + +	// We don't have to update items visibility if the menu is hiding. +	if (!new_visibility) return; + +	BOOL are_any_items_in_trash = FALSE; +	BOOL are_all_items_in_trash = TRUE; + +	LLFolderView* root_folder_view = mCurrentSelectedList ? mCurrentSelectedList->getRootFolder() : NULL; +	if(root_folder_view) +	{ +		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + +		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); + +		// Iterate through selected items to find out if any of these items are in Trash +		// or all the items are in Trash category. +		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) +		{ +			LLFolderViewItem* item = root_folder_view->getItemByID(*iter); + +			// If no item is found it might be a folder id. +			if (!item) +			{ +				item = root_folder_view->getFolderByID(*iter); +			} +			if (!item) continue; + +			LLFolderViewEventListener* listenerp = item->getListener(); +			if(!listenerp) continue; + +			// Trash category itself should not be included because it can't be +			// actually restored from trash. +			are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id; + +			// If there are any selected items in Trash including the Trash category itself +			// we show "Restore Item" in context menu and hide other irrelevant items. +			are_any_items_in_trash |= listenerp->isItemInTrash(); +		} +	} + +	// Display "Restore Item" menu entry if at least one of the selected items +	// is in Trash or the Trash category itself is among selected items. +	// Hide other menu entries in this case. +	// Enable this menu entry only if all selected items are in the Trash category. +	toggle_restore_menu((LLMenuGL*)ctrl, are_any_items_in_trash, are_all_items_in_trash);  }  /* @@ -1414,4 +1472,31 @@ static bool has_collapsed_folders(LLFolderView* root_folder)  	return true;  } + +// Displays "Restore Item" context menu entry while hiding +// all other entries or vice versa. +// Sets "Restore Item" enabled state. +void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled) +{ +	if (!menu) return; + +	const LLView::child_list_t *list = menu->getChildList(); +	for (LLView::child_list_t::const_iterator itor = list->begin(); +		 itor != list->end(); +		 ++itor) +	{ +		LLView *menu_item = (*itor); +		std::string name = menu_item->getName(); + +		if ("restore_item" == name) +		{ +			menu_item->setVisible(visible); +			menu_item->setEnabled(enabled); +		} +		else +		{ +			menu_item->setVisible(!visible); +		} +	} +}  // EOF diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 8dcbca0440..b2f4e92473 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -129,6 +129,14 @@ private:  	void onCustomAction(const LLSD& command_name);  	/** +	 * Updates context menu depending on the selected items location. +	 * +	 * For items in Trash category the menu includes the "Restore Item" +	 * context menu entry. +	 */ +	void onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param); + +	/**  	 * Determines if an item can be modified via context/gear menu.  	 *  	 * It validates Places Landmarks rules first. And then LLFolderView permissions. diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index fcc67d6840..14e39f2c48 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -958,7 +958,7 @@ void LLPanelNearByMedia::onAdvancedButtonClick()  void LLPanelNearByMedia::onMoreLess()  { -	bool is_more = getChild<LLUICtrl>("more_btn")->getVisible(); +	bool is_more = getChild<LLButton>("more_btn")->getToggleState();  	mNearbyMediaPanel->setVisible(is_more);  	// enable resizing when expanded @@ -969,8 +969,7 @@ void LLPanelNearByMedia::onMoreLess()  	setShape(new_rect); -	getChild<LLUICtrl>("more_btn")->setVisible(!is_more); -	getChild<LLUICtrl>("less_btn")->setVisible(is_more); +	getChild<LLUICtrl>("more_btn")->setVisible(true);  }  void LLPanelNearByMedia::updateControls() diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 211b9cf4b1..0b6267c9e6 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -766,22 +766,12 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const  		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());  		if(object)  		{ -			const LLInventoryItem *inv = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID)); -			if (inv) +			const LLInventoryObject* cat = object->getInventoryObject(mUUID); +			if ( (cat) && (move_inv_category_world_to_agent(mUUID, LLUUID::null, FALSE)) )  			{ -				const LLPermissions& perm = inv->getPermissions(); -				bool can_copy = gAgent.allowOperation(PERM_COPY, perm, -														GP_OBJECT_MANIPULATE); -				if((can_copy && perm.allowTransferTo(gAgent.getID())) -				   || object->permYouOwner()) -//				   || gAgent.isGodlike()) - -				{ -					*type = LLViewerAssetType::lookupDragAndDropType(inv->getType()); - -					*id = inv->getUUID(); -					return TRUE; -				} +				*type = LLViewerAssetType::lookupDragAndDropType(cat->getType()); +				*id = mUUID; +				return TRUE;  			}  		}  	} diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 54198d6aa4..b07a46a222 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -54,6 +54,7 @@  #include "llgroupactions.h"  #include "llgrouplist.h"  #include "llinventoryobserver.h" +#include "llnetmap.h"  #include "llpanelpeoplemenus.h"  #include "llsidetray.h"  #include "llsidetraypanelcontainer.h" @@ -494,7 +495,8 @@ LLPanelPeople::LLPanelPeople()  		mNearbyGearButton(NULL),  		mFriendsGearButton(NULL),  		mGroupsGearButton(NULL), -		mRecentGearButton(NULL) +		mRecentGearButton(NULL), +		mMiniMap(NULL)  {  	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));  	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this)); @@ -567,6 +569,9 @@ BOOL LLPanelPeople::postBuild()  	mNearbyList->setNoItemsMsg(getString("no_one_near"));  	mNearbyList->setNoFilteredItemsMsg(getString("no_one_filtered_near"));  	mNearbyList->setShowIcons("NearbyListShowIcons"); +	mMiniMap = (LLNetMap*)getChildView("Net Map",true); +	mMiniMap->setToolTipMsg(gSavedSettings.getBOOL("DoubleClickTeleport") ?  +		getString("AltMiniMapToolTipMsg") :	getString("MiniMapToolTipMsg"));  	mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");  	mRecentList->setNoItemsCommentText(getString("no_recent_people")); @@ -1088,6 +1093,12 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)  void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)  { +	if (getActiveTabName() == NEARBY_TAB_NAME) +	{ +		uuid_vec_t selected_uuids; +		getCurrentItemIDs(selected_uuids); +		mMiniMap->setSelected(selected_uuids); +	} else  	// Make sure only one of the friends lists (online/all) has selection.  	if (getActiveTabName() == FRIENDS_TAB_NAME)  	{ diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index b496bb3779..46c58cd139 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -142,6 +142,7 @@ private:  	LLAvatarList*			mNearbyList;  	LLAvatarList*			mRecentList;  	LLGroupList*			mGroupList; +	LLNetMap*				mMiniMap;  	LLHandle<LLView>		mGroupPlusMenuHandle;  	LLHandle<LLView>		mNearbyViewSortMenuHandle; diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 7657cccd4e..6cfb708112 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -273,6 +273,8 @@ void LLPreviewTexture::saveAs()  	mSaveFileName = file_picker.getFirstFile();  	mLoadingFullImage = TRUE;  	getWindow()->incBusyCount(); + +	mImage->forceToSaveRawImage(0) ;//re-fetch the raw image if the old one is removed.  	mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave,   								0, TRUE, FALSE, new LLUUID( mItemUUID ), &mCallbackTextureList );  } diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index e5ef51bdd1..3862dac340 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -33,6 +33,7 @@  #include "llpanel.h"  #include "llhttpclient.h"  #include "llsdserialize.h" +#include "llurlentry.h"  #include "llviewerregion.h"  #include "llview.h" @@ -168,6 +169,18 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v  	{  		observers.erase(*i);  	} + +	LLUrlEntryParcel::LLParcelData url_data; +	url_data.parcel_id = parcel_data.parcel_id; +	url_data.name = parcel_data.name; +	url_data.sim_name = parcel_data.sim_name; +	url_data.global_x = parcel_data.global_x; +	url_data.global_y = parcel_data.global_y; +	url_data.global_z = parcel_data.global_z; + +	// Pass the parcel data to LLUrlEntryParcel to render +	// human readable parcel name. +	LLUrlEntryParcel::processParcelInfo(url_data);  }  void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 7478ed5f9a..65a9a493f6 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -235,7 +235,7 @@ public:  	{  		bool operator()(LLSelectNode* node);  	}; -	typedef boost::filter_iterator<is_root, list_t::iterator > valid_root_iterator; +	typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator;  	valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); }  	valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index b316171604..363fe5f12b 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -185,7 +185,7 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)  {  	LLSD visibility;  	visibility["visible"] = new_visibility.asBoolean(); -	visibility["reset_accordion"] = true; +	visibility["reset_accordion"] = false;  	updateToVisibility(visibility);  } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index aef665a35c..eb537c7d7b 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -141,6 +141,8 @@ public:  	void			toggleTabDocked(); +	BOOL			handleScrollWheel(S32 x, S32 y, S32 clicks); +  	LLPanel *getPanel();  private:  	std::string mTabTitle; @@ -269,6 +271,15 @@ void LLSideTrayTab::toggleTabDocked()  	LLFloaterReg::toggleInstance("side_bar_tab", tab_name);  } +BOOL LLSideTrayTab::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ +	// Let children handle the event +	LLUICtrl::handleScrollWheel(x, y, clicks); + +	// and then eat it to prevent in-world scrolling (STORM-351). +	return TRUE; +} +  void LLSideTrayTab::dock(LLFloater* floater_tab)  {  	LLSideTray* side_tray = getSideTray(); @@ -498,8 +509,8 @@ private:  LLSideTray::Params::Params()  :	collapsed("collapsed",false), -	tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("sidebar_tab_left.tga")), -	tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("button_enabled_selected_32x128.tga")), +	tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("taskpanel/TaskPanel_Tab_Off.png")), +	tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("taskpanel/TaskPanel_Tab_Selected.png")),  	default_button_width("tab_btn_width",32),  	default_button_height("tab_btn_height",32),  	default_button_margin("tab_btn_margin",0) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 960e72ee42..8adb8c30e0 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2578,6 +2578,49 @@ void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)  	gGL.end();  } +void renderUpdateType(LLDrawable* drawablep) +{ +	LLViewerObject* vobj = drawablep->getVObj(); +	if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType()) +	{ +		return; +	} +	LLGLEnable blend(GL_BLEND); +	switch (vobj->getLastUpdateType()) +	{ +	case OUT_FULL: +		glColor4f(0,1,0,0.5f); +		break; +	case OUT_TERSE_IMPROVED: +		glColor4f(0,1,1,0.5f); +		break; +	case OUT_FULL_COMPRESSED: +		if (vobj->getLastUpdateCached()) +		{ +			glColor4f(1,0,0,0.5f); +		} +		else +		{ +			glColor4f(1,1,0,0.5f); +		} +		break; +	case OUT_FULL_CACHED: +		glColor4f(0,0,1,0.5f); +		break; +	default: +		llwarns << "Unknown update_type " << vobj->getLastUpdateType() << llendl; +		break; +	}; +	S32 num_faces = drawablep->getNumFaces(); +	if (num_faces) +	{ +		for (S32 i = 0; i < num_faces; ++i) +		{ +			pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); +		} +	} +} +  void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)  { @@ -3018,6 +3061,10 @@ public:  			{  				renderRaycast(drawable);  			} +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_UPDATE_TYPE)) +			{ +				renderUpdateType(drawable); +			}  			LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); @@ -3180,6 +3227,7 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_OCCLUSION |  									  LLPipeline::RENDER_DEBUG_LIGHTS |  									  LLPipeline::RENDER_DEBUG_BATCH_SIZE | +									  LLPipeline::RENDER_DEBUG_UPDATE_TYPE |  									  LLPipeline::RENDER_DEBUG_BBOXES |  									  LLPipeline::RENDER_DEBUG_POINTS |  									  LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 611f9de2e6..0eac7d5e2a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -139,6 +139,7 @@  #include "lltrans.h"  #include "llui.h"  #include "llurldispatcher.h" +#include "llurlentry.h"  #include "llslurl.h"  #include "llurlhistory.h"  #include "llurlwhitelist.h" @@ -980,7 +981,6 @@ bool idle_startup()  			login->setSkipOptionalUpdate(true);  		} -		login->setUserInteraction(show_connect_box);  		login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());  		login->setLastExecEvent(gLastExecEvent);  		login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance())); @@ -2882,9 +2882,17 @@ bool process_login_success_response()  	if(!text.empty()) gAgentID.set(text);  	gDebugInfo["AgentID"] = text; +	// Agent id needed for parcel info request in LLUrlEntryParcel +	// to resolve parcel name. +	LLUrlEntryParcel::setAgentID(gAgentID); +  	text = response["session_id"].asString();  	if(!text.empty()) gAgentSessionID.set(text);  	gDebugInfo["SessionID"] = text; + +	// Session id needed for parcel info request in LLUrlEntryParcel +	// to resolve parcel name. +	LLUrlEntryParcel::setSessionID(gAgentSessionID);  	text = response["secure_session_id"].asString();  	if(!text.empty()) gAgent.mSecureSessionID.set(text); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 6a213309a0..f54214b95c 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -326,6 +326,7 @@ bool LLTextureCacheRemoteWorker::doRead()  	// First state / stage : find out if the file is local  	if (mState == INIT)  	{ +#if 0  		std::string filename = mCache->getLocalFileName(mID);	  		// Is it a JPEG2000 file?   		{ @@ -360,6 +361,11 @@ bool LLTextureCacheRemoteWorker::doRead()  		}  		// Determine the next stage: if we found a file, then LOCAL else CACHE  		mState = (local_size > 0 ? LOCAL : CACHE); + +		llassert_always(mState == CACHE) ; +#else +		mState = CACHE; +#endif  	}  	// Second state / stage : if the file is local, load it and leave @@ -1592,7 +1598,7 @@ void LLTextureCache::purgeTextures(bool validate)  	if (validate)  	{  		validate_idx = gSavedSettings.getU32("CacheValidateCounter"); -		U32 next_idx = (++validate_idx) % 256; +		U32 next_idx = (validate_idx + 1) % 256;  		gSavedSettings.setU32("CacheValidateCounter", next_idx);  		LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL;  	} @@ -1858,8 +1864,22 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)  //called after mHeaderMutex is locked.  void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)  { + 	bool file_maybe_exists = true;	// Always attempt to remove when idx is invalid. +  	if(idx >= 0) //valid entry  	{ +		if (entry.mBodySize == 0)	// Always attempt to remove when mBodySize > 0. +		{ +		  if (LLAPRFile::isExist(filename, getLocalAPRFilePool()))		// Sanity check. Shouldn't exist when body size is 0. +		  { +			  LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL; +		  } +		  else +		  { +			  file_maybe_exists = false; +		  } +		} +  		entry.mImageSize = -1;  		entry.mBodySize = 0;  		mHeaderIDMap.erase(entry.mID); @@ -1869,7 +1889,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)  		mFreeList.insert(idx);	  	} -	LLAPRFile::remove(filename, getLocalAPRFilePool());		 +	if (file_maybe_exists) +	{ +		LLAPRFile::remove(filename, getLocalAPRFilePool());		 +	}  }  bool LLTextureCache::removeFromCache(const LLUUID& id) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 4f63abb152..18c3a3b87d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1141,7 +1141,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			//1, not openning too many file descriptors at the same time;  			//2, control the traffic of http so udp gets bandwidth.  			// -			static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 32 ; +			static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ;  			if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE)  			{  				return false ; //wait. @@ -1822,6 +1822,7 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mImageDecodeThread(imagedecodethread),  	  mTextureBandwidth(0),  	  mHTTPTextureBits(0), +	  mTotalHTTPRequests(0),  	  mCurlGetRequest(NULL),  	  mQAMode(qa_mode)  { @@ -1973,6 +1974,7 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)  {  	LLMutexLock lock(&mNetworkQueueMutex);  	mHTTPTextureQueue.insert(id); +	mTotalHTTPRequests++;  }  void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size) @@ -2035,6 +2037,15 @@ S32 LLTextureFetch::getNumHTTPRequests()  	return size ;  } +U32 LLTextureFetch::getTotalNumHTTPRequests() +{ +	mNetworkQueueMutex.lock() ; +	U32 size = mTotalHTTPRequests ; +	mNetworkQueueMutex.unlock() ; + +	return size ; +} +  // call lockQueue() first!  LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)  { diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index ad00a7ea36..d101da1f4b 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -79,6 +79,7 @@ public:  	void dump();  	S32 getNumRequests() ;  	S32 getNumHTTPRequests() ; +	U32 getTotalNumHTTPRequests() ;  	// Public for access by callbacks      S32 getPending(); @@ -183,6 +184,9 @@ private:  	U32 mHTTPTextureBits; +	//debug use +	U32 mTotalHTTPRequests ; +  	// Out-of-band cross-thread command queue.  This command queue  	// is logically tied to LLQueuedThread's list of  	// QueuedRequest instances and so must be covered by the diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b9a15fd1f4..0115115a23 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -516,6 +516,7 @@ void LLGLTexMemBar::draw()  	S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);  	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);  	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); +	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;  	//----------------------------------------------------------------------------  	LLGLSUIDefault gls_ui;  	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -526,13 +527,13 @@ void LLGLTexMemBar::draw()  	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB", +	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",  					total_mem,  					max_total_mem,  					bound_mem,  					max_bound_mem,  					LLImageRaw::sGlobalRawMemory >> 20,	discard_bias, -					cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded); +					cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);  	//, cache_entries, cache_max_entries  	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b3642a2c1e..cc851e676b 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -366,11 +366,11 @@ void LLViewerInventoryItem::fetchFromServer(void) const  		{  		  if(gAgent.getID() != mPermissions.getOwner())  		    { -		      url = region->getCapability("FetchLib"); +		      url = region->getCapability("FetchLib2");  		    }  		  else  		    {	 -		      url = region->getCapability("FetchInventory"); +		      url = region->getCapability("FetchInventory2");  		    }  		}  		else @@ -648,7 +648,7 @@ bool LLViewerInventoryCategory::fetch()  		std::string url;  		if (gAgent.getRegion())  		{ -			url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents"); +			url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2");  		}  		else  		{ @@ -660,7 +660,7 @@ bool LLViewerInventoryCategory::fetch()  		}  		else  		{	//Deprecated, but if we don't have a capability, use the old system. -			llinfos << "WebFetchInventoryDescendents capability not found.  Using deprecated UDP message." << llendl; +			llinfos << "FetchInventoryDescendents2 capability not found.  Using deprecated UDP message." << llendl;  			LLMessageSystem* msg = gMessageSystem;  			msg->newMessage("FetchInventoryDescendents");  			msg->nextBlock("AgentData"); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 433151860c..f16d8814dd 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1436,9 +1436,12 @@ void LLViewerMedia::proxyWindowClosed(const std::string &uuid)  // static  void LLViewerMedia::createSpareBrowserMediaSource()  { -	if(!sSpareBrowserMediaSource) +	// If we don't have a spare browser media source, create one. +	// However, if PluginAttachDebuggerToPlugins is set then don't spawn a spare +	// SLPlugin process in order to not be confused by an unrelated gdb terminal +	// popping up at the moment we start a media plugin. +	if (!sSpareBrowserMediaSource && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))  	{ -		// If we don't have a spare browser media source, create one.  		// The null owner will keep the browser plugin from fully initializing   		// (specifically, it keeps LLPluginClassMedia from negotiating a size change,   		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color) @@ -1694,7 +1697,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_  	LLPluginClassMedia* media_source = NULL;  	// HACK: we always try to keep a spare running webkit plugin around to improve launch times. -	if(plugin_basename == "media_plugin_webkit") +	// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it. +	if(plugin_basename == "media_plugin_webkit" && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))  	{  		media_source = LLViewerMedia::getSpareBrowserMediaSource();  		if(media_source) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9e16bf2fbb..7cc04e0338 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -557,7 +557,7 @@ class LLAdvancedCheckConsole : public view_listener_t  			new_value = get_visibility( (void*)gDebugView->mMemoryView );  		}  #endif - +		  		return new_value;  	}  }; @@ -906,6 +906,10 @@ U32 info_display_from_string(std::string info_display)  	{  		return LLPipeline::RENDER_DEBUG_BATCH_SIZE;  	} +	else if ("update type" == info_display) +	{ +		return LLPipeline::RENDER_DEBUG_UPDATE_TYPE; +	}  	else if ("texture anim" == info_display)  	{  		return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM; @@ -4197,9 +4201,9 @@ class LLObjectEnableReturn : public view_listener_t  					{  						virtual bool apply(LLViewerObject* obj)  						{ -							return (obj->isOverAgentOwnedLand() || -									obj->isOverGroupOwnedLand() || -									obj->permModify()); +							return  +								obj->permModify() || +								obj->isReturnable();  						}  					} func;  					const bool firstonly = true; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 7dc5d96689..103989ee80 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -171,31 +171,6 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =  	FALSE	// ControlYourCamera  }; -// Extract channel and version from a string like "SL Web Viewer Beta 10.11.29.215604". -// (channel: "SL Web Viewer Beta", version: "10.11.29.215604") -static bool parse_version_info(const std::string& version_info, std::string& channel, std::string& ver) -{ -	size_t last_space = version_info.rfind(" "); -	channel = version_info; - -	if (last_space != std::string::npos) -	{ -		try -		{ -			ver = version_info.substr(last_space + 1); -			channel.replace(last_space, ver.length() + 1, ""); // strip version -		} -		catch (std::out_of_range) -		{ -			return false; -		} - -		return true; -	} - -	return false; -} -  bool friendship_offer_callback(const LLSD& notification, const LLSD& response)  {  	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -2746,6 +2721,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				LLSD args;  				args["slurl"] = location;  				args["type"] = LLNotificationsUI::NT_NEARBYCHAT; + +				// Look for IRC-style emotes here so object name formatting is correct +				std::string prefix = message.substr(0, 4); +				if (prefix == "/me " || prefix == "/me'") +				{ +					chat.mChatStyle = CHAT_STYLE_IRC; +				} +  				LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);  			} @@ -3848,31 +3831,6 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)  		return;  	} -	if (!gLastVersionChannel.empty()) -	{ -		std::string url = regionp->getCapability("ServerReleaseNotes"); -		if (url.empty()) -		{ -			// The capability hasn't arrived yet or is not supported, -			// fall back to parsing server version channel. -			std::string channel, ver; -			if (!parse_version_info(version_channel, channel, ver)) -			{ -				llwarns << "Failed to parse server version channel (" << version_channel << ")" << llendl; -			} - -			url = gSavedSettings.getString("ReleaseNotesURL"); -			LLSD args; -			args["CHANNEL"] = LLWeb::escapeURL(channel); -			args["VERSION"] = LLWeb::escapeURL(ver); -			LLStringUtil::format(url, args); -		} - -		LLSD args; -		args["URL"] = url; -		LLNotificationsUtil::add("ServerVersionChanged", args); -	} -  	gLastVersionChannel = version_channel;  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1804fac1b3..090d3cadd4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -210,7 +210,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mLastInterpUpdateSecs(0.f),  	mLastMessageUpdateSecs(0.f),  	mLatestRecvPacketID(0), -	mCircuitPacketCount(0),  	mData(NULL),  	mAudioSourcep(NULL),  	mAudioGain(1.f), @@ -234,7 +233,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mState(0),  	mMedia(NULL),  	mClickAction(0), -	mAttachmentItemID(LLUUID::null) +	mAttachmentItemID(LLUUID::null), +	mLastUpdateType(OUT_UNKNOWN), +	mLastUpdateCached(FALSE)  {  	if (!is_global)  	{ @@ -516,20 +517,23 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)  // This method returns true if the object is over land owned by the  // agent. -BOOL LLViewerObject::isOverAgentOwnedLand() const +bool LLViewerObject::isReturnable()  { -	return mRegionp -		&& mRegionp->getParcelOverlay() -		&& mRegionp->getParcelOverlay()->isOwnedSelf(getPositionRegion()); -} +	if (isAttachment()) +	{ +		return false; +	} +	std::vector<LLBBox> boxes; +	boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); +	for (child_list_t::iterator iter = mChildList.begin(); +		 iter != mChildList.end(); iter++) +	{ +		LLViewerObject* child = *iter; +		boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); +	} -// This method returns true if the object is over land owned by the -// agent. -BOOL LLViewerObject::isOverGroupOwnedLand() const -{ -	return mRegionp  -		&& mRegionp->getParcelOverlay() -		&& mRegionp->getParcelOverlay()->isOwnedGroup(getPositionRegion()); +	return mRegionp +		&& mRegionp->objectIsReturnable(getPositionRegion(), boxes);  }  BOOL LLViewerObject::setParent(LLViewerObject* parent) @@ -1879,7 +1883,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	}  	mLatestRecvPacketID = packet_id; -	mCircuitPacketCount = 0;  	// Set the change flags for scale  	if (new_scale != getScale()) @@ -2202,7 +2205,8 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)  		LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	  		LLVector3 new_v = accel * dt; -		if (time_since_last_update > sPhaseOutUpdateInterpolationTime) +		if (time_since_last_update > sPhaseOutUpdateInterpolationTime && +			sPhaseOutUpdateInterpolationTime > 0.0)  		{	// Haven't seen a viewer update in a while, check to see if the ciruit is still active  			if (mRegionp)  			{	// The simulator will NOT send updates if the object continues normally on the path @@ -2211,9 +2215,12 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)  				LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );  				if (cdp)  				{ +					// Find out how many seconds since last packet arrived on the circuit +					F64 time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime(); +  					if (!cdp->isAlive() ||		// Circuit is dead or blocked  						 cdp->isBlocked() ||	// or doesn't seem to be getting any packets -						 (mCircuitPacketCount > 0 && mCircuitPacketCount == cdp->getPacketsIn())) +						 (time_since_last_packet > sPhaseOutUpdateInterpolationTime))  					{  						// Start to reduce motion interpolation since we haven't seen a server update in a while  						F64 time_since_last_interpolation = time - mLastInterpUpdateSecs; @@ -2244,9 +2251,6 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)  						new_pos = new_pos * ((F32) phase_out);  						new_v = new_v * ((F32) phase_out);  					} - -					// Save current circuit packet count to see if it changes  -					mCircuitPacketCount = cdp->getPacketsIn();  				}  			}  		} @@ -5100,7 +5104,6 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)  	}  	mLatestRecvPacketID = 0; -	mCircuitPacketCount = 0;  	mRegionp = regionp;  	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) @@ -5400,6 +5403,26 @@ void LLViewerObject::setAttachmentItemID(const LLUUID &id)  	mAttachmentItemID = id;  } +EObjectUpdateType LLViewerObject::getLastUpdateType() const +{ +	return mLastUpdateType; +} + +void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type) +{ +	mLastUpdateType = last_update_type; +} + +BOOL LLViewerObject::getLastUpdateCached() const +{ +	return mLastUpdateCached; +} + +void LLViewerObject::setLastUpdateCached(BOOL last_update_cached) +{ +	mLastUpdateCached = last_update_cached; +} +  const LLUUID &LLViewerObject::extractAttachmentItemID()  {  	LLUUID item_id = LLUUID::null; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index fe670f8827..7afb7f464b 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -77,6 +77,7 @@ typedef enum e_object_update_type  	OUT_TERSE_IMPROVED,  	OUT_FULL_COMPRESSED,  	OUT_FULL_CACHED, +	OUT_UNKNOWN,  } EObjectUpdateType; @@ -226,12 +227,9 @@ public:  	virtual BOOL hasLightTexture() const			{ return FALSE; }  	// This method returns true if the object is over land owned by -	// the agent. -	BOOL isOverAgentOwnedLand() const; - -	// True if over land owned by group of which the agent is -	// either officer or member. -	BOOL isOverGroupOwnedLand() const; +	// the agent, one of its groups, or it encroaches and  +	// anti-encroachment is enabled +	bool isReturnable();  	/*  	// This method will scan through this object, and then query the @@ -615,7 +613,6 @@ protected:  	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation  	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator  	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator -	U32				mCircuitPacketCount;			// Packet tracking for early detection of a stopped simulator circuit  	// extra data sent from the sim...currently only used for tree species info  	U8* mData; @@ -696,8 +693,15 @@ public:  	const LLUUID &getAttachmentItemID() const;  	void setAttachmentItemID(const LLUUID &id);  	const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object +	EObjectUpdateType getLastUpdateType() const; +	void setLastUpdateType(EObjectUpdateType last_update_type); +	BOOL getLastUpdateCached() const; +	void setLastUpdateCached(BOOL last_update_cached); +  private:  	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. +	EObjectUpdateType	mLastUpdateType; +	BOOL	mLastUpdateCached;  };  /////////////////// diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index f5a32438cf..970cc2e2a7 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -56,6 +56,7 @@  #include "llresmgr.h"  #include "llviewerregion.h"  #include "llviewerstats.h" +#include "llviewerstatsrecorder.h"  #include "llvoavatarself.h"  #include "lltoolmgr.h"  #include "lltoolpie.h" @@ -159,19 +160,13 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,  	return (((U64)index) << 32) | (U64)local_id;  } -BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object) +BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)  { -	if(object.getRegion()) +	if(objectp && objectp->getRegion())  	{ -		U32 local_id = object.mLocalID; -		LLHost region_host = object.getRegion()->getHost(); -		if(!region_host.isOk()) -		{ -			return FALSE ; -		} - -		U32 ip = region_host.getAddress(); -		U32 port = region_host.getPort(); +		U32 local_id = objectp->mLocalID;		 +		U32 ip = objectp->getRegion()->getHost().getAddress(); +		U32 port = objectp->getRegion()->getHost().getPort();  		U64 ipport = (((U64)ip) << 32) | (U64)port;  		U32 index = sIPAndPortToIndex[ipport]; @@ -186,7 +181,7 @@ BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object)  		}  		// Found existing entry -		if (iter->second == object.getID()) +		if (iter->second == objectp->getID())  		{   // Full UUIDs match, so remove the entry  			sIndexAndLocalIDToUUID.erase(iter);  			return TRUE; @@ -302,8 +297,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	// have to transform to absolute coordinates.  	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); +	// I don't think this case is ever hit.  TODO* Test this.  	if (!cached && !compressed && update_type != OUT_FULL)  	{ +		//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;  		gTerseObjectUpdates += num_objects;  		S32 size;  		if (mesgsys->getReceiveCompressedSize()) @@ -314,7 +311,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		{  			size = mesgsys->getReceiveSize();  		} -		// llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; +		//llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;  	}  	else  	{ @@ -345,9 +342,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	U8 compressed_dpbuffer[2048];  	LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);  	LLDataPacker *cached_dpp = NULL; -	 + +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(regionp); +#endif +  	for (i = 0; i < num_objects; i++)  	{ +		// timer is unused?  		LLTimer update_timer;  		BOOL justCreated = FALSE; @@ -359,9 +361,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);  			// Lookup data packer and add this id to cache miss lists if necessary. -			cached_dpp = regionp->getDP(id, crc); +			U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; +			cached_dpp = regionp->getDP(id, crc, cache_miss_type);  			if (cached_dpp)  			{ +				// Cache Hit.  				cached_dpp->reset();  				cached_dpp->unpackUUID(fullid, "ID");  				cached_dpp->unpackU32(local_id, "LocalID"); @@ -369,6 +373,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			}  			else  			{ +				// Cache Miss. +				#if LL_RECORD_VIEWER_STATS +				LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type); +				#endif +  				continue; // no data packer, skip this object  			}  		} @@ -380,13 +389,15 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			compressed_dp.reset();  			U32 flags = 0; -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{  				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);  			} +			// I don't think we ever use this flag from the server.  DK 2010/12/09  			if (flags & FLAGS_ZLIB_COMPRESSED)  			{ +				//llinfos << "TEST: flags & FLAGS_ZLIB_COMPRESSED" << llendl;  				compressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);  				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compbuffer, 0, i);  				uncompressed_length = 2048; @@ -402,7 +413,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			} -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{  				compressed_dp.unpackUUID(fullid, "ID");  				compressed_dp.unpackU32(local_id, "LocalID"); @@ -422,7 +433,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				}  			}  		} -		else if (update_type != OUT_FULL) +		else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only?  		{  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);  			getUUIDFromLocal(fullid, @@ -435,7 +446,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				mNumUnknownUpdates++;  			}  		} -		else +		else // OUT_FULL only?  		{  			mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); @@ -460,19 +471,19 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			//			<< ", regionp " << (U32) regionp << ", object region " << (U32) objectp->getRegion()  			//			<< llendl;  			//} -			removeFromLocalIDTable(*objectp); +			removeFromLocalIDTable(objectp);  			setUUIDAndLocal(fullid,  							local_id,  							gMessageSystem->getSenderIP(),  							gMessageSystem->getSenderPort());  			if (objectp->mLocalID != local_id) -			{    // Update local ID in object with the one sent from the region +			{	// Update local ID in object with the one sent from the region  				objectp->mLocalID = local_id;  			}  			if (objectp->getRegion() != regionp) -			{    // Object changed region, so update it +			{	// Object changed region, so update it  				objectp->updateRegion(regionp); // for LLVOAvatar  			}  		} @@ -483,18 +494,24 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			{  				if (update_type == OUT_TERSE_IMPROVED)  				{ -					// llinfos << "terse update for an unknown object:" << fullid << llendl; +					// llinfos << "terse update for an unknown object (compressed):" << fullid << llendl; +					#if LL_RECORD_VIEWER_STATS +					LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +					#endif  					continue;  				}  			} -			else if (cached) +			else if (cached) // Cache hit only?  			{  			}  			else  			{  				if (update_type != OUT_FULL)  				{ -					// llinfos << "terse update for an unknown object:" << fullid << llendl; +					//llinfos << "terse update for an unknown object:" << fullid << llendl; +					#if LL_RECORD_VIEWER_STATS +					LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +					#endif  					continue;  				} @@ -504,7 +521,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			if (mDeadObjects.find(fullid) != mDeadObjects.end())  			{  				mNumDeadObjectUpdates++; -				// llinfos << "update for a dead object:" << fullid << llendl; +				//llinfos << "update for a dead object:" << fullid << llendl; +				#if LL_RECORD_VIEWER_STATS +				LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +				#endif  				continue;  			}  #endif @@ -512,6 +532,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());  			if (!objectp)  			{ +				llinfos << "createObject failure for object: " << fullid << llendl; +				#if LL_RECORD_VIEWER_STATS +				LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +				#endif  				continue;  			}  			justCreated = TRUE; @@ -524,19 +548,26 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;  		} +		bool bCached = false;  		if (compressed)  		{ -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{  				objectp->mLocalID = local_id;  			}  			processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{ +				bCached = true; +				#if LL_RECORD_VIEWER_STATS +				LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); +				LLViewerStatsRecorder::instance()->recordCacheFullUpdate(local_id, update_type, result, objectp); +				#else  				objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); +				#endif  			}  		} -		else if (cached) +		else if (cached) // Cache hit only?  		{  			objectp->mLocalID = local_id;  			processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated); @@ -549,8 +580,17 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			}  			processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);  		} +		#if LL_RECORD_VIEWER_STATS +		LLViewerStatsRecorder::instance()->recordObjectUpdateEvent(local_id, update_type, objectp); +		#endif +		objectp->setLastUpdateType(update_type); +		objectp->setLastUpdateCached(bCached);  	} +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); +#endif +  	LLVOAvatar::cullAvatarsByPixelArea();  } @@ -681,12 +721,12 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	// update global timer  	F32 last_time = gFrameTimeSeconds; -	U64 time = totalTime();                 // this will become the new gFrameTime when the update is done +	U64 time = totalTime();				 // this will become the new gFrameTime when the update is done  	// Time _can_ go backwards, for example if the user changes the system clock.  	// It doesn't cause any fatal problems (just some oddness with stats), so we shouldn't assert here.  //	llassert(time > gFrameTime);  	F64 time_diff = U64_to_F64(time - gFrameTime)/(F64)SEC_TO_MICROSEC; -	gFrameTime    = time; +	gFrameTime	= time;  	F64 time_since_start = U64_to_F64(gFrameTime - gStartTime)/(F64)SEC_TO_MICROSEC;  	gFrameTimeSeconds = (F32)time_since_start; @@ -788,7 +828,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  		{  			std::string id_str;  			objectp->mID.toString(id_str); -			std::string tmpstr = std::string("Par:    ") + id_str; +			std::string tmpstr = std::string("Par:	") + id_str;  			addDebugBeacon(objectp->getPositionAgent(),  							tmpstr,  							LLColor4(1.f,0.f,0.f,1.f), @@ -808,12 +848,12 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  			std::string tmpstr;  			if (objectp->getParent())  			{ -				tmpstr = std::string("ChP:    ") + id_str; +				tmpstr = std::string("ChP:	") + id_str;  				text_color = LLColor4(0.f, 1.f, 0.f, 1.f);  			}  			else  			{ -				tmpstr = std::string("ChNoP:    ") + id_str; +				tmpstr = std::string("ChNoP:	") + id_str;  				text_color = LLColor4(1.f, 0.f, 0.f, 1.f);  			}  			id = sIndexAndLocalIDToUUID[oi.mParentInfo]; @@ -864,7 +904,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)  	//				<< objectp->getRegion()->getHost().getPort() << llendl;  	//}	 -	removeFromLocalIDTable(*objectp); +	removeFromLocalIDTable(objectp);  	if (objectp->onActiveList())  	{ @@ -1519,8 +1559,8 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)  			llinfos << "Agent: " << objectp->getPositionAgent() << llendl;  			addDebugBeacon(objectp->getPositionAgent(),"");  #endif -            gPipeline.markMoved(objectp->mDrawable);                 -            objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE); +			gPipeline.markMoved(objectp->mDrawable);				 +			objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE);  			// Flag the object as no longer orphaned  			childp->mOrphaned = FALSE; diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 605bac8e89..fda3d6899d 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -160,7 +160,7 @@ public:  								const U32 ip,  								const U32 port); // Requires knowledge of message system info! -	static BOOL removeFromLocalIDTable(const LLViewerObject &object); +	static BOOL removeFromLocalIDTable(const LLViewerObject* objectp);  	// Used ONLY by the orphaned object code.  	static U64 getIndex(const U32 local_id, const U32 ip, const U32 port); diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index eee653b0c1..d07e06f6a7 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -145,6 +145,35 @@ BOOL LLViewerParcelOverlay::isOwnedOther(const LLVector3& pos) const  	return (PARCEL_OWNED == overlay || PARCEL_FOR_SALE == overlay);  } +bool LLViewerParcelOverlay::encroachesOwned(const std::vector<LLBBox>& boxes) const +{ +	// boxes are expected to already be axis aligned +	for (U32 i = 0; i < boxes.size(); ++i) +	{ +		LLVector3 min = boxes[i].getMinAgent(); +		LLVector3 max = boxes[i].getMaxAgent(); +		 +		S32 left   = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); +		S32 right  = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); +		S32 top    = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); +		S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); +	 +		for (S32 row = top; row <= bottom; row++) +		{ +			for (S32 column = left; column <= right; column++) +			{ +				U8 type = ownership(row, column); +				if ((PARCEL_SELF == type) +					|| (PARCEL_GROUP == type)) +				{ +					return true; +				} +			} +		} +	} +	return false; +} +  BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const  {  	S32 row =    S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 61be220312..c80baedda6 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -30,6 +30,7 @@  // The ownership data for land parcels.  // One of these structures per region. +#include "llbbox.h"  #include "lldarray.h"  #include "llframetimer.h"  #include "lluuid.h" @@ -54,6 +55,12 @@ public:  	BOOL			isOwnedSelf(const LLVector3& pos) const;  	BOOL			isOwnedGroup(const LLVector3& pos) const;  	BOOL			isOwnedOther(const LLVector3& pos) const; + +	// "encroaches" means the prim hangs over the parcel, but its center +	// might be in another parcel. for now, we simply test axis aligned  +	// bounding boxes which isn't perfect, but is close +	bool encroachesOwned(const std::vector<LLBBox>& boxes) const; +	  	BOOL			isSoundLocal(const LLVector3& pos) const;  	BOOL			isBuildCameraAllowed(const LLVector3& pos) const; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 551ba18dd5..23b7b921b8 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -59,6 +59,7 @@  #include "llurldispatcher.h"  #include "llviewerobjectlist.h"  #include "llviewerparceloverlay.h" +#include "llviewerstatsrecorder.h"  #include "llvlmanager.h"  #include "llvlcomposition.h"  #include "llvocache.h" @@ -321,6 +322,12 @@ LLViewerRegion::~LLViewerRegion()  	std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());  } +/*virtual*/  +const LLHost&	LLViewerRegion::getHost() const				 +{  +	return mHost;  +} +  void LLViewerRegion::loadObjectCache()  {  	if (mCacheLoaded) @@ -1032,7 +1039,7 @@ void LLViewerRegion::getInfo(LLSD& info)  	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;  } -void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)  {  	U32 local_id = objectp->getLocalID();  	U32 crc = objectp->getCRC(); @@ -1046,35 +1053,36 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary  		{  			// Record a hit  			entry->recordDupe(); +			return CACHE_UPDATE_DUPE;  		} -		else -		{ -			// Update the cache entry -			mCacheMap.erase(local_id); -			delete entry; -			entry = new LLVOCacheEntry(local_id, crc, dp); -			mCacheMap[local_id] = entry; -		} -	} -	else -	{ -		// we haven't seen this object before -		// Create new entry and add to map -		if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) -		{ -			mCacheMap.erase(mCacheMap.begin()); -		} +		// Update the cache entry +		mCacheMap.erase(local_id); +		delete entry;  		entry = new LLVOCacheEntry(local_id, crc, dp); -  		mCacheMap[local_id] = entry; +		return CACHE_UPDATE_CHANGED;  	} -	return ; + +	// we haven't seen this object before + +	// Create new entry and add to map +	eCacheUpdateResult result = CACHE_UPDATE_ADDED; +	if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) +	{ +		mCacheMap.erase(mCacheMap.begin()); +		result = CACHE_UPDATE_REPLACED; +		 +	} +	entry = new LLVOCacheEntry(local_id, crc, dp); + +	mCacheMap[local_id] = entry; +	return result;  }  // Get data packer for this object, if we have cached data  // AND the CRC matches. JC -LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc) +LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)  {  	llassert(mCacheLoaded); @@ -1087,17 +1095,20 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc)  		{  			// Record a hit  			entry->recordHit(); +			cache_miss_type = CACHE_MISS_TYPE_NONE;  			return entry->getDP(crc);  		}  		else  		{  			// llinfos << "CRC miss for " << local_id << llendl; +			cache_miss_type = CACHE_MISS_TYPE_CRC;  			mCacheMissCRC.put(local_id);  		}  	}  	else  	{  		// llinfos << "Cache miss for " << local_id << llendl; +		cache_miss_type = CACHE_MISS_TYPE_FULL;  		mCacheMissFull.put(local_id);  	}  	return NULL; @@ -1119,9 +1130,6 @@ void LLViewerRegion::requestCacheMisses()  	S32 blocks = 0;  	S32 i; -	const U8 CACHE_MISS_TYPE_FULL = 0; -	const U8 CACHE_MISS_TYPE_CRC  = 1; -  	// Send full cache miss updates.  For these, we KNOW we don't  	// have a viewer object.  	for (i = 0; i < full_count; i++) @@ -1184,6 +1192,11 @@ void LLViewerRegion::requestCacheMisses()  	mCacheDirty = TRUE ;  	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; +	#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this); +	LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count); +	LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); +	#endif  }  void LLViewerRegion::dumpCache() @@ -1372,11 +1385,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("DispatchRegionInfo");  	capabilityNames.append("EstateChangeInfo");  	capabilityNames.append("EventQueueGet"); -	capabilityNames.append("FetchInventory");  	capabilityNames.append("ObjectMedia");  	capabilityNames.append("ObjectMediaNavigate"); -	capabilityNames.append("FetchLib"); -	capabilityNames.append("FetchLibDescendents"); +	capabilityNames.append("FetchLib2"); +	capabilityNames.append("FetchLibDescendents2"); +	capabilityNames.append("FetchInventory2"); +	capabilityNames.append("FetchInventoryDescendents2");  	capabilityNames.append("GetDisplayNames");  	capabilityNames.append("GetTexture");  	capabilityNames.append("GroupProposalBallot"); @@ -1400,7 +1414,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("SendUserReportWithScreenshot");  	capabilityNames.append("ServerReleaseNotes");  	capabilityNames.append("SetDisplayName"); -	capabilityNames.append("SimConsole");  	capabilityNames.append("SimConsoleAsync");  	capabilityNames.append("StartGroupProposal");  	capabilityNames.append("TextureStats"); @@ -1417,7 +1430,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); -	capabilityNames.append("WebFetchInventoryDescendents");  	// Please add new capabilities alphabetically to reduce  	// merge conflicts. @@ -1497,6 +1509,20 @@ LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)  	return NULL;  } +// the viewer can not yet distinquish between normal- and estate-owned objects +// so we collapse these two bits and enable the UI if either are set +const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT +											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT; + +bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const +{ +	return (mParcelOverlay != NULL) +		&& (mParcelOverlay->isOwnedSelf(pos) +			|| mParcelOverlay->isOwnedGroup(pos) +			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT) +				&& mParcelOverlay->encroachesOwned(boxes)) ); +} +  void LLViewerRegion::showReleaseNotes()  {  	std::string url = this->getCapability("ServerReleaseNotes"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 8b71998f60..dd40b876cd 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -33,6 +33,7 @@  #include "lldarray.h"  #include "llwind.h" +#include "llbbox.h"  #include "llcloud.h"  #include "llstat.h"  #include "v3dmath.h" @@ -50,7 +51,7 @@  // Surface id's  #define LAND  1  #define WATER 2 -const U32	MAX_OBJECT_CACHE_ENTRIES = 10000; +const U32	MAX_OBJECT_CACHE_ENTRIES = 50000;  class LLEventPoll; @@ -244,7 +245,7 @@ public:      LLEventPump& getCapAPI() { return mCapabilityListener.getCapAPI(); }      /// implements LLCapabilityProvider -	virtual LLHost	getHost() const				{ return mHost; } +	/*virtual*/ const LLHost& getHost() const;  	const U64 		&getHandle() const 			{ return mHandle; }  	LLSurface		&getLand() const			{ return *mLandp; } @@ -274,9 +275,24 @@ public:  	void getInfo(LLSD& info); +	typedef enum +	{ +		CACHE_MISS_TYPE_FULL = 0, +		CACHE_MISS_TYPE_CRC, +		CACHE_MISS_TYPE_NONE +	} eCacheMissType; + +	typedef enum +	{ +		CACHE_UPDATE_DUPE = 0, +		CACHE_UPDATE_CHANGED, +		CACHE_UPDATE_ADDED, +		CACHE_UPDATE_REPLACED +	} eCacheUpdateResult; +  	// handle a full update message -	void cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); -	LLDataPacker *getDP(U32 local_id, U32 crc); +	eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); +	LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type);  	void requestCacheMisses();  	void addCacheMissFull(const U32 local_id); @@ -293,6 +309,8 @@ public:  	std::string getHttpUrl() const { return mHttpUrl ;}  	LLSpatialPartition* getSpatialPartition(U32 type); + +	bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;  public:  	struct CompareDistance  	{ diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp new file mode 100644 index 0000000000..e9d21b4848 --- /dev/null +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -0,0 +1,258 @@ +/** + * @file llviewerstatsrecorder.cpp + * @brief record info about viewer events to a metrics log file + * + * $LicenseInfo:firstyear=2010&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 "llviewerstatsrecorder.h" + +#if LL_RECORD_VIEWER_STATS + +#include "llfile.h" +#include "llviewerregion.h" +#include "llviewerobject.h" + + +// To do - something using region name or global position +#if LL_WINDOWS +	static const std::string STATS_FILE_NAME("C:\\ViewerObjectCacheStats.csv"); +#else +	static const std::string STATS_FILE_NAME("/tmp/viewerstats.csv"); +#endif + +LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL; +LLViewerStatsRecorder::LLViewerStatsRecorder() : +	mObjectCacheFile(NULL), +	mTimer(), +	mRegionp(NULL), +	mStartTime(0.f), +	mProcessingTime(0.f) +{ +	if (NULL != sInstance) +	{ +		llerrs << "Attempted to create multiple instances of LLViewerStatsRecorder!" << llendl; +	} +	sInstance = this; +	clearStats(); +} + +LLViewerStatsRecorder::~LLViewerStatsRecorder() +{ +	if (mObjectCacheFile != NULL) +	{ +		LLFile::close(mObjectCacheFile); +		mObjectCacheFile = NULL; +	} +} + +// static +void LLViewerStatsRecorder::initClass() +{ +	sInstance = new LLViewerStatsRecorder(); +} + +// static +void LLViewerStatsRecorder::cleanupClass() +{ +	delete sInstance; +	sInstance = NULL; +} + + +void LLViewerStatsRecorder::initStatsRecorder(LLViewerRegion *regionp) +{ +	if (mObjectCacheFile == NULL) +	{ +		mStartTime = LLTimer::getTotalTime(); +		mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); +		if (mObjectCacheFile) +		{	// Write column headers +			std::ostringstream data_msg; +			data_msg << "EventTime, " +				<< "ProcessingTime, " +				<< "CacheHits, " +				<< "CacheFullMisses, " +				<< "CacheCrcMisses, " +				<< "FullUpdates, " +				<< "TerseUpdates, " +				<< "CacheMissRequests, " +				<< "CacheMissResponses, " +				<< "CacheUpdateDupes, " +				<< "CacheUpdateChanges, " +				<< "CacheUpdateAdds, " +				<< "CacheUpdateReplacements, " +				<< "UpdateFailures" +				<< "\n"; + +			fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); +		} +	} +} + +void LLViewerStatsRecorder::beginObjectUpdateEvents(LLViewerRegion *regionp) +{ +	initStatsRecorder(regionp); +	mRegionp = regionp; +	mProcessingTime = LLTimer::getTotalTime(); +	clearStats(); +} + +void LLViewerStatsRecorder::clearStats() +{ +	mObjectCacheHitCount = 0; +	mObjectCacheMissFullCount = 0; +	mObjectCacheMissCrcCount = 0; +	mObjectFullUpdates = 0; +	mObjectTerseUpdates = 0; +	mObjectCacheMissRequests = 0; +	mObjectCacheMissResponses = 0; +	mObjectCacheUpdateDupes = 0; +	mObjectCacheUpdateChanges = 0; +	mObjectCacheUpdateAdds = 0; +	mObjectCacheUpdateReplacements = 0; +	mObjectUpdateFailures = 0; +} + + +void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type) +{ +	mObjectUpdateFailures++; +} + +void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type) +{ +	if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type) +	{ +		mObjectCacheMissFullCount++; +	} +	else +	{ +		mObjectCacheMissCrcCount++; +	} +} + +void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp) +{ +	switch (update_type) +	{ +	case OUT_FULL: +		mObjectFullUpdates++; +		break; +	case OUT_TERSE_IMPROVED: +		mObjectTerseUpdates++; +		break; +	case OUT_FULL_COMPRESSED: +		mObjectCacheMissResponses++; +		break; +	case OUT_FULL_CACHED: +		mObjectCacheHitCount++; +		break; +	default: +		llwarns << "Unknown update_type" << llendl; +		break; +	}; +} + +void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp) +{ +	switch (update_result) +	{ +		case LLViewerRegion::CACHE_UPDATE_DUPE: +			mObjectCacheUpdateDupes++; +			break; +		case LLViewerRegion::CACHE_UPDATE_CHANGED: +			mObjectCacheUpdateChanges++; +			break; +		case LLViewerRegion::CACHE_UPDATE_ADDED: +			mObjectCacheUpdateAdds++; +			break; +		case LLViewerRegion::CACHE_UPDATE_REPLACED: +			mObjectCacheUpdateReplacements++; +			break; +		default: +			llwarns << "Unknown update_result type" << llendl; +			break; +	}; +} + +void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count) +{ +	mObjectCacheMissRequests += count; +} + +void LLViewerStatsRecorder::endObjectUpdateEvents() +{ +	llinfos << "ILX: "  +		<< mObjectCacheHitCount << " hits, "  +		<< mObjectCacheMissFullCount << " full misses, " +		<< mObjectCacheMissCrcCount << " crc misses, " +		<< mObjectFullUpdates << " full updates, " +		<< mObjectTerseUpdates << " terse updates, " +		<< mObjectCacheMissRequests << " cache miss requests, " +		<< mObjectCacheMissResponses << " cache miss responses, " +		<< mObjectCacheUpdateDupes << " cache update dupes, " +		<< mObjectCacheUpdateChanges << " cache update changes, " +		<< mObjectCacheUpdateAdds << " cache update adds, " +		<< mObjectCacheUpdateReplacements << " cache update replacements, " +		<< mObjectUpdateFailures << " update failures" +		<< llendl; + +	S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; +	if (mObjectCacheFile != NULL && +		total_objects > 0) +	{ +		std::ostringstream data_msg; +		F32 processing32 = (F32) ((LLTimer::getTotalTime() - mProcessingTime) / 1000.0); + +		data_msg << getTimeSinceStart() +			<< ", " << processing32 +			<< ", " << mObjectCacheHitCount +			<< ", " << mObjectCacheMissFullCount +			<< ", " << mObjectCacheMissCrcCount +			<< ", " << mObjectFullUpdates +			<< ", " << mObjectTerseUpdates +			<< ", " << mObjectCacheMissRequests +			<< ", " << mObjectCacheMissResponses +			<< ", " << mObjectCacheUpdateDupes +			<< ", " << mObjectCacheUpdateChanges +			<< ", " << mObjectCacheUpdateAdds +			<< ", " << mObjectCacheUpdateReplacements +			<< ", " << mObjectUpdateFailures +			<< "\n"; + +		fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); +	} + +	clearStats(); +} + +F32 LLViewerStatsRecorder::getTimeSinceStart() +{ +	return (F32) ((LLTimer::getTotalTime() - mStartTime) / 1000.0); +} + +#endif + + + diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h new file mode 100644 index 0000000000..612ac380f7 --- /dev/null +++ b/indra/newview/llviewerstatsrecorder.h @@ -0,0 +1,97 @@ +/** + * @file llviewerstatsrecorder.h + * @brief record info about viewer events to a metrics log file + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LLVIEWERSTATSRECORDER_H +#define LLVIEWERSTATSRECORDER_H + + +// This is a diagnostic class used to record information from the viewer +// for analysis. + +// This is normally 0.  Set to 1 to enable viewer stats recording +#define LL_RECORD_VIEWER_STATS	0 + + +#if LL_RECORD_VIEWER_STATS +#include "llframetimer.h" +#include "llviewerobject.h" +#include "llviewerregion.h" + +class LLMutex; +class LLViewerRegion; +class LLViewerObject; + +class LLViewerStatsRecorder +{ + public: +	LLViewerStatsRecorder(); +	~LLViewerStatsRecorder(); + +	static void initClass(); +	static void cleanupClass(); +	static LLViewerStatsRecorder* instance() {return sInstance; } + +	void initStatsRecorder(LLViewerRegion *regionp); + +	void beginObjectUpdateEvents(LLViewerRegion *regionp); +	void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type); +	void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type); +	void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp); +	void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp); +	void recordRequestCacheMissesEvent(S32 count); +	void endObjectUpdateEvents(); + +	F32 getTimeSinceStart(); + +private: +	static LLViewerStatsRecorder* sInstance; + +	LLFILE *	mObjectCacheFile;		// File to write data into +	LLFrameTimer	mTimer; +	LLViewerRegion*	mRegionp; +	F64			mStartTime; +	F64			mProcessingTime; + +	S32			mObjectCacheHitCount; +	S32			mObjectCacheMissFullCount; +	S32			mObjectCacheMissCrcCount; +	S32			mObjectFullUpdates; +	S32			mObjectTerseUpdates; +	S32			mObjectCacheMissRequests; +	S32			mObjectCacheMissResponses; +	S32			mObjectCacheUpdateDupes; +	S32			mObjectCacheUpdateChanges; +	S32			mObjectCacheUpdateAdds; +	S32			mObjectCacheUpdateReplacements; +	S32			mObjectUpdateFailures; + + +	void	clearStats(); +}; +#endif	// LL_RECORD_VIEWER_STATS + +#endif // LLVIEWERSTATSRECORDER_H + diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0c05a301e6..cd16b15e3e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1214,12 +1214,15 @@ void LLViewerFetchedTexture::cleanup()  void LLViewerFetchedTexture::setForSculpt()  { +	static const S32 MAX_INTERVAL = 8 ; //frames +  	mForSculpt = TRUE ;  	if(isForSculptOnly() && !getBoundRecently())  	{  		destroyGLTexture() ; //sculpt image does not need gl texture.  	}  	checkCachedRawSculptImage() ; +	setMaxVirtualSizeResetInterval(MAX_INTERVAL) ;  }  BOOL LLViewerFetchedTexture::isForSculptOnly() const diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c812fcf2da..ca0478ee0c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -296,13 +296,15 @@ private:  	line_list_t mLineList;  	LLColor4 mTextColor; -public: -	LLDebugText(LLViewerWindow* window) : mWindow(window) {} -	  	void addText(S32 x, S32 y, const std::string &text)   	{  		mLineList.push_back(Line(text, x, y));  	} +	 +	void clearText() { mLineList.clear(); } +	 +public: +	LLDebugText(LLViewerWindow* window) : mWindow(window) {}  	void update()  	{ @@ -323,6 +325,8 @@ public:  		U32 ypos = 64;  		const U32 y_inc = 20; +		clearText(); +		  		if (gSavedSettings.getBOOL("DebugShowTime"))  		{  			const U32 y_inc2 = 15; @@ -347,6 +351,14 @@ public:  			addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;  		} +#if LL_WINDOWS +		if (gSavedSettings.getBOOL("DebugShowMemory")) +		{ +			addText(xpos, ypos, llformat("Memory: %d (KB)", LLMemory::getWorkingSetSize() / 1024));  +			ypos += y_inc; +		} +#endif +  		if (gDisplayCameraPos)  		{  			std::string camera_view_text; @@ -601,6 +613,50 @@ public:  				ypos += y_inc;  			}  		} +		 +		if (gSavedSettings.getBOOL("DebugShowTextureInfo")) +		{ +			LLViewerObject* objectp = NULL ; +			//objectp = = gAgentCamera.getFocusObject(); +			 +			LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode(); +			if (nodep) +			{ +				objectp = nodep->getObject();			 +			} +			if (objectp && !objectp->isDead()) +			{ +				S32 num_faces = objectp->mDrawable->getNumFaces() ; +				 +				for(S32 i = 0 ; i < num_faces; i++) +				{ +					LLFace* facep = objectp->mDrawable->getFace(i) ; +					if(facep) +					{ +						//addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0], +						//		facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1])); +						//ypos += y_inc; +						 +						addText(xpos, ypos, llformat("v_size: %.3f:  p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea())); +						ypos += y_inc; +						 +						//const LLTextureEntry *tep = facep->getTextureEntry(); +						//if(tep) +						//{ +						//	addText(xpos, ypos, llformat("scale_s: %.3f:  scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ; +						//	ypos += y_inc; +						//} +						 +						LLViewerTexture* tex = facep->getTexture() ; +						if(tex) +						{ +							addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize())); +							ypos += y_inc; +						} +					} +				} +			} +		}  	}  	void draw() diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index bb4c5b1804..fd89044995 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2106,31 +2106,6 @@ void LLVOAvatar::computeBodySize()  			gAgent.sendAgentSetAppearance();  		}  	} - -/* debug spam -	std::cout << "skull = " << skull << std::endl;				// adebug -	std::cout << "head = " << head << std::endl;				// adebug -	std::cout << "head_scale = " << head_scale << std::endl;	// adebug -	std::cout << "neck = " << neck << std::endl;				// adebug -	std::cout << "neck_scale = " << neck_scale << std::endl;	// adebug -	std::cout << "chest = " << chest << std::endl;				// adebug -	std::cout << "chest_scale = " << chest_scale << std::endl;	// adebug -	std::cout << "torso = " << torso << std::endl;				// adebug -	std::cout << "torso_scale = " << torso_scale << std::endl;	// adebug -	std::cout << std::endl;	// adebug - -	std::cout << "pelvis_scale = " << pelvis_scale << std::endl;// adebug -	std::cout << std::endl;	// adebug - -	std::cout << "hip = " << hip << std::endl;					// adebug -	std::cout << "hip_scale = " << hip_scale << std::endl;		// adebug -	std::cout << "ankle = " << ankle << std::endl;				// adebug -	std::cout << "ankle_scale = " << ankle_scale << std::endl;	// adebug -	std::cout << "foot = " << foot << std::endl;				// adebug -	std::cout << "mBodySize = " << mBodySize << std::endl;		// adebug -	std::cout << "mPelvisToFoot = " << mPelvisToFoot << std::endl;	// adebug -	std::cout << std::endl;		// adebug -*/  }  //------------------------------------------------------------------------ diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 145ee31260..b3312db4a0 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -40,6 +40,7 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)  	return apr_file->write(src, n_bytes) == n_bytes ;  } +  //---------------------------------------------------------------------------  // LLVOCacheEntry  //--------------------------------------------------------------------------- @@ -212,8 +213,8 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  		if(success)  		{  			success = check_write(apr_file, (void*)mBuffer, size); +		}  	} -}  	return success ;  } @@ -224,7 +225,9 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  // Format string used to construct filename for the object cache  static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; -const U32 NUM_ENTRIES_TO_PURGE = 16 ; +const U32 MAX_NUM_OBJECT_ENTRIES = 128 ; +const U32 MIN_ENTRIES_TO_PURGE = 16 ; +const U32 INVALID_TIME = 0 ;  const char* object_cache_dirname = "objectcache";  const char* header_filename = "object.cache"; @@ -286,22 +289,27 @@ void LLVOCache::setDirNames(ELLPath location)  void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)  { -	if(mInitialized || !mEnabled) +	if(!mEnabled)  	{ +		llwarns << "Not initializing cache: Cache is currently disabled." << llendl;  		return ;  	} +	if(mInitialized) +	{ +		llwarns << "Cache already initialized." << llendl; +		return ; +	} +	mInitialized = TRUE ; +  	setDirNames(location);  	if (!mReadOnly)  	{  		LLFile::mkdir(mObjectCacheDirName);  	} - -	mCacheSize = size; - +	mCacheSize = llclamp(size, MIN_ENTRIES_TO_PURGE, MAX_NUM_OBJECT_ENTRIES);  	mMetaInfo.mVersion = cache_version; -	readCacheHeader(); -	mInitialized = TRUE ; +	readCacheHeader();	  	if(mMetaInfo.mVersion != cache_version)   	{ @@ -321,12 +329,16 @@ void LLVOCache::removeCache(ELLPath location)  {  	if(mReadOnly)  	{ +		llwarns << "Not removing cache at " << location << ": Cache is currently in read-only mode." << llendl;  		return ;  	} +	llinfos << "about to remove the object cache due to settings." << llendl ; +  	std::string delem = gDirUtilp->getDirDelimiter();  	std::string mask = delem + "*";  	std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname); +	llinfos << "Removing cache at " << cache_dir << llendl;  	gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files  	LLFile::rmdir(cache_dir); @@ -339,17 +351,56 @@ void LLVOCache::removeCache()  	llassert_always(mInitialized) ;  	if(mReadOnly)  	{ +		llwarns << "Not clearing object cache: Cache is currently in read-only mode." << llendl;  		return ;  	} +	llinfos << "about to remove the object cache due to some error." << llendl ; +  	std::string delem = gDirUtilp->getDirDelimiter();  	std::string mask = delem + "*"; +	llinfos << "Removing cache at " << mObjectCacheDirName << llendl;  	gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);   	clearCacheInMemory() ;  	writeCacheHeader();  } +void LLVOCache::removeEntry(HeaderEntryInfo* entry)  +{ +	llassert_always(mInitialized) ; +	if(mReadOnly) +	{ +		return ; +	} +	if(!entry) +	{ +		return ; +	} + +	header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry) ; +	if(iter != mHeaderEntryQueue.end()) +	{		 +		mHandleEntryMap.erase(entry->mHandle) ;		 +		mHeaderEntryQueue.erase(iter) ; +		removeFromCache(entry) ; +		delete entry ; + +		mNumEntries = mHandleEntryMap.size() ; +	} +} + +void LLVOCache::removeEntry(U64 handle)  +{ +	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; +	if(iter == mHandleEntryMap.end()) //no cache +	{ +		return ; +	} +	HeaderEntryInfo* entry = iter->second ; +	removeEntry(entry) ; +} +  void LLVOCache::clearCacheInMemory()  {  	if(!mHeaderEntryQueue.empty())  @@ -362,6 +413,7 @@ void LLVOCache::clearCacheInMemory()  		mHandleEntryMap.clear();  		mNumEntries = 0 ;  	} +  }  void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)  @@ -375,146 +427,169 @@ void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)  	return ;  } -void LLVOCache::removeFromCache(U64 handle) +void LLVOCache::removeFromCache(HeaderEntryInfo* entry)  {  	if(mReadOnly)  	{ +		llwarns << "Not removing cache for handle " << entry->mHandle << ": Cache is currently in read-only mode." << llendl;  		return ;  	}  	std::string filename; -	getObjectCacheFilename(handle, filename); -	LLAPRFile::remove(filename, mLocalAPRFilePoolp);	 -} - -BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes)  -{ -	if(!check_read(apr_file, src, n_bytes)) -	{ -		delete apr_file ; -		removeCache() ; -		return FALSE ; -	} - -	return TRUE ; -} - -BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes)  -{ -	if(!check_write(apr_file, src, n_bytes)) -	{ -		delete apr_file ; -		removeCache() ; -		return FALSE ; -	} - -	return TRUE ; +	getObjectCacheFilename(entry->mHandle, filename); +	LLAPRFile::remove(filename, mLocalAPRFilePoolp); +	entry->mTime = INVALID_TIME ; +	updateEntry(entry) ; //update the head file.  }  void LLVOCache::readCacheHeader()  {  	if(!mEnabled)  	{ -		return ; +		llwarns << "Not reading cache header: Cache is currently disabled." << llendl; +		return;  	}  	//clear stale info.  	clearCacheInMemory();	 +	bool success = true ;  	if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))  	{ -		LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);		 +		LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);		  		//read the meta element -		if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo))) -		{ -			return ; -		} - -		HeaderEntryInfo* entry ; -		mNumEntries = 0 ; -		while(mNumEntries < mCacheSize) +		success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; +		 +		if(success)  		{ -			entry = new HeaderEntryInfo() ; -			if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo))) +			HeaderEntryInfo* entry = NULL ; +			mNumEntries = 0 ; +			U32 num_read = 0 ; +			while(num_read++ < MAX_NUM_OBJECT_ENTRIES)  			{ -				delete entry ;			 -				return ; +				if(!entry) +				{ +					entry = new HeaderEntryInfo() ; +				} +				success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo)); +								 +				if(!success) //failed +				{ +					llwarns << "Error reading cache header entry. (entry_index=" << mNumEntries << ")" << llendl; +					delete entry ; +					entry = NULL ; +					break ; +				} +				else if(entry->mTime == INVALID_TIME) +				{ +					continue ; //an empty entry +				} + +				entry->mIndex = mNumEntries++ ; +				mHeaderEntryQueue.insert(entry) ; +				mHandleEntryMap[entry->mHandle] = entry ; +				entry = NULL ;  			} -			else if(!entry->mTime) //end of the cache. +			if(entry)  			{  				delete entry ; -				return ;  			} - -			entry->mIndex = mNumEntries++ ; -			mHeaderEntryQueue.insert(entry) ; -			mHandleEntryMap[entry->mHandle] = entry ;  		} -		delete apr_file ; +		//--------- +		//debug code +		//---------- +		//std::string name ; +		//for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter) +		//{ +		//	getObjectCacheFilename((*iter)->mHandle, name) ; +		//	llinfos << name << llendl ; +		//} +		//-----------  	}  	else  	{  		writeCacheHeader() ;  	} + +	if(!success) +	{ +		removeCache() ; //failed to read header, clear the cache +	} +	else if(mNumEntries >= mCacheSize) +	{ +		purgeEntries(mCacheSize) ; +	} + +	return ;  }  void LLVOCache::writeCacheHeader()  { -	if(mReadOnly || !mEnabled) +	if (!mEnabled)  	{ -		return ; -	}	 - -	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +		llwarns << "Not writing cache header: Cache is currently disabled." << llendl; +		return; +	} -	//write the meta element -	if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo))) +	if(mReadOnly)  	{ -		return ; +		llwarns << "Not writing cache header: Cache is currently in read-only mode." << llendl; +		return;  	} -	mNumEntries = 0 ; -	for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; iter != mHeaderEntryQueue.end(); ++iter) +	bool success = true ;  	{ -		(*iter)->mIndex = mNumEntries++ ; -		if(!checkWrite(apr_file, (void*)*iter, sizeof(HeaderEntryInfo))) +		LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); + +		//write the meta element +		success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; + + +		mNumEntries = 0 ;	 +		for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)  		{ -			return ; +			(*iter)->mIndex = mNumEntries++ ; +			success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));  		} -	} - -	mNumEntries = mHeaderEntryQueue.size() ; -	if(mNumEntries < mCacheSize) -	{ -		HeaderEntryInfo* entry = new HeaderEntryInfo() ; -		for(U32 i = mNumEntries ; i < mCacheSize; i++) +	 +		mNumEntries = mHeaderEntryQueue.size() ; +		if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES)  		{ -			//fill the cache with the default entry. -			if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo))) +			HeaderEntryInfo* entry = new HeaderEntryInfo() ; +			entry->mTime = INVALID_TIME ; +			for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)  			{ -				mReadOnly = TRUE ; //disable the cache. -				return ; +				//fill the cache with the default entry. +				success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;			 +  			} +			delete entry ;  		} -		delete entry ;  	} -	delete apr_file ; + +	if(!success) +	{ +		clearCacheInMemory() ; +		mReadOnly = TRUE ; //disable the cache. +	} +	return ;  }  BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)  { -	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); -	apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; +	LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +	apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; -	return checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; +	return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;  }  void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)   {  	if(!mEnabled)  	{ +		llwarns << "Not reading cache for handle " << handle << "): Cache is currently disabled." << llendl;  		return ;  	}  	llassert_always(mInitialized); @@ -522,65 +597,69 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;  	if(iter == mHandleEntryMap.end()) //no cache  	{ +		llwarns << "No handle map entry for " << handle << llendl;  		return ;  	} -	std::string filename; -	getObjectCacheFilename(handle, filename); -	LLAPRFile* apr_file = new LLAPRFile(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); - -	LLUUID cache_id ; -	if(!checkRead(apr_file, cache_id.mData, UUID_BYTES)) +	bool success = true ;  	{ -		return ; -	} -	if(cache_id != id) -	{ -		llinfos << "Cache ID doesn't match for this region, discarding"<< llendl; - -		delete apr_file ; -		return ; -	} +		std::string filename; +		getObjectCacheFilename(handle, filename); +		LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); +	 +		LLUUID cache_id ; +		success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ; +	 +		if(success) +		{		 +			if(cache_id != id) +			{ +				llinfos << "Cache ID doesn't match for this region, discarding"<< llendl; +				success = false ; +			} -	S32 num_entries; -	if(!checkRead(apr_file, &num_entries, sizeof(S32))) -	{ -		return ; +			if(success) +			{ +				S32 num_entries; +				success = check_read(&apr_file, &num_entries, sizeof(S32)) ; +	 +				for (S32 i = 0; success && i < num_entries; i++) +				{ +					LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file); +					if (!entry->getLocalID()) +					{ +						llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; +						delete entry ; +						success = false ; +					} +					cache_entry_map[entry->getLocalID()] = entry; +				} +			} +		}		  	} -	for (S32 i = 0; i < num_entries; i++) +	if(!success)  	{ -		LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file); -		if (!entry->getLocalID()) +		if(cache_entry_map.empty())  		{ -			llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; -			delete entry ; -			break; +			removeEntry(iter->second) ;  		} -		cache_entry_map[entry->getLocalID()] = entry;  	} -	num_entries = cache_entry_map.size() ; -	delete apr_file ;  	return ;  } -void LLVOCache::purgeEntries() +void LLVOCache::purgeEntries(U32 size)  { -	U32 limit = mCacheSize - NUM_ENTRIES_TO_PURGE ; -	while(mHeaderEntryQueue.size() > limit) +	while(mHeaderEntryQueue.size() >= size)  	{  		header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; -		HeaderEntryInfo* entry = *iter ; -		 -		removeFromCache(entry->mHandle) ; -		mHandleEntryMap.erase(entry->mHandle) ;		 +		HeaderEntryInfo* entry = *iter ;			 +		mHandleEntryMap.erase(entry->mHandle);  		mHeaderEntryQueue.erase(iter) ; -		delete entry ; +		removeFromCache(entry) ; +		delete entry;  	} - -	writeCacheHeader() ; -	readCacheHeader() ;  	mNumEntries = mHandleEntryMap.size() ;  } @@ -588,80 +667,86 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:  {  	if(!mEnabled)  	{ +		llwarns << "Not writing cache for handle " << handle << "): Cache is currently disabled." << llendl;  		return ;  	}  	llassert_always(mInitialized);  	if(mReadOnly)  	{ +		llwarns << "Not writing cache for handle " << handle << "): Cache is currently in read-only mode." << llendl;  		return ; -	} +	}	  	HeaderEntryInfo* entry;  	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;  	if(iter == mHandleEntryMap.end()) //new entry -	{		 -		if(mNumEntries >= mCacheSize) +	{				 +		if(mNumEntries >= mCacheSize - 1)  		{ -			purgeEntries() ; +			purgeEntries(mCacheSize - 1) ;  		} -		 +  		entry = new HeaderEntryInfo();  		entry->mHandle = handle ;  		entry->mTime = time(NULL) ; -		entry->mIndex = mNumEntries++ ; +		entry->mIndex = mNumEntries++;  		mHeaderEntryQueue.insert(entry) ;  		mHandleEntryMap[handle] = entry ;  	}  	else  	{ -		entry = iter->second ; -		entry->mTime = time(NULL) ; +		// Update access time. +		entry = iter->second ;		  		//resort  		mHeaderEntryQueue.erase(entry) ; +		 +		entry->mTime = time(NULL) ;  		mHeaderEntryQueue.insert(entry) ;  	}  	//update cache header  	if(!updateEntry(entry))  	{ +		llwarns << "Failed to update cache header index " << entry->mIndex << ". handle = " << handle << llendl;  		return ; //update failed.  	}  	if(!dirty_cache)  	{ +		llwarns << "Skipping write to cache for handle " << handle << ": cache not dirty" << llendl;  		return ; //nothing changed, no need to update.  	}  	//write to cache file -	std::string filename; -	getObjectCacheFilename(handle, filename); -	LLAPRFile* apr_file = new LLAPRFile(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); -	 -	if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES)) +	bool success = true ;  	{ -		return ; -	} +		std::string filename; +		getObjectCacheFilename(handle, filename); +		LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +	 +		success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ; -	S32 num_entries = cache_entry_map.size() ; -	if(!checkWrite(apr_file, &num_entries, sizeof(S32))) -	{ -		return ; +	 +		if(success) +		{ +			S32 num_entries = cache_entry_map.size() ; +			success = check_write(&apr_file, &num_entries, sizeof(S32)); +	 +			for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter) +			{ +				success = iter->second->writeToFile(&apr_file) ; +			} +		}  	} -	for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); iter != cache_entry_map.end(); ++iter) +	if(!success)  	{ -		if(!iter->second->writeToFile(apr_file)) -		{ -			//failed -			delete apr_file ; -			removeCache() ; -			return ; -		} +		removeEntry(entry) ; +  	} -	delete apr_file ;  	return ;  } diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index ed2bc8bafe..14e3b4c793 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -95,7 +95,12 @@ private:  	{  		bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const  		{ -			return lhs->mTime < rhs->mTime; // older entry in front of queue (set) +			if(lhs->mTime == rhs->mTime)  +			{ +				return lhs < rhs ; +			} +			 +			return lhs->mTime < rhs->mTime ; // older entry in front of queue (set)  		}  	};  	typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t; @@ -111,6 +116,7 @@ public:  	void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;  	void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ; +	void removeEntry(U64 handle) ;  	void setReadOnly(BOOL read_only) {mReadOnly = read_only;}  @@ -118,15 +124,14 @@ private:  	void setDirNames(ELLPath location);	  	// determine the cache filename for the region from the region handle	  	void getObjectCacheFilename(U64 handle, std::string& filename); -	void removeFromCache(U64 handle); +	void removeFromCache(HeaderEntryInfo* entry);  	void readCacheHeader();  	void writeCacheHeader();  	void clearCacheInMemory();  	void removeCache() ; -	void purgeEntries(); +	void removeEntry(HeaderEntryInfo* entry) ; +	void purgeEntries(U32 size);  	BOOL updateEntry(const HeaderEntryInfo* entry); -	BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) ; -	BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) ;  private:  	BOOL                 mEnabled; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 761e12020b..f67e3a9770 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -388,10 +388,12 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  				// There's something bogus in the data that we're unpacking.  				dp->dumpBufferToLog();  				llwarns << "Flushing cache files" << llendl; -				std::string mask; -				mask = gDirUtilp->getDirDelimiter() + "*.slc"; -				gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask); -// 				llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl; + +				if(LLVOCache::hasInstance() && getRegion()) +				{ +					LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; +				} +				  				llwarns << "Bogus TE data in " << getID() << llendl;  			}  			else  @@ -667,11 +669,32 @@ void LLVOVolume::updateTextures()  	}  } +BOOL LLVOVolume::isVisible() const  +{ +	if(mDrawable.notNull() && mDrawable->isVisible()) +	{ +		return TRUE ; +	} + +	if(isAttachment()) +	{ +		LLViewerObject* objp = (LLViewerObject*)getParent() ; +		while(objp && !objp->isAvatar()) +		{ +			objp = (LLViewerObject*)objp->getParent() ; +		} + +		return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ; +	} + +	return FALSE ; +} +  void LLVOVolume::updateTextureVirtualSize()  {  	// Update the pixel area of all faces -	if(mDrawable.isNull() || !mDrawable->isVisible()) +	if(!isVisible())  	{  		return ;  	} @@ -2738,14 +2761,7 @@ void LLVOVolume::updateRadius()  BOOL LLVOVolume::isAttachment() const  { -	if (mState == 0) -	{ -		return FALSE; -	} -	else -	{ -		return TRUE; -	} +	return mState != 0 ;  }  BOOL LLVOVolume::isHUDAttachment() const diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 1e9b9737b1..8b68e7c78a 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -102,6 +102,7 @@ public:  				void	animateTextures();  	/*virtual*/ BOOL	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); +	            BOOL    isVisible() const ;  	/*virtual*/ BOOL	isActive() const;  	/*virtual*/ BOOL	isAttachment() const;  	/*virtual*/ BOOL	isRootEdit() const; // overridden for sake of attachments treating themselves as a root object diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index a49dc1b59d..66a6ab5e94 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -287,6 +287,9 @@ BOOL LLPanelBodyPartsListItem::postBuild()  	addWidgetToRightSide("btn_lock");  	addWidgetToRightSide("btn_edit_panel"); +	setWidgetsVisible(false); +	reshapeWidgets(); +  	return TRUE;  } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 15477e0a80..59b526059b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1967,12 +1967,12 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)  	if(drawablep && !drawablep->isDead())  	{ -	if (drawablep->isSpatialBridge()) -	{ +		if (drawablep->isSpatialBridge()) +		{  			const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;  			llassert(root); // trying to catch a bad assumption  			if (root && //  // this test may not be needed, see above -			    root->getVObj()->isAttachment()) +					root->getVObj()->isAttachment())  			{  				LLDrawable* rootparent = root->getParent();  				if (rootparent) // this IS sometimes NULL @@ -1980,24 +1980,24 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)  					LLViewerObject *vobj = rootparent->getVObj();  					llassert(vobj); // trying to catch a bad assumption  					if (vobj) // this test may not be needed, see above -		{ +					{  						const LLVOAvatar* av = vobj->asAvatar(); -			if (av && av->isImpostor()) -			{ -				return; -			} -		} +						if (av && av->isImpostor()) +						{ +							return; +						} +					}  				}  			} -		sCull->pushBridge((LLSpatialBridge*) drawablep); -	} -	else -	{ -		sCull->pushDrawable(drawablep); -	} +			sCull->pushBridge((LLSpatialBridge*) drawablep); +		} +		else +		{ +			sCull->pushDrawable(drawablep); +		} -	drawablep->setVisible(camera); -} +		drawablep->setVisible(camera); +	}  }  void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 3f785a99fe..cef3d87f36 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -424,6 +424,7 @@ public:  		RENDER_DEBUG_AVATAR_VOLUME      = 0x0100000,  		RENDER_DEBUG_BUILD_QUEUE		= 0x0200000,  		RENDER_DEBUG_AGENT_TARGET       = 0x0400000, +		RENDER_DEBUG_UPDATE_TYPE		= 0x0800000,  	};  public: diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 62441fd984..75aec21f93 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -115,9 +115,6 @@       name="AlertCautionTextColor"       reference="LtYellow" />      <color -     name="AgentLinkColor" -     reference="EmphasisColor" /> -    <color       name="AlertTextColor"       value="0.58 0.66 0.84 1" />      <color @@ -349,9 +346,6 @@       name="GridlineShadowColor"       value="0 0 0 0.31" />      <color -     name="GroupLinkColor" -     reference="White" /> -    <color       name="GroupNotifyBoxColor"       value="0.3344 0.5456 0.5159 1" />      <color diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 2c00120177..7b3cc7bdfa 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -107,6 +107,7 @@ with the same filename but different name    <texture name="ComboButton_Selected" file_name="widgets/ComboButton_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />    <texture name="ComboButton_UpSelected" file_name="widgets/ComboButton_UpSelected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />    <texture name="ComboButton_Up_On_Selected" file_name="widgets/ComboButton_Up_On_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> +  <texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />    <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />    <texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />    <texture name="Container" file_name="containers/Container.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 70299c61b4..27024f4eaa 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1580,9 +1580,6 @@ Klik på Acceptér for at deltage eller Afvis for at afvise invitationen. Klik p  	<notification name="VoiceCallGenericError">  		En fejl er opstået under forsøget på at koble sig på stemme chatten [VOICE_CHANNEL_NAME].  Pråv venligst senere.  	</notification> -	<notification name="ServerVersionChanged"> -		Du er netop ankommet til en region der benytter en anden server version, hvilket kan influere på hastigheden. [[URL] For at se yderligere.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Den SLurl du klikkede på understøttes ikke.  	</notification> @@ -1636,7 +1633,7 @@ Knappen vil blive vist når der er nok plads til den.  	<notification name="ShareItemsConfirmation">  		Er du sikker på at du vil dele følgende genstande: -[ITEMS] +<nolink>[ITEMS]</nolink>  Med følgende beboere: diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index bf525dd7c3..b0ad989a59 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -2717,9 +2717,6 @@ Klicken Sie auf  'Akzeptieren ', um dem Chat beizutreten, oder auf  &a  	<notification name="VoiceCallGenericError">  		Fehler beim Versuch, eine Voice-Chat-Verbindung zu [VOICE_CHANNEL_NAME] herzustellen.  Bitte versuchen Sie es erneut.  	</notification> -	<notification name="ServerVersionChanged"> -		Sie haben eine Region betreten, die eine andere Server-Version verwendet. Dies kann sich auf die Leistung auswirken. [[URL] Versionshinweise anzeigen.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Die SLurl, auf die Sie geklickt haben, wird nicht unterstützt.  	</notification> @@ -2773,7 +2770,7 @@ Die Schaltfläche wird angezeigt, wenn genügend Platz vorhanden ist.  	<notification name="ShareItemsConfirmation">  		Möchten Sie diese Objekte wirklich für andere freigeben: -[ITEMS] +<nolink>[ITEMS]</nolink>  Für folgende Einwohner: diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 6370ff9243..ae99fa8dd5 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -22,7 +22,11 @@       name="ToolTipMsg">          [REGION](Double-click to open Map, shift-drag to pan)      </floater.string> -    <floater.string name="mini_map_caption"> +	<floater.string +     name="AltToolTipMsg"> +		[REGION](Double-click to teleport, shift-drag to pan) +	</floater.string> +	<floater.string name="mini_map_caption">  	MINIMAP      </floater.string>      <net_map diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index e70e1eb61b..1808fea445 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -872,12 +872,13 @@               length="1"               follows="left|top"               left_pad="0" -             height="30" +             height="20"               layout="topleft"               name="Creator Name"               top_delta="0"               width="190" -             word_wrap="true"> +             word_wrap="true" +             use_ellipses="ture">                  Mrs. Esbee Linden (esbee.linden)              </text>              <text @@ -888,7 +889,7 @@               height="19"               layout="topleft"               name="Owner:" -             top_pad="3" +             top_pad="13"               width="90">                  Owner:              </text> @@ -897,13 +898,14 @@               type="string"               length="1"               follows="left|top" -             height="30" +             height="20"               layout="topleft"               name="Owner Name"               left_pad="0"               top_delta="0"               width="190" -             word_wrap="true"> +             word_wrap="true" +             use_ellipses="true">                  Mrs. Erica "Moose" Linden (erica.linden)              </text>             <text @@ -914,7 +916,7 @@               left="10"               height="18"               name="Group:" -             top_pad="7" +             top_pad="17"               width="75">                  Group:              </text> diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index 456b2d4421..e04a72cbc0 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -1,190 +1,190 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<floater
 -  legacy_header_height="18"
 -  can_resize="true"
 -  height="775"
 -  layout="topleft"
 -  min_height="400"
 -  min_width="500"
 -  name="floater_web_content"
 -  help_topic="floater_web_content"
 -  save_rect="true"
 -  auto_tile="true"
 -  title=""
 -  initial_mime_type="text/html"
 -  width="780">
 -  <layout_stack
 -    bottom="775"
 -    follows="left|right|top|bottom"
 -    layout="topleft"
 -    left="5"
 -    name="stack1"
 -    orientation="vertical"
 -    top="20"
 -    width="770">
 -    <layout_panel
 -      auto_resize="false"
 -      default_tab_group="1"
 -      height="22"
 -      layout="topleft"
 -      left="0"
 -      min_height="20"
 -      name="nav_controls"
 -      top="400"
 -      user_resize="false"
 -      width="770">
 -      <button
 -        image_overlay="Arrow_Left_Off"
 -		    image_disabled="PushButton_Disabled"
 -		    image_disabled_selected="PushButton_Disabled"
 -		    image_selected="PushButton_Selected"
 -		    image_unselected="PushButton_Off"
 -		    hover_glow_amount="0.15"
 -        tool_tip="Navigate back"
 -        follows="left|top"
 -        height="22"
 -        layout="topleft"
 -        left="1"
 -        name="back"
 -        top="0"
 -        width="22">
 -        <button.commit_callback
 -          function="WebContent.Back" />
 -      </button>
 -      <button
 -        image_overlay="Arrow_Right_Off"
 -		    image_disabled="PushButton_Disabled"
 -		    image_disabled_selected="PushButton_Disabled"
 -		    image_selected="PushButton_Selected"
 -		    image_unselected="PushButton_Off"
 -        tool_tip="Navigate forward"
 -        follows="left|top"
 -        height="22"
 -        layout="topleft"
 -        left="27"
 -        name="forward"
 -        top_delta="0"
 -        width="22">
 -        <button.commit_callback
 -          function="WebContent.Forward" />
 -      </button>
 -      <button
 -        image_overlay="Stop_Off"
 -		    image_disabled="PushButton_Disabled"
 -		    image_disabled_selected="PushButton_Disabled"
 -		    image_selected="PushButton_Selected"
 -		    image_unselected="PushButton_Off"
 -        tool_tip="Stop navigation"
 -        enabled="true"
 -        follows="left|top"
 -        height="22"
 -        layout="topleft"
 -        left="51"
 -        name="stop"
 -        top_delta="0"
 -        width="22">
 -        <button.commit_callback
 -          function="WebContent.Stop" />
 -      </button>
 -      <button
 -        image_overlay="Refresh_Off"
 -		    image_disabled="PushButton_Disabled"
 -		    image_disabled_selected="PushButton_Disabled"
 -		    image_selected="PushButton_Selected"
 -		    image_unselected="PushButton_Off"
 -        tool_tip="Reload page"
 -        follows="left|top"
 -        height="22"
 -        layout="topleft"
 -        left="51"
 -        name="reload"
 -        top_delta="0"
 -        width="22">
 -        <button.commit_callback
 -          function="WebContent.Reload" />
 -      </button>
 -      <combo_box
 -        allow_text_entry="true"
 -        follows="left|top|right"
 -        tab_group="1"
 -        height="22"
 -        layout="topleft"
 -        left_pad="4"
 -        max_chars="1024"
 -        name="address"
 -        combo_editor.select_on_focus="true"
 -        tool_tip="Enter URL here"
 -        top_delta="0"
 -        width="672">
 -        <combo_box.commit_callback
 -          function="WebContent.EnterAddress" />
 -      </combo_box>
 -      <icon
 -        name="media_secure_lock_flag"
 -        height="16"
 -        follows="top|right"
 -        image_name="Lock2"
 -        layout="topleft"
 -        left_delta="620"
 -        top_delta="2"
 -        visible="false" 
 -        tool_tip="Secured Browsing"
 -        width="16" />
 -      <button
 -        image_overlay="ExternalBrowser_Off"
 -		    image_disabled="PushButton_Disabled"
 -		    image_disabled_selected="PushButton_Disabled"
 -		    image_selected="PushButton_Selected"
 -		    image_unselected="PushButton_Off"
 -        tool_tip="Open current URL in your desktop browser"
 -        follows="right|top"
 -        enabled="true" 
 -        height="22"
 -        layout="topleft"
 -        name="popexternal"
 -        right="770"
 -        top_delta="-2"
 -        width="22">
 -        <button.commit_callback
 -          function="WebContent.PopExternal" />
 -      </button>
 -    </layout_panel>
 -    <layout_panel
 -      height="40"
 -      layout="topleft"
 -      left_delta="0"
 -      name="external_controls"
 -      top_delta="0"
 -      user_resize="false"
 -      width="585">
 -      <web_browser
 -        bottom="-22"
 -        follows="all"
 -        layout="topleft"
 -        left="0"
 -        name="webbrowser"
 -        top="0"/>
 -      <text
 -        type="string"
 -        length="200"
 -        follows="bottom|left"
 -        height="20"
 -        layout="topleft"
 -        left_delta="0"
 -        name="statusbartext"
 -        parse_urls="false"
 -        text_color="0.4 0.4 0.4 1"
 -        top_pad="5"
 -        width="495"/>
 -      <progress_bar
 -        color_bar="0.3 1.0 0.3 1"
 -        follows="bottom|right"
 -        height="16"
 -        top_delta="-1"
 -        left_pad="24"
 -        layout="topleft"
 -        name="statusbarprogress"
 -        width="64"/>
 -    </layout_panel>
 -  </layout_stack>
 -</floater>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater +  legacy_header_height="18" +  can_resize="true" +  height="775" +  layout="topleft" +  min_height="400" +  min_width="500" +  name="floater_web_content" +  help_topic="floater_web_content" +  save_rect="true" +  auto_tile="true" +  title="" +  initial_mime_type="text/html" +  width="780"> +  <layout_stack +    bottom="775" +    follows="left|right|top|bottom" +    layout="topleft" +    left="5" +    name="stack1" +    orientation="vertical" +    top="20" +    width="770"> +    <layout_panel +      auto_resize="false" +      default_tab_group="1" +      height="22" +      layout="topleft" +      left="0" +      min_height="20" +      name="nav_controls" +      top="400" +      user_resize="false" +      width="770"> +      <button +        image_overlay="Arrow_Left_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off" +		    hover_glow_amount="0.15" +        tool_tip="Navigate back" +        follows="left|top" +        height="22" +        layout="topleft" +        left="1" +        name="back" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.Back" /> +      </button> +      <button +        image_overlay="Arrow_Right_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off" +        tool_tip="Navigate forward" +        follows="left|top" +        height="22" +        layout="topleft" +        left="27" +        name="forward" +        top_delta="0" +        width="22"> +        <button.commit_callback +          function="WebContent.Forward" /> +      </button> +      <button +        image_overlay="Stop_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off" +        tool_tip="Stop navigation" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="51" +        name="stop" +        top_delta="0" +        width="22"> +        <button.commit_callback +          function="WebContent.Stop" /> +      </button> +      <button +        image_overlay="Refresh_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off" +        tool_tip="Reload page" +        follows="left|top" +        height="22" +        layout="topleft" +        left="51" +        name="reload" +        top_delta="0" +        width="22"> +        <button.commit_callback +          function="WebContent.Reload" /> +      </button> +      <combo_box +        allow_text_entry="true" +        follows="left|top|right" +        tab_group="1" +        height="22" +        layout="topleft" +        left_pad="4" +        max_chars="1024" +        name="address" +        combo_editor.select_on_focus="true" +        tool_tip="Enter URL here" +        top_delta="0" +        width="672"> +        <combo_box.commit_callback +          function="WebContent.EnterAddress" /> +      </combo_box> +      <icon +        name="media_secure_lock_flag" +        height="16" +        follows="top|right" +        image_name="Lock2" +        layout="topleft" +        left_delta="620" +        top_delta="2" +        visible="false"  +        tool_tip="Secured Browsing" +        width="16" /> +      <button +        image_overlay="ExternalBrowser_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off" +        tool_tip="Open current URL in your desktop browser" +        follows="right|top" +        enabled="true"  +        height="22" +        layout="topleft" +        name="popexternal" +        right="770" +        top_delta="-2" +        width="22"> +        <button.commit_callback +          function="WebContent.PopExternal" /> +      </button> +    </layout_panel> +    <layout_panel +      height="40" +      layout="topleft" +      left_delta="0" +      name="external_controls" +      top_delta="0" +      user_resize="false" +      width="585"> +      <web_browser +        bottom="-22" +        follows="all" +        layout="topleft" +        left="0" +        name="webbrowser" +        top="0"/> +      <text +        type="string" +        length="200" +        follows="bottom|left" +        height="20" +        layout="topleft" +        left_delta="0" +        name="statusbartext" +        parse_urls="false" +        text_color="0.4 0.4 0.4 1" +        top_pad="5" +        width="495"/> +      <progress_bar +        color_bar="0.3 1.0 0.3 1" +        follows="bottom|right" +        height="16" +        top_delta="-1" +        left_pad="24" +        layout="topleft" +        name="statusbarprogress" +        width="64"/> +    </layout_panel> +  </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index c751aa4e0c..719509301b 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -100,7 +100,7 @@           name="Object Attach HUD" />     </context_menu>     <context_menu -         label="Remove" +         label="Manage"           name="Remove">     <menu_item_call           enabled="false" @@ -129,15 +129,6 @@           <menu_item_call.on_enable            function="Object.EnableReturn" />       </menu_item_call> -     <menu_item_call -   enabled="false" -   label="Delete" -   name="Delete"> -      <menu_item_call.on_click -       function="Object.Delete" /> -      <menu_item_call.on_enable -       function="Object.EnableDelete" /> -    </menu_item_call>      </context_menu>     <menu_item_separator layout="topleft" />     <menu_item_call @@ -176,4 +167,13 @@        <menu_item_call.on_enable         function="Object.EnableBuy" />     </menu_item_call> +   <menu_item_call +     enabled="false" +     label="Delete" +     name="Delete"> +      <menu_item_call.on_click +       function="Object.Delete" /> +      <menu_item_call.on_enable +       function="Object.EnableDelete" /> +  </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml index 6f46165883..1aeb166e01 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -25,6 +25,14 @@           function="Places.LandmarksGear.Enable"           parameter="category" />      </menu_item_call> +    <menu_item_call +     label="Restore Item" +     layout="topleft" +     name="restore_item"> +        <menu_item_call.on_click +         function="Places.LandmarksGear.Custom.Action" +         parameter="restore" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" />      <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml index 121e7cc07a..ff5fdd3795 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -60,6 +60,14 @@           function="Places.LandmarksGear.Enable"           parameter="category" />      </menu_item_call> +    <menu_item_call +     label="Restore Item" +     layout="topleft" +     name="restore_item"> +        <menu_item_call.on_click +         function="Places.LandmarksGear.Custom.Action" +         parameter="restore" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" />      <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index d997a262a8..08ae0c233e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1960,6 +1960,16 @@                   function="ToggleControl"                   parameter="DebugShowRenderInfo" />              </menu_item_check> +			<menu_item_check +             label="Show Texture Info" +             name="Show Texture Info"> +                <menu_item_check.on_check +                 function="CheckControl" +                 parameter="DebugShowTextureInfo" /> +                <menu_item_check.on_click +                 function="ToggleControl" +                 parameter="DebugShowTextureInfo" /> +            </menu_item_check>              <menu_item_check               label="Show Matrices"               name="Show Matrices"> @@ -1980,6 +1990,16 @@                   function="ToggleControl"                   parameter="DebugShowColor" />              </menu_item_check> +            <menu_item_check +               label="Show Memory" +               name="Show Memory"> +              <menu_item_check.on_check +               function="CheckControl" +               parameter="DebugShowMemory" /> +              <menu_item_check.on_click +               function="ToggleControl" +               parameter="DebugShowMemory" /> +            </menu_item_check>              <menu_item_separator/> @@ -2153,6 +2173,16 @@             parameter="render batches" />          </menu_item_check>          <menu_item_check +         label="Update Type" +         name="Update Type"> +          <menu_item_check.on_check +           function="Advanced.CheckInfoDisplay" +           parameter="update type" /> +          <menu_item_check.on_click +           function="Advanced.ToggleInfoDisplay" +           parameter="update type" /> +        </menu_item_check> +        <menu_item_check           label="Texture Anim"           name="Texture Anim">            <menu_item_check.on_check @@ -2717,6 +2747,18 @@                   function="Floater.Toggle"                   parameter="region_debug_console" />              </menu_item_check> +            <menu_item_check +             label="Region Debug Console" +             name="Region Debug Console" +             shortcut="control|shift|`" +             use_mac_ctrl="true"> +                <menu_item_check.on_check +                 function="Floater.Visible" +                 parameter="region_debug_console" /> +                <menu_item_check.on_click +                 function="Floater.Toggle" +                 parameter="region_debug_console" /> +            </menu_item_check>              <menu_item_separator /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3df53ac442..f008042a81 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6304,15 +6304,6 @@ An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_N    </notification>    <notification -   duration="10" -   icon="notifytip.tga" -   name="ServerVersionChanged" -   priority="high" -   type="notifytip"> -You just entered a region using a different server version, which may affect performance. [[URL] View the release notes.] -  </notification> - -  <notification     icon="notifytip.tga"     name="UnsupportedCommandSLURL"     priority="high" @@ -6431,7 +6422,7 @@ Select residents to share with.     type="alertmodal">  Are you sure you want to share the following items: -[ITEMS] +<nolink>[ITEMS]</nolink>  With the following Residents: diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 61d6cbb2d0..eff674c628 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -67,23 +67,23 @@          <scroll_list.columns           label="Parcel"           name="name" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Region"           name="location" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Type"           name="type" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Area"           name="area" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Hidden"           name="hidden" -         width="47" /> +         relative_width="0.2" />      </scroll_list>      <text       type="string" diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 5871eb0654..21c627cdfb 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -45,9 +45,9 @@       left_pad="4"       image_disabled="ComboButton_UpOff"       image_unselected="ComboButton_UpOff" -     image_selected="ComboButton_Up_On_Selected" +     image_selected="ComboButton_On"       image_pressed="ComboButton_UpSelected" -     image_pressed_selected="ComboButton_Up_On_Selected" +     image_pressed_selected="ComboButton_Selected"       height="23"       name="show_nearby_chat"       tool_tip="Shows/hides nearby chat log"> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml index 8c13ced8f3..9bd60b935f 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml @@ -68,24 +68,12 @@  		right="-8"  		width="66"  		height="22" +		is_toggle="true"  		label="More >>" -		label_selected="Less <<"> +		label_selected="<< Less">  	  <button.commit_callback  		  function="MediaListCtrl.MoreLess" />  	</button> -  <button -		name="less_btn" -		follows="right" -		tool_tip="Advanced Controls" -		top_delta="0" -		right="-8" -		width="66" -		height="22" -		label="More >>" -		label_selected="Less <<"> -      <button.commit_callback -        function="MediaListCtrl.MoreLess" /> -  </button>    </panel>    <panel  	  name="nearby_media_panel" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 6a8bf87bc5..43431ea7c1 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -54,7 +54,13 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M      <string       name="no_groups_msg"       value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." /> -    <filter_editor +	<string +	 name="MiniMapToolTipMsg" +	 value="[REGION](Double-click to open Map, shift-drag to pan)"/> +	<string +	 name="AltMiniMapToolTipMsg" +	 value="[REGION](Double-click to teleport, shift-drag to pan)"/> +	<filter_editor       follows="left|top|right"       height="23"       layout="topleft" @@ -93,16 +99,26 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M           name="nearby_panel"           top="0"           width="313"> -            <avatar_list +			<net_map +			 bg_color="NetMapBackgroundColor" +			 follows="top|left|right" +			 layout="topleft" +			 left="3" +			 mouse_opaque="false" +			 name="Net Map" +			 width="307" +			 height="140" +			 top="0"/> +			<avatar_list               allow_select="true" -             follows="all" -             height="356" +             follows="top|left|bottom|right" +             height="216"               ignore_online_status="true"               layout="topleft"               left="3"               multi_select="true"               name="avatar_list" -             top="0" +             top="145"               width="307" />              <panel               background_visible="true" diff --git a/indra/newview/skins/default/xui/en/widgets/floater.xml b/indra/newview/skins/default/xui/en/widgets/floater.xml index 85d0c633af..2e5ebafe46 100644 --- a/indra/newview/skins/default/xui/en/widgets/floater.xml +++ b/indra/newview/skins/default/xui/en/widgets/floater.xml @@ -21,4 +21,5 @@   tear_off_pressed_image="tearoff_pressed.tga"   dock_pressed_image="Icon_Dock_Press"   help_pressed_image="Icon_Help_Press" + focus_root="true"    /> diff --git a/indra/newview/skins/default/xui/en/widgets/talk_button.xml b/indra/newview/skins/default/xui/en/widgets/talk_button.xml index a7e271a1ff..d792e9f29c 100644 --- a/indra/newview/skins/default/xui/en/widgets/talk_button.xml +++ b/indra/newview/skins/default/xui/en/widgets/talk_button.xml @@ -23,11 +23,11 @@      bottom="0"      tab_stop="false"      is_toggle="true" -                 image_selected="SegmentedBtn_Right_Selected_Press" -                 image_unselected="SegmentedBtn_Right_Off" -		 image_pressed="SegmentedBtn_Right_Press" -		 image_pressed_selected="SegmentedBtn_Right_Selected_Press" -		 image_overlay="Arrow_Small_Up" +    image_disabled="ComboButton_UpOff" +    image_unselected="ComboButton_UpOff" +    image_selected="ComboButton_On" +    image_pressed="ComboButton_UpSelected" +    image_pressed_selected="ComboButton_Selected"      />    <monitor      follows="right"  diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 051314bdfa..2bf36bb763 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -2706,9 +2706,6 @@ Pulsa Aceptar o Rehusar para coger o no la llamada. Pulsa Ignorar para ignorar a  	<notification name="VoiceCallGenericError">  		Se ha producido un error al intentar conectarte al [VOICE_CHANNEL_NAME]. Por favor, inténtalo más tarde.  	</notification> -	<notification name="ServerVersionChanged"> -		Acabas de entrar en una región que usa un servidor con una versión distinta, y esto puede influir en el funcionamiento. [[URL] Ver las notas de desarrollo]. -	</notification>  	<notification name="UnsupportedCommandSLURL">  		No se admite el formato de la SLurl que has pulsado.  	</notification> @@ -2762,7 +2759,7 @@ Se mostrará cuando haya suficiente espacio.  	<notification name="ShareItemsConfirmation">  		¿Estás seguro de que quieres compartir los elementos siguientes? -[ITEMS] +<nolink>[ITEMS]</nolink>  Con los siguientes residentes: diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 140bbcc18b..603b8f0edc 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2702,9 +2702,6 @@ Pour y participer, cliquez sur Accepter. Sinon, cliquez sur Refuser. Pour ignore  	<notification name="VoiceCallGenericError">  		Une erreur est survenue pendant la connexion au chat vocal pour [VOICE_CHANNEL_NAME]. Veuillez réessayer ultérieurement.  	</notification> -	<notification name="ServerVersionChanged"> -		La région dans laquelle vous avez pénétré utilise une version de serveur différente, ce qui peut avoir un impact sur votre performance. [[URL] Consultez les notes de version.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		La SLurl que vous avez saisie n'est pas prise en charge.  	</notification> @@ -2758,7 +2755,7 @@ Le bouton sera affiché quand il y aura suffisamment de place.  	<notification name="ShareItemsConfirmation">  		Voulez-vous vraiment partager les articles suivants : -[ITEMS] +<nolink>[ITEMS]</nolink>  avec les résidents suivants : diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 32483881b2..cce5888598 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -2623,9 +2623,6 @@ Clicca su Accetta per unirti alla chat oppure su Declina per declinare l'in  	<notification name="VoiceCallGenericError">  		Si è verificato un errore durante il tentativo di collegarti a una voice chat con [VOICE_CHANNEL_NAME].  Riprova più tardi.  	</notification> -	<notification name="ServerVersionChanged"> -		Sei appena entrato in una regione che usa una versione differente del server: ciò potrebbe incidere sule prestazioni. [[URL] Visualizza le note sulla versione.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Lo SLurl su cui hai cliccato non è valido.  	</notification> @@ -2679,7 +2676,7 @@ Il pulsante verrà visualizzato quando lo spazio sarà sufficiente.  	<notification name="ShareItemsConfirmation">  		Sei sicuro di volere condividere gli oggetti -[ITEMS] +<nolink>[ITEMS]</nolink>  Con i seguenti residenti? diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index c0af0e03ff..baec8c073c 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -2675,9 +2675,6 @@ M キーを押して変更します。  	<notification name="VoiceCallGenericError">  		[VOICE_CHANNEL_NAME] のボイスチャットに接続中に、エラーが発生しました。後でもう一度お試しください。  	</notification> -	<notification name="ServerVersionChanged"> -		サーバーのバージョンが異なるリージョンに来ました。パフォーマンスに影響することがあります。 [[URL] リリースノートを確認] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		クリックした SLurl はサポートされていません。  	</notification> @@ -2731,7 +2728,7 @@ M キーを押して変更します。  	<notification name="ShareItemsConfirmation">  		次のアイテムを共有しますか: -[ITEMS] +<nolink>[ITEMS]</nolink>  次の住人と共有しますか: diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml index be0c17d2ff..f27b83d3f9 100644 --- a/indra/newview/skins/default/xui/nl/notifications.xml +++ b/indra/newview/skins/default/xui/nl/notifications.xml @@ -3012,9 +3012,6 @@ Klik Accepteren om deel te nemen aan de chat of Afwijzen om de uitnodiging af te  	<notification name="VoiceCallGenericError">  		Er is een fout opgetreden tijdens het verbinden met voice chat voor [VOICE_CHANNEL_NAME]. Probeert u het later alstublieft opnieuw.  	</notification> -	<notification name="ServerVersionChanged"> -		De regio die u bent binnengetreden wordt onder een andere simulatorversie uitgevoerd. Klik dit bericht voor meer details. -	</notification>  	<notification name="UnableToOpenCommandURL">  		De URL die u heeft geklikt kan niet binnen deze webbrowser worden geopend.  	</notification> diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index 8dc4b041cd..25fa5da3ab 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -2672,9 +2672,6 @@ Wybierz Zaakceptuj żeby zacząć czat albo Odmów żeby nie przyjąć zaproszen  	<notification name="VoiceCallGenericError">  		Błąd podczas łączenia z rozmową [VOICE_CHANNEL_NAME]. Spróbuj póżniej.  	</notification> -	<notification name="ServerVersionChanged"> -		Ten region używa innej wersji symulatora. Kliknij na tą wiadomość żeby uzyskać więcej informacji: [[URL] View the release notes.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Nie można otworzyć wybranego SLurl.  	</notification> @@ -2728,7 +2725,7 @@ Przycisk zostanie wyświetlony w przypadku dostatecznej ilości przestrzeni.  	<notification name="ShareItemsConfirmation">  		Jesteś pewien/pewna, że chcesz udostępnić następujące obiekty: -[ITEMS] +<nolink>[ITEMS]</nolink>  następującym Rezydentom: diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 5f09397ac5..4b2e4bc5e0 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -481,7 +481,7 @@ Para aumentar a qualidade do vídeo, vá para Preferências > Vídeo.  	</notification>  	<notification name="CannotCopyWarning">  		Você não tem autorização para copiar os itens abaixo: -[ITENS] +[ITEMS]  ao dá-los, você ficará sem eles no seu inventário. Deseja realmente dar estes itens?  		<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>  	</notification> @@ -2686,9 +2686,6 @@ Clique em Aceitar para atender ou em Recusar para recusar este convite.  Clique  	<notification name="VoiceCallGenericError">  		Ocorreu um erro enquanto você tentava se conectar à conversa de voz de [VOICE_CHANNEL_NAME].  Favor tentar novamente mais tarde.  	</notification> -	<notification name="ServerVersionChanged"> -		Você chegou a uma região com uma versão diferente de servidor, que pode afetar o desempenho.  [[URL] Consultar notas da versão.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		O SLurl no qual você clicou não é suportado.  	</notification> @@ -2742,7 +2739,7 @@ O botão será exibido quando houver espaço suficente.  	<notification name="ShareItemsConfirmation">  		Tem certeza de que quer compartilhar os items abaixo? -[ITENS] +<nolink>[ITEMS]</nolink>  Com os seguintes residentes: diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp index 9da851ffc4..d691bb6c44 100644 --- a/indra/newview/tests/llcapabilitylistener_test.cpp +++ b/indra/newview/tests/llcapabilitylistener_test.cpp @@ -72,7 +72,7 @@ struct TestCapabilityProvider: public LLCapabilityProvider      {          mCaps[cap] = url;      } -    LLHost getHost() const { return mHost; } +    const LLHost& getHost() const { return mHost; }      std::string getDescription() const { return "TestCapabilityProvider"; }      LLHost mHost; diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp index a6c1f69c82..7862cce3a1 100644 --- a/indra/newview/tests/llremoteparcelrequest_test.cpp +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -1,134 +1,136 @@ -/** 
 - * @file llremoteparcelrequest_test.cpp
 - * @author Brad Kittenbrink <brad@lindenlab.com>
 - *
 - * $LicenseInfo:firstyear=2010&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "linden_common.h"
 -
 -#include "../test/lltut.h"
 -
 -#include "../llremoteparcelrequest.h"
 -
 -#include "../llagent.h"
 -#include "message.h"
 -
 -namespace {
 -	LLControlGroup s_saved_settings("dummy_settings");
 -	const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
 -}
 -
 -LLCurl::Responder::Responder() { }
 -LLCurl::Responder::~Responder() { }
 -void LLCurl::Responder::error(U32,std::string const &) { }
 -void LLCurl::Responder::result(LLSD const &) { }
 -void LLCurl::Responder::errorWithContent(U32 status,std::string const &,LLSD const &) { }
 -void LLCurl::Responder::completedRaw(U32 status, std::string const &, LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
 -void LLCurl::Responder::completed(U32 status, std::string const &, LLSD const &) { }
 -void LLCurl::Responder::completedHeader(U32 status, std::string const &, LLSD const &) { }
 -void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { }
 -void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { }
 -void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { }
 -void LLMessageSystem::getString(char const *,char const *, std::string &,S32) { }
 -void LLMessageSystem::getUUID(char const *,char const *, LLUUID & out_id,S32)
 -{
 -	out_id = TEST_PARCEL_ID;
 -}
 -void LLMessageSystem::nextBlock(char const *) { }
 -void LLMessageSystem::addUUID(char const *,LLUUID const &) { }
 -void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { }
 -void LLMessageSystem::nextBlockFast(char const *) { }
 -void LLMessageSystem::newMessage(char const *) { }
 -LLMessageSystem * gMessageSystem;
 -char * _PREHASH_AgentID;
 -char * _PREHASH_AgentData;
 -LLAgent gAgent;
 -LLAgent::LLAgent() : mAgentAccess(s_saved_settings) { }
 -LLAgent::~LLAgent() { }
 -void LLAgent::sendReliableMessage(void) { }
 -LLUUID gAgentSessionID;
 -LLUUID gAgentID;
 -LLUIColor::LLUIColor(void) { }
 -LLAgentAccess::LLAgentAccess(LLControlGroup & settings) : mSavedSettings(settings) { }
 -LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
 -LLControlGroup::~LLControlGroup(void) { }
 -
 -namespace tut
 -{
 -	struct TestObserver : public LLRemoteParcelInfoObserver {
 -		TestObserver() : mProcessed(false) { }
 -
 -		virtual void processParcelInfo(const LLParcelData& parcel_data)
 -		{
 -			mProcessed = true;
 -		}
 -
 -		virtual void setParcelID(const LLUUID& parcel_id) { }
 -
 -		virtual void setErrorStatus(U32 status, const std::string& reason) { }
 -
 -		bool mProcessed;
 -	};
 -
 -    struct RemoteParcelRequestData
 -    {
 -		RemoteParcelRequestData()
 -		{
 -		}
 -    };
 -    
 -	typedef test_group<RemoteParcelRequestData> remoteparcelrequest_t;
 -	typedef remoteparcelrequest_t::object remoteparcelrequest_object_t;
 -	tut::remoteparcelrequest_t tut_remoteparcelrequest("LLRemoteParcelRequest");
 -
 -	template<> template<>
 -	void remoteparcelrequest_object_t::test<1>()
 -	{
 -		set_test_name("observer pointer");
 -
 -		boost::scoped_ptr<TestObserver> observer(new TestObserver());
 -
 -		LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
 -		processor.addObserver(LLUUID(TEST_PARCEL_ID), observer.get());
 -
 -		processor.processParcelInfoReply(gMessageSystem, NULL);
 -
 -		ensure(observer->mProcessed);
 -	}
 -
 -	template<> template<>
 -	void remoteparcelrequest_object_t::test<2>()
 -	{
 -		set_test_name("CHOP-220: dangling observer pointer");
 -
 -		LLRemoteParcelInfoObserver * observer = new TestObserver();
 -
 -		LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
 -		processor.addObserver(LLUUID(TEST_PARCEL_ID), observer);
 -
 -		delete observer;
 -		observer = NULL;
 -
 -		processor.processParcelInfoReply(gMessageSystem, NULL);
 -	}
 -}
 +/**  + * @file llremoteparcelrequest_test.cpp + * @author Brad Kittenbrink <brad@lindenlab.com> + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llremoteparcelrequest.h" + +#include "../llagent.h" +#include "message.h" +#include "llurlentry.h" + +namespace { +	LLControlGroup s_saved_settings("dummy_settings"); +	const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111"); +} + +LLCurl::Responder::Responder() { } +LLCurl::Responder::~Responder() { } +void LLCurl::Responder::error(U32,std::string const &) { } +void LLCurl::Responder::result(LLSD const &) { } +void LLCurl::Responder::errorWithContent(U32 status,std::string const &,LLSD const &) { } +void LLCurl::Responder::completedRaw(U32 status, std::string const &, LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { } +void LLCurl::Responder::completed(U32 status, std::string const &, LLSD const &) { } +void LLCurl::Responder::completedHeader(U32 status, std::string const &, LLSD const &) { } +void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { } +void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { } +void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { } +void LLMessageSystem::getString(char const *,char const *, std::string &,S32) { } +void LLMessageSystem::getUUID(char const *,char const *, LLUUID & out_id,S32) +{ +	out_id = TEST_PARCEL_ID; +} +void LLMessageSystem::nextBlock(char const *) { } +void LLMessageSystem::addUUID(char const *,LLUUID const &) { } +void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { } +void LLMessageSystem::nextBlockFast(char const *) { } +void LLMessageSystem::newMessage(char const *) { } +LLMessageSystem * gMessageSystem; +char * _PREHASH_AgentID; +char * _PREHASH_AgentData; +LLAgent gAgent; +LLAgent::LLAgent() : mAgentAccess(s_saved_settings) { } +LLAgent::~LLAgent() { } +void LLAgent::sendReliableMessage(void) { } +LLUUID gAgentSessionID; +LLUUID gAgentID; +LLUIColor::LLUIColor(void) { } +LLAgentAccess::LLAgentAccess(LLControlGroup & settings) : mSavedSettings(settings) { } +LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { } +LLControlGroup::~LLControlGroup(void) { } +void LLUrlEntryParcel::processParcelInfo(const LLUrlEntryParcel::LLParcelData& parcel_data) { } + +namespace tut +{ +	struct TestObserver : public LLRemoteParcelInfoObserver { +		TestObserver() : mProcessed(false) { } + +		virtual void processParcelInfo(const LLParcelData& parcel_data) +		{ +			mProcessed = true; +		} + +		virtual void setParcelID(const LLUUID& parcel_id) { } + +		virtual void setErrorStatus(U32 status, const std::string& reason) { } + +		bool mProcessed; +	}; + +    struct RemoteParcelRequestData +    { +		RemoteParcelRequestData() +		{ +		} +    }; +     +	typedef test_group<RemoteParcelRequestData> remoteparcelrequest_t; +	typedef remoteparcelrequest_t::object remoteparcelrequest_object_t; +	tut::remoteparcelrequest_t tut_remoteparcelrequest("LLRemoteParcelRequest"); + +	template<> template<> +	void remoteparcelrequest_object_t::test<1>() +	{ +		set_test_name("observer pointer"); + +		boost::scoped_ptr<TestObserver> observer(new TestObserver()); + +		LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance(); +		processor.addObserver(LLUUID(TEST_PARCEL_ID), observer.get()); + +		processor.processParcelInfoReply(gMessageSystem, NULL); + +		ensure(observer->mProcessed); +	} + +	template<> template<> +	void remoteparcelrequest_object_t::test<2>() +	{ +		set_test_name("CHOP-220: dangling observer pointer"); + +		LLRemoteParcelInfoObserver * observer = new TestObserver(); + +		LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance(); +		processor.addObserver(LLUUID(TEST_PARCEL_ID), observer); + +		delete observer; +		observer = NULL; + +		processor.processParcelInfoReply(gMessageSystem, NULL); +	} +} diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 5f8cd28f29..88ab5a2284 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -1,200 +1,200 @@ -/**
 - * @file   llupdaterservice_test.cpp
 - * @brief  Tests of llupdaterservice.cpp.
 - * 
 - * $LicenseInfo:firstyear=2010&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$
 - */
 -
 -// Precompiled header
 -#include "linden_common.h"
 -// associated header
 -#include "../llupdaterservice.h"
 -#include "../llupdatechecker.h"
 -#include "../llupdatedownloader.h"
 -#include "../llupdateinstaller.h"
 -
 -#include "../../../test/lltut.h"
 -//#define DEBUG_ON
 -#include "../../../test/debug.h"
 -
 -#include "llevents.h"
 -#include "lldir.h"
 -
 -/*****************************************************************************
 -*   MOCK'd
 -*****************************************************************************/
 -LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
 -{}
 -void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, 
 -								  std::string const & servicePath, std::string channel, std::string version)
 -{}
 -LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
 -void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, bool){}
 -
 -class LLDir_Mock : public LLDir
 -{
 -	void initAppDirs(const std::string &app_name, 
 -		   			 const std::string& app_read_only_data_dir = "") {}
 -	U32 countFilesInDir(const std::string &dirname, const std::string &mask) 
 -	{
 -		return 0;
 -	}
 -
 -	BOOL getNextFileInDir(const std::string &dirname, 
 -						  const std::string &mask, 
 -						  std::string &fname) 
 -	{
 -		return false;
 -	}
 -	void getRandomFileInDir(const std::string &dirname, 
 -							const std::string &mask, 
 -							std::string &fname) {}
 -	std::string getCurPath() { return ""; }
 -	BOOL fileExists(const std::string &filename) const { return false; }
 -	std::string getLLPluginLauncher() { return ""; }
 -	std::string getLLPluginFilename(std::string base_name) { return ""; }
 -
 -} gDirUtil;
 -LLDir* gDirUtilp = &gDirUtil;
 -LLDir::LLDir() {}
 -LLDir::~LLDir() {}
 -S32 LLDir::deleteFilesInDir(const std::string &dirname, 
 -							const std::string &mask)
 -{ return 0; }
 -
 -void LLDir::setChatLogsDir(const std::string &path){}		
 -void LLDir::setPerAccountChatLogsDir(const std::string &username){}
 -void LLDir::setLindenUserDir(const std::string &username){}		
 -void LLDir::setSkinFolder(const std::string &skin_folder){}
 -bool LLDir::setCacheDir(const std::string &path){ return true; }
 -void LLDir::dumpCurrentDirectories() {}
 -
 -std::string LLDir::getExpandedFilename(ELLPath location, 
 -									   const std::string &filename) const 
 -{
 -	return "";
 -}
 -
 -std::string LLUpdateDownloader::downloadMarkerPath(void)
 -{
 -	return "";
 -}
 -
 -void LLUpdateDownloader::resume(void) {}
 -void LLUpdateDownloader::cancel(void) {}
 -void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) {}
 -
 -int ll_install_update(std::string const &, std::string const &, bool, LLInstallScriptMode)
 -{
 -	return 0;
 -}
 -
 -std::string const & ll_install_failed_marker_path()
 -{
 -	static std::string wubba;
 -	return wubba;
 -}
 -
 -/*
 -#pragma warning(disable: 4273)
 -llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename,
 -										   ios_base::openmode _Mode,
 -										   int _Prot) :
 -	std::basic_istream<char,std::char_traits< char > >(NULL,true)
 -{}
 -
 -llus_mock_llifstream::~llus_mock_llifstream() {}
 -bool llus_mock_llifstream::is_open() const {return true;}
 -void llus_mock_llifstream::close() {}
 -*/
 -
 -/*****************************************************************************
 -*   TUT
 -*****************************************************************************/
 -namespace tut
 -{
 -    struct llupdaterservice_data
 -    {
 -		llupdaterservice_data() :
 -            pumps(LLEventPumps::instance()),
 -			test_url("dummy_url"),
 -			test_channel("dummy_channel"),
 -			test_version("dummy_version")
 -		{}
 -		LLEventPumps& pumps;
 -		std::string test_url;
 -		std::string test_channel;
 -		std::string test_version;
 -	};
 -
 -    typedef test_group<llupdaterservice_data> llupdaterservice_group;
 -    typedef llupdaterservice_group::object llupdaterservice_object;
 -    llupdaterservice_group llupdaterservicegrp("LLUpdaterService");
 -
 -    template<> template<>
 -    void llupdaterservice_object::test<1>()
 -    {
 -        DEBUG;
 -		LLUpdaterService updater;
 -		bool got_usage_error = false;
 -		try
 -		{
 -			updater.startChecking();
 -		}
 -		catch(LLUpdaterService::UsageError)
 -		{
 -			got_usage_error = true;
 -		}
 -		ensure("Caught start before params", got_usage_error);
 -	}
 -
 -    template<> template<>
 -    void llupdaterservice_object::test<2>()
 -    {
 -        DEBUG;
 -		LLUpdaterService updater;
 -		bool got_usage_error = false;
 -		try
 -		{
 -			updater.initialize("1.0",test_url, "update" ,test_channel, test_version);
 -			updater.startChecking();
 -			updater.initialize("1.0", "other_url", "update", test_channel, test_version);
 -		}
 -		catch(LLUpdaterService::UsageError)
 -		{
 -			got_usage_error = true;
 -		}
 -		ensure("Caught params while running", got_usage_error);
 -	}
 -
 -    template<> template<>
 -    void llupdaterservice_object::test<3>()
 -    {
 -        DEBUG;
 -		LLUpdaterService updater;
 -		updater.initialize("1.0", test_url, "update", test_channel, test_version);
 -		updater.startChecking();
 -		ensure(updater.isChecking());
 -		updater.stopChecking();
 -		ensure(!updater.isChecking());
 -	}
 -}
 +/** + * @file   llupdaterservice_test.cpp + * @brief  Tests of llupdaterservice.cpp. + *  + * $LicenseInfo:firstyear=2010&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$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "../llupdaterservice.h" +#include "../llupdatechecker.h" +#include "../llupdatedownloader.h" +#include "../llupdateinstaller.h" + +#include "../../../test/lltut.h" +//#define DEBUG_ON +#include "../../../test/debug.h" + +#include "llevents.h" +#include "lldir.h" + +/***************************************************************************** +*   MOCK'd +*****************************************************************************/ +LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client) +{} +void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl,  +								  std::string const & servicePath, std::string channel, std::string version) +{} +LLUpdateDownloader::LLUpdateDownloader(Client & ) {} +void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, bool){} + +class LLDir_Mock : public LLDir +{ +	void initAppDirs(const std::string &app_name,  +		   			 const std::string& app_read_only_data_dir = "") {} +	U32 countFilesInDir(const std::string &dirname, const std::string &mask)  +	{ +		return 0; +	} + +	BOOL getNextFileInDir(const std::string &dirname,  +						  const std::string &mask,  +						  std::string &fname)  +	{ +		return false; +	} +	void getRandomFileInDir(const std::string &dirname,  +							const std::string &mask,  +							std::string &fname) {} +	std::string getCurPath() { return ""; } +	BOOL fileExists(const std::string &filename) const { return false; } +	std::string getLLPluginLauncher() { return ""; } +	std::string getLLPluginFilename(std::string base_name) { return ""; } + +} gDirUtil; +LLDir* gDirUtilp = &gDirUtil; +LLDir::LLDir() {} +LLDir::~LLDir() {} +S32 LLDir::deleteFilesInDir(const std::string &dirname,  +							const std::string &mask) +{ return 0; } + +void LLDir::setChatLogsDir(const std::string &path){}		 +void LLDir::setPerAccountChatLogsDir(const std::string &username){} +void LLDir::setLindenUserDir(const std::string &username){}		 +void LLDir::setSkinFolder(const std::string &skin_folder){} +bool LLDir::setCacheDir(const std::string &path){ return true; } +void LLDir::dumpCurrentDirectories() {} + +std::string LLDir::getExpandedFilename(ELLPath location,  +									   const std::string &filename) const  +{ +	return ""; +} + +std::string LLUpdateDownloader::downloadMarkerPath(void) +{ +	return ""; +} + +void LLUpdateDownloader::resume(void) {} +void LLUpdateDownloader::cancel(void) {} +void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) {} + +int ll_install_update(std::string const &, std::string const &, bool, LLInstallScriptMode) +{ +	return 0; +} + +std::string const & ll_install_failed_marker_path() +{ +	static std::string wubba; +	return wubba; +} + +/* +#pragma warning(disable: 4273) +llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename, +										   ios_base::openmode _Mode, +										   int _Prot) : +	std::basic_istream<char,std::char_traits< char > >(NULL,true) +{} + +llus_mock_llifstream::~llus_mock_llifstream() {} +bool llus_mock_llifstream::is_open() const {return true;} +void llus_mock_llifstream::close() {} +*/ + +/***************************************************************************** +*   TUT +*****************************************************************************/ +namespace tut +{ +    struct llupdaterservice_data +    { +		llupdaterservice_data() : +            pumps(LLEventPumps::instance()), +			test_url("dummy_url"), +			test_channel("dummy_channel"), +			test_version("dummy_version") +		{} +		LLEventPumps& pumps; +		std::string test_url; +		std::string test_channel; +		std::string test_version; +	}; + +    typedef test_group<llupdaterservice_data> llupdaterservice_group; +    typedef llupdaterservice_group::object llupdaterservice_object; +    llupdaterservice_group llupdaterservicegrp("LLUpdaterService"); + +    template<> template<> +    void llupdaterservice_object::test<1>() +    { +        DEBUG; +		LLUpdaterService updater; +		bool got_usage_error = false; +		try +		{ +			updater.startChecking(); +		} +		catch(LLUpdaterService::UsageError) +		{ +			got_usage_error = true; +		} +		ensure("Caught start before params", got_usage_error); +	} + +    template<> template<> +    void llupdaterservice_object::test<2>() +    { +        DEBUG; +		LLUpdaterService updater; +		bool got_usage_error = false; +		try +		{ +			updater.initialize("1.0",test_url, "update" ,test_channel, test_version); +			updater.startChecking(); +			updater.initialize("1.0", "other_url", "update", test_channel, test_version); +		} +		catch(LLUpdaterService::UsageError) +		{ +			got_usage_error = true; +		} +		ensure("Caught params while running", got_usage_error); +	} + +    template<> template<> +    void llupdaterservice_object::test<3>() +    { +        DEBUG; +		LLUpdaterService updater; +		updater.initialize("1.0", test_url, "update", test_channel, test_version); +		updater.startChecking(); +		ensure(updater.isChecking()); +		updater.stopChecking(); +		ensure(!updater.isChecking()); +	} +} | 
